Prog-0 2013 Lec14-1 Copyright (C) 1999 – 2013 by Programming-0 Group プログラミング入門 第1 4 回講義 マークのあるサンプルプログラムは /home/course/prog0/public_html/2013/lec/source/

Slides:



Advertisements
Similar presentations
プログラミング論 第八回数字の計算,整数の入出力. 本日の内容 前回の課題(続き) 前回の課題(続き) 数字の計算をする 数字の計算をする – 加減乗除を行う – インクリメント演算子とデクリメン ト演算子.
Advertisements

オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
Prog Lec02-1 Copyright (C) by Programming-0 Group プログラミング入門 第2回講義 マークのあるサンプルプログラムは /home/course/prog0/public_html/2013/lec/source/ 下に置いてありますから、各自自分のディレクトリに.
ループで実行する文が一つならこれでもOK
初年次セミナー 第4回 整数と実数の取り扱い.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
基礎プログラミング (第五回) 担当者: 伊藤誠 (量子多体物理研究室) 内容: 1. 先週のおさらいと続き (実習)
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
第6章 2重ループ&配列 2重ループと配列をやります.
プログラムはなぜ動くのか.
2進数・16進数.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
第7回 条件による繰り返し.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
情報処理3 第5回目講義         担当 鶴貝 達政 11/8/2018.
C言語講座 第3回 ポインタ、配列.
プログラミング演習 バージョン1 担当教員:綴木 馴.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
プログラミング入門 電卓を作ろう・パートIV!!.
プログラミング演習I 2003年5月7日(第4回) 木村巌.
高度プログラミング演習 (03).
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
第7回 条件による繰り返し.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
Ibaraki Univ. Dept of Electrical & Electronic Eng.
Ibaraki Univ. Dept of Electrical & Electronic Eng.
原子動力工学特論 レポート1 交通電子機械工学専攻 齋藤 泰治.
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
整数データと浮動小数データ.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
情報処理Ⅱ 第2回:2003年10月14日(火).
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
復習 一定回数を繰り返す反復処理の考え方 「ループ」と呼ぶ false i < 3 true i をループ変数あるいはカウンタと呼ぶ
疑似乱数, モンテカルロ法によるシミュレーション
地域情報学 C言語プログラミング 第2回 変数・配列、型変換、入力 2017年10月20日
補講:アルゴリズムと漸近的評価.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
第5回 プログラミングⅡ 第5回
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
精密工学科プログラミング基礎 第7回資料 (11/27実施)
ニュートン法による 非線型方程式の解.
ループだよ!難しいよ! 第5章 while(ループ);.
cp-15. 疑似乱数とシミュレーション (C プログラミング演習,Visual Studio 2019 対応)
Cプログラミング演習 ニュートン法による方程式の求解.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
プログラミング演習I 数値計算における計算精度と誤差
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
コンピュータの高速化により, 即座に計算できるようになってきたが, 手法的にはコンピュータ出現以前に考え出された 方法が数多く使われている。
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
プログラミング演習I 補講用課題
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

Prog Lec14-1 Copyright (C) 1999 – 2013 by Programming-0 Group プログラミング入門 第1 4 回講義 マークのあるサンプルプログラムは /home/course/prog0/public_html/2013/lec/source/ 下に置いてありますから、各自自分のディレクトリに コピーして、コンパイル・実行してみてください マークのあるサンプルプログラムは /home/course/prog0/public_html/2013/lec/source/ 下に置いてありますから、各自自分のディレクトリに コピーして、コンパイル・実行してみてください 関数(その2) 関数の復習 (2) 関数の例1 ニュートン法 (4) 関数の例2 桁数 (11) 関数の例3 ある桁の数 (14) エラーチェックと強制終了 (17) 関数の例4 2進 → 10進変換 (20)

Prog Lec14-2 Copyright (C) 1999 – 2013 by Programming-0 Group #include double nijou(double); main() { double a = 1.73, b, c ; b = nijou(a); c = nijou(1.41);... (以下略) } double nijou( double x ) { double y; y = x * x; return y ; } #include double nijou(double); main() { double a = 1.73, b, c ; b = nijou(a); c = nijou(1.41);... (以下略) } double nijou( double x ) { double y; y = x * x; return y ; } 引数が仮引数にコピーされる 関数内で仮引数の値に従って 計算(処理) 戻り値が関数の値となる main の前にプロトタイプ宣言 main の後ろに関数本体の宣言 関数の復習 1

Prog Lec14-3 Copyright (C) 1999 – 2013 by Programming-0 Group #include double nijou(double); main() { double x = 2.0, a1, a2, a3; a1 = nijou(3.0); /* 値 */ a2 = nijou(x); /* 変数 */ a3 = nijou(x * 2.0); /* 式 */ printf("a1:%f a2:%f a3:%f \ n", a1, a2, a3); } double nijou(double x) { double y; y = x * x; return y ; } #include double nijou(double); main() { double x = 2.0, a1, a2, a3; a1 = nijou(3.0); /* 値 */ a2 = nijou(x); /* 変数 */ a3 = nijou(x * 2.0); /* 式 */ printf("a1:%f a2:%f a3:%f \ n", a1, a2, a3); } double nijou(double x) { double y; y = x * x; return y ; } 1.main の最初の実行文から開始 2.nijou(3.0) が評価される が関数の仮引数 x にコピーされ、関数 nijou に実行が移る 4. 計算の結果、 y に 9.0 が入り、「 return y 」 で 9.0 が nijou 関数の結果となる 5.nijou 関数の結果が a1 に代入される。 6. 次に nijou(x) が評価される 7.x(2.0) が関数の x にコピーされ、関数 nijou に実行が移る 8. 計算の結果 y に 4.0 が入り、「 return y 」で 4.0 が nijou 関数の結果となる 9.nijou 関数の結果が a2 に代入される 10.a3 も同様に計算される 11.printf で a1,a2,a3 が表示される 12. 終了 (教科書 P165 参照) 1.main の最初の実行文から開始 2.nijou(3.0) が評価される が関数の仮引数 x にコピーされ、関数 nijou に実行が移る 4. 計算の結果、 y に 9.0 が入り、「 return y 」 で 9.0 が nijou 関数の結果となる 5.nijou 関数の結果が a1 に代入される。 6. 次に nijou(x) が評価される 7.x(2.0) が関数の x にコピーされ、関数 nijou に実行が移る 8. 計算の結果 y に 4.0 が入り、「 return y 」で 4.0 が nijou 関数の結果となる 9.nijou 関数の結果が a2 に代入される 10.a3 も同様に計算される 11.printf で a1,a2,a3 が表示される 12. 終了 (教科書 P165 参照) 関数の動作おさらい

Prog Lec14-4 Copyright (C) 1999 – 2013 by Programming-0 Group 非線型方程式 f(x)=0 の解を求める方法 例題として、ニュートン法で の解 を求める ( ただし、 は与えられた定数、例えば 1,2 など ) 関数の例 1― ニュートン法 (p.178)

Prog Lec14-5 Copyright (C) 1999 – 2013 by Programming-0 Group 以後 x n につきステップ①②を繰り返 す x0x0 x1x1 f(x) 傾き f'(x 0 ) x 0 y 求める x x2x2 傾き f'(x 1 ) 傾き f'(x 2 ) x3x3 ニュートン法の原理 と x 軸との交点を 反復法によって求める ステップ① : 初期値 x 0 を与え、 点 (x 0,y 0 ) における y=f(x) の接線 ステップ② : 点 (x 1,y 1 ) における y=f(x) の接線 と x 軸との交点を求める ただし y 0 =f(x 0 ) ただし y 1 =f(x 1 ) と x 軸の交点 x 1 を求める x 0, x 1, x 2, x 3 … と だんだん f(x) の零点 ( 根になる点 ) に 近づいていく

Prog Lec14-6 Copyright (C) 1999 – 2013 by Programming-0 Group ニュートン法の原理まとめ 初期値 x 0 とし、そこでの接線と x 軸との交点を順次求めて行く ここで、 とする。 x0x0 x1x1 f(x) 傾き f'(x 0 ) x 0 y 求める x x2x2 傾き f'(x 1 ) 傾き f'(x 2 ) x3x3 求めた f(x k ) の値が一定の値(精 度)より小さければ終了 f(x 0 ) f(x 1 ) f(x 2 ) f( x k )<( 精度 )

Prog Lec14-7 Copyright (C) 1999 – 2013 by Programming-0 Group フローチャート x← x-f(x,a)/df(x) f(x,a)> 精度 はじめ x← 初期値 終り 真 偽 関数 f(x,a) fx← x*x-a return fx 関数 df(x) dfx←2*x return dfx 初期値は一般的に解より少し大きい値 a とする。 精度はマクロ EPS で与え、値は10 -6 とする また、一般的には「 f(x,a)< 精度」に関して、本当 は f(x,a) の絶対値を取る必要があるが、初期値を 解より大きい a としたので、負になることは考え ない 初期値は一般的に解より少し大きい値 a とする。 精度はマクロ EPS で与え、値は10 -6 とする また、一般的には「 f(x,a)< 精度」に関して、本当 は f(x,a) の絶対値を取る必要があるが、初期値を 解より大きい a としたので、負になることは考え ない dfx は、 fx つまり x 2 の 1 階微分だから 2x x 出力 読みこみ a← 定数

Prog Lec14-8 Copyright (C) 1999 – 2013 by Programming-0 Group プログラム #include #define EPS 1.0e-6 double f(double, double); double df(double); main() { double a, x, fx, dfx; printf("input a number : "); scanf("%lf",&a); x = a; printf("x(k-1) \ t \ tfx \ t \ tdfx \ t \ tx(k) \ t \ tf(x,%f)", a); while((fx = f(x,a)) > EPS ){ dfx = df(x); printf("%f \ t%f \ t%f",x,fx,dfx); x = x - fx/dfx; printf(" \ t%f \ t%12.10f \ n",x,f(x,a)); } printf("sqrt(%f) : %12.10f \ n",a,x); } #include #define EPS 1.0e-6 double f(double, double); double df(double); main() { double a, x, fx, dfx; printf("input a number : "); scanf("%lf",&a); x = a; printf("x(k-1) \ t \ tfx \ t \ tdfx \ t \ tx(k) \ t \ tf(x,%f)", a); while((fx = f(x,a)) > EPS ){ dfx = df(x); printf("%f \ t%f \ t%f",x,fx,dfx); x = x - fx/dfx; printf(" \ t%f \ t%12.10f \ n",x,f(x,a)); } printf("sqrt(%f) : %12.10f \ n",a,x); } double f(double x, double a) { double fx; fx = x*x - a; return fx; } double df(double x) { double dfx; dfx = 2.0*x; return dfx; } double f(double x, double a) { double fx; fx = x*x - a; return fx; } double df(double x) { double dfx; dfx = 2.0*x; return dfx; } タブ 代入してから比較 マクロで 精度を定義 /home/course/prog0/public_html/2013/lec/source/lec14-1.c 初期値

Prog Lec14-9 Copyright (C) 1999 – 2013 by Programming-0 Group 実行結果 std0dc0{s }1:./a.out input a number : 2 x(k-1) fx dfx x(k) f(x, ) sqrt( ) : std0dc0{s }2: std0dc0{s }1:./a.out input a number : 2 x(k-1) fx dfx x(k) f(x, ) sqrt( ) : std0dc0{s }2: 値が EPS (精度)以下に なった時点でループを終 了する x k での関数 f(x k ) の値。この 値が0になった時の x k が求 める値であるが、 f(x k ) は 完全に0にはならないの で、非常に小さい値 EPS 以下になった時の x k を解と する x k つまり x k-1 - fx/dfx x k-1

Prog Lec14-10 Copyright (C) 1999 – 2013 by Programming-0 Group 他の方程式 ( ) を解く 場合 double f(double x, double a) { double fx; fx = x*x*x – a ; return fx; } double df(double x) { double dfx; dfx = 3.0*x*x; return dfx; } double f(double x, double a) { double fx; fx = x*x*x – a ; return fx; } double df(double x) { double dfx; dfx = 3.0*x*x; return dfx; } main 関数での変更は最小 限で済む 簡単な変更で、もっと複 雑な方程式の解を求める ことも 可能 /home/course/prog0/public_html/2013/lec/source/lec14-2.c 2 dfx は、 fx つまり x 3 の 1 階微分だから 3x 2

Prog Lec14-11 Copyright (C) 1999 – 2013 by Programming-0 Group 関数の例 2 : 桁数を知る (1) 入力された数の桁数を返す関数を作る (例えば、「 」は8桁) 受け渡しの要件:1入力・1出力 入力:数⇨ int 型 出力:桁数⇨ int 型 関数名は桁数( digits )から digits とする。 digits のプロトタイプ宣言は以下のようになる。 int digits(int);

Prog Lec14-12 Copyright (C) 1999 – 2013 by Programming-0 Group 桁数を知る (2) 10 で割った答えが 0 でなければ、 2 桁以上の数 100(=10  10) で割った答えが 0 でなければ、 3 桁以上の数 1000(=100  10) で割った答えが 0 でなければ、 4 桁以上の数 … と割る数を順次 10 倍し、答えが 0 でない限り計算を続ける。 答えが初めて 0 になったときを見つける。 10 で割った答えが 0 でなければ、 2 桁以上の数 100(=10  10) で割った答えが 0 でなければ、 3 桁以上の数 1000(=100  10) で割った答えが 0 でなければ、 4 桁以上の数 … と割る数を順次 10 倍し、答えが 0 でない限り計算を続ける。 答えが初めて 0 になったときを見つける。 ループ回数 yx/y keta 引数に が渡された 時のループの様子 整数どうしの割り算は小数点 以下は切り捨てられる int digits(int x) { int keta = 1, y = 10; while((x / y) > 0){ y *= 10; keta++; } return keta; } int digits(int x) { int keta = 1, y = 10; while((x / y) > 0){ y *= 10; keta++; } return keta; } xをyで割った答えが0以外の間以下の処 理 yを10倍する ( つまり今度は一桁上を見 る) 桁数に1加える xをyで割った答えが0以外の間以下の処 理 yを10倍する ( つまり今度は一桁上を見 る) 桁数に1加える 右表はこの時点の値 初期値として 桁数=1,y=10 とする ループここまで 関数の値として桁数をリ ターン ループここまで 関数の値として桁数をリ ターン 数が一桁の場合は 一度もループに入らな い

Prog Lec14-13 Copyright (C) 1999 – 2013 by Programming-0 Group #include int digits(int); main() { int i, j; scanf("%d",&i); j = digits(i); printf("%d の桁数は %d です \ n",i,j); } int digits(int x) { int keta = 1, y = 10 ; while((x / y) > 0){ y *= 10; keta++; } return keta; } #include int digits(int); main() { int i, j; scanf("%d",&i); j = digits(i); printf("%d の桁数は %d です \ n",i,j); } int digits(int x) { int keta = 1, y = 10 ; while((x / y) > 0){ y *= 10; keta++; } return keta; } 実行結果 std1dc1{s }1:./a.out の桁数は 8 です std1dc1{s }2: 実行結果 std1dc1{s }1:./a.out の桁数は 8 です std1dc1{s }2: プログラムと実行結果 /home/course/prog0/public_html/2013/lec/source/lec14-3.c 43

Prog Lec14-14 Copyright (C) 1999 – 2013 by Programming-0 Group 関数の例 3 : ある桁の数を知る (1) 入力された数字の指定された桁の数を返す関数を作る (例えば、 の下から2桁目は2) 受け渡しの要件:2入力・1出力 二つの入力: データ ⇨ int 型 桁数 ⇨ int 型 結果(その桁の数) ⇨ int 型 関数名は get_1_digit とした。この関数のプロトタイ プ宣言は以下のようになる。 int get_1_digit(int,int); データ桁数

Prog Lec14-15 Copyright (C) 1999 – 2013 by Programming-0 Group ある桁の数を知る (2) 例えば の(下から)2桁目は2 % 100 = / 10 = 2 つまり 求める数 = ( データ % 10 桁数 ) / 10 ( 桁数ー1 ) 10 ( 桁数ー1 ) をどう作るか? ⇨ 10を(桁数ー1)回掛け合わせる(ループに て) 5 剰余算

Prog Lec14-16 Copyright (C) 1999 – 2013 by Programming-0 Group #include int get_1_digit(int, int); main() { int i, j = 2, result; scanf("%d",&i); result = get_1_digit(i, j); printf("%d の %d 桁目は %d です \ n",i,j,result); } int get_1_digit(int x, int pos) { int i, j, k = 1; for(i = 1 ; i < pos ; i++){ k *= 10; } j = x % (k * 10) / k; return j; } #include int get_1_digit(int, int); main() { int i, j = 2, result; scanf("%d",&i); result = get_1_digit(i, j); printf("%d の %d 桁目は %d です \ n",i,j,result); } int get_1_digit(int x, int pos) { int i, j, k = 1; for(i = 1 ; i < pos ; i++){ k *= 10; } j = x % (k * 10) / k; return j; } 実行結果 std1dc1{s }1:./a.out の 2 桁目は 2 です std1dc1{s }2: 実行結果 std1dc1{s }1:./a.out の 2 桁目は 2 です std1dc1{s }2: プログラムと実行結果 10(桁数ー1)のためのループ (データ%10桁数) / 10(桁 数ー1) の計算 (データ%10桁数) / 10(桁 数ー1) の計算 /home/course/prog0/public_html/2013/lec/source/lec14-4.c

Prog Lec14-17 Copyright (C) 1999 – 2013 by Programming-0 Group 10進数 : 10本指の人間が理解しやすい 14 (10) = 1×10 1 + 4×10 0 2進数 : コンピュータが理解出来る(スイッチの on/off として) 1110 (2) = 1×2 3 + 1×2 2 + 1×2 1 + 0×2 0 = 14 (10) X進数の「X]のことを基数と呼ぶ。 0からカウントアップし、基数になると桁上げが起こる。 2進数は0、1と来て、2になると桁上げが起こり10になる。 コンピュータの内部では、命令もデータも全て 0/1 の列( 2 進数)で表現さ れる → 詳細は後期、「コンピュータシステム概論」で学ぶ 32 ビット( 32 個の 0/1 の系列)で表現できる最大の数 2 32 = = 約 43 億 →138 年(一秒ごとにひとつカウントした場合) 例4の前に: 2 進数と 10 進数

Prog Lec14-18 Copyright (C) 1999 – 2013 by Programming-0 Group 関数の例4: 2進数から10進数への変換 (1) 入力された数字を2進数とみなして10進数に変換する プログラム(これまで作った関数を使う) 構成 main digits (桁数を求める) get_1_digit (数のうち一桁だけを取り出す) main() で行うこと: 0が入力されるまで無限ループで数を読み込む 2進数から10進数への変換(次ページ)

Prog Lec14-19 Copyright (C) 1999 – 2013 by Programming-0 Group 2進数から10進数への変換 (2) 各桁の重みと各桁の数をかけた物を加え合わす 例: (2進数) ⇨ 43 25*1+24*0+23*1+22*0+21*1+20*1 = 43 処理: keta = digits(data) total = 0; exp = 1; for(i = 1 ; i <= keta ; i++){ n = get_1_digit(data, i); total += n * exp; exp *= 2; } keta = digits(data) total = 0; exp = 1; for(i = 1 ; i <= keta ; i++){ n = get_1_digit(data, i); total += n * exp; exp *= 2; } 桁数を求める ( digits を使用 ) 合計を0にする。 桁の重みの初期値を20(=1)にする 桁数回ループして各桁について計算する その桁の数を求める ( get_1_digit を使用 ) 桁の重みと桁の数(0または1)を掛けて合計に足し 込む 次のループに備えて次の桁の重みを計算する(重みを 2倍する) ループここまで 桁数を求める ( digits を使用 ) 合計を0にする。 桁の重みの初期値を20(=1)にする 桁数回ループして各桁について計算する その桁の数を求める ( get_1_digit を使用 ) 桁の重みと桁の数(0または1)を掛けて合計に足し 込む 次のループに備えて次の桁の重みを計算する(重みを 2倍する) ループここまで nexptotal この場所での値 ループの様子 計算順序

Prog Lec14-20 Copyright (C) 1999 – 2013 by Programming-0 Group #include int digits(int); int get_1_digit(int, int); main() { int data, keta, i, n, exp, total; while(1){ /* データ読み込みとチェック */ printf(" 8桁以下の2進数を入力 ==> "); scanf("%d",&data); if (data == 0) exit(0); if (data > || data < 0){ printf(" 変換出来る範囲を越えています\ n"); continue; } /* 桁数計算 */ keta = digits(data); /* 10進数に変換 */ total = 0; exp = 1; for(i = 1 ; i <= keta ; i++){ n = get_1_digit(data, i); if((n != 0) && (n != 1)){ /* データチェック */ printf(" データが0か1ではありません\ n"); exit(8); } total += n * exp; exp *= 2; } printf(" 2進 : %d -> 10進 : %d \ n",data,total); } #include int digits(int); int get_1_digit(int, int); main() { int data, keta, i, n, exp, total; while(1){ /* データ読み込みとチェック */ printf(" 8桁以下の2進数を入力 ==> "); scanf("%d",&data); if (data == 0) exit(0); if (data > || data < 0){ printf(" 変換出来る範囲を越えています\ n"); continue; } /* 桁数計算 */ keta = digits(data); /* 10進数に変換 */ total = 0; exp = 1; for(i = 1 ; i <= keta ; i++){ n = get_1_digit(data, i); if((n != 0) && (n != 1)){ /* データチェック */ printf(" データが0か1ではありません\ n"); exit(8); } total += n * exp; exp *= 2; } printf(" 2進 : %d -> 10進 : %d \ n",data,total); } int digits(int x) { int keta = 1, k = 10; while((x / k) > 0){ k *= 10; keta++; } return keta; } int get_1_digit(int x, int pos) { int i, j, k = 1; for(i = 1 ; i < pos ; i++){ k *= 10; } j = x % (k * 10) / k; return j; } int digits(int x) { int keta = 1, k = 10; while((x / k) > 0){ k *= 10; keta++; } return keta; } int get_1_digit(int x, int pos) { int i, j, k = 1; for(i = 1 ; i < pos ; i++){ k *= 10; } j = x % (k * 10) / k; return j; } 右に続く⇨ ⇨左から続く 2進数 →10 進数変換プログラ ム /home/course/prog0/public_html/2013/lec/source/lec14-6{a,b,c,d}.c 8 lec14-6a.c が記載されたプログラム。 後は様々なバリエーション

Prog Lec14-21 Copyright (C) 1999 – 2013 by Programming-0 Group std1dc1{s }1:./a.out 8桁以下の2進数を入力 ==> 2進 : > 10進 : 43 8桁以下の2進数を入力 ==> 変換出来る範囲を越えています 8桁以下の2進数を入力 ==> -101 変換出来る範囲を越えています 8桁以下の2進数を入力 ==> データが0か1ではありません std1dc1{s }2: echo $status 8 std1dc1{s }3: std1dc1{s }1:./a.out 8桁以下の2進数を入力 ==> 2進 : > 10進 : 43 8桁以下の2進数を入力 ==> 変換出来る範囲を越えています 8桁以下の2進数を入力 ==> -101 変換出来る範囲を越えています 8桁以下の2進数を入力 ==> データが0か1ではありません std1dc1{s }2: echo $status 8 std1dc1{s }3: 実行例 9 cshの場合

Prog Lec14-22 Copyright (C) 1999 – 2013 by Programming-0 Group エラーチェック エラーチェックとは 予想される間違いを検出 すること 前述の例4のプログラムの場合、以下のような入力誤りが予想される 負の数が入力される(例:-101) 1 桁の数が入力される(例:8) エラーを検出した場合はエラーに応じた処理を行う(「エラー処理」と言 う) エラーの重大さによって、処理が異なることがある(例えば軽度なエラーは 処理を続行させ、重度なエラーは処理を中止するなど) 例4のプログラムの場合 負の数だった場合:「変換出来る範囲を越えています」と表示して再度データ入 力からやり直す 1桁の数だった場合、「データが適切ではありません」と表示してプログラムを 強制終了させる。(強制終了は次ページ参照) エラーチェックをしっかりしておくとプログラムの誤動作を未然に防ぐこと が出来る 7 6

Prog Lec14-23 Copyright (C) 1999 – 2013 by Programming-0 Group プログラムの強制終了 プログラムの強制終了の方法 をインクルードする。 exit ( 整数 ); で どこからでもプログラムを強制終了させることが出 来る。 プログラム実行後、この引数はシェル変数に渡される(例えば tcsh だ と「 $? 」、 csh だと 「 $status 」 というシェル変数に格納される) シェル変数の制約により渡せる引数は 0 ~ 255 までの整数のみに限られ る。 このようにプログラムからシェル変数に値が渡る事で、 値によってエラーの理由を知ることが出来る シェルスクリプトを使用して値によって動作を変える事が可能 例えば以下のような非常に簡単なプログラム ( exit(8); で強制終了) の実行終了後 $status を見ると8という数字が入っていることが分か る。 #include main() { exit(8); } #include main() { exit(8); } 実行結果 (csh の場合) std1dc1{s }1:./a.out std1dc1{s }2: echo $status 8 std1dc1{s }3: 実行結果 (csh の場合) std1dc1{s }1:./a.out std1dc1{s }2: echo $status 8 std1dc1{s }3: /home/course/prog0/public_html/2013/lec/source/lec14-5.c

Prog Lec14-24 Copyright (C) 1999 – 2013 by Programming-0 Group 補足:10進数から2進数への変換 なお、10進数から2進数への変換は以下のようなプ ログラムによって行う事が出来る。 #include main() { unsigned int data; int bin[32], i; printf(" 10進数を入力 ==> "); scanf("%u",&data); for(i = 0; i < 32; i++){ bin[31 - i] = data % 2; data /= 2; } for(i = 0; i < 32; i++){ printf("%1d",bin[i]); } printf(" \ n"); } #include main() { unsigned int data; int bin[32], i; printf(" 10進数を入力 ==> "); scanf("%u",&data); for(i = 0; i < 32; i++){ bin[31 - i] = data % 2; data /= 2; } for(i = 0; i < 32; i++){ printf("%1d",bin[i]); } printf(" \ n"); } #include main() { unsigned int data; int i; printf(" 10進数を入力 ==> "); scanf("%u",&data); for(i = 0; i < 32; i++){ printf("%1d",(data >> (31 - i)) & 1); } printf(" \ n"); } #include main() { unsigned int data; int i; printf(" 10進数を入力 ==> "); scanf("%u",&data); for(i = 0; i < 32; i++){ printf("%1d",(data >> (31 - i)) & 1); } printf(" \ n"); } 配列を使用 シフト演算 子を使用 /home/course/prog0/public_html/2013/lec/source/lec14-7{a,b,c}.c