05: 反復 (1) C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/CPR1/ 2015-05-11
if - else for while do - while 制御構文 条件分岐(第4回) ループ(今回・次回) (switch – case) (goto) ループ(今回・次回) for while do - while 2015-05-11 C プログラミング入門 総機1 (月1)
今回 次回 今日の内容 便利な演算子 while 文 do-while 文 for 文 累積誤差 多重ループ break, continue カンマ演算子 2015-05-11 C プログラミング入門 総機1 (月1)
ループでよくつかわれる演算子(復習) 複合代入演算子 インクリメント・デクリメント a += 8 (a = a + 8 と同じ) などなど a++ ++a (a = a + 1 と同じ) a-- --a (a = a - 1 と同じ) 2015-05-11 C プログラミング入門 総機1 (月1)
一般角 a [deg] を半開区間 [0, 360) に正規化する 例題1:一般角の正規化 一般角 a [deg] を半開区間 [0, 360) に正規化する 360 以上の場合は、繰り返し 360 を引く 負の角度の場合は、繰り返し 360 を足す 1035 [deg] =360×2+315 315 [deg] 2015-05-11 C プログラミング入門 総機1 (月1)
while (条件式) 文; while (条件式) {ブロック} while 文 構文 式の評価 ブロックの実行 真 偽 条件を満たす (真である) 間、文またはブロックを繰り返し実行する 反復、ループなどと呼ぶ 先判定ループ 条件によっては一度も実行されない 2015-05-11 C プログラミング入門 総機1 (月1)
一般角 a [deg] を半開区間 [0, 360) に正規化する 例題1:一般角の正規化 一般角 a [deg] を半開区間 [0, 360) に正規化する 360 以上の場合は、繰り返し 360 を引く 負の角度の場合は、繰り返し 360 を足す /* 正の角の正規化 */ while(a >= 360) { a -= 360; } /* 負の角の正規化 */ while(a < 0) { a += 360; } それぞれ一行で書くこともできる。 while(a >= 360) a -= 360; 2015-05-11 C プログラミング入門 総機1 (月1)
例題1:一般角の正規化 実行例 ... double a = 1035; /* 正の角の正規化 */ while(a >= 360) { a -= 360; } 1035 a 675 315 2015-05-11 C プログラミング入門 総機1 (月1)
例題2:ニュートン法 平方根 2 に収束する数列を計算する 2 は 𝑓 𝑥 = 𝑥 2 − 2 = 0 の根の1つ 平方根 2 に収束する数列を計算する 2 は 𝑓 𝑥 = 𝑥 2 − 2 = 0 の根の1つ 以下の漸化式で定義される無限数列 𝑥 0 , 𝑥 1 , 𝑥 2 , …, 𝑥 𝑛 ,… は適当な 𝑥 0 ≠0 から始めて ± 2 のいずれかに収束する 𝑥 𝑛+1 &=& 𝑥 𝑛 − 𝑓 𝑥 𝑛 𝑓 ′ 𝑥 𝑛 &=& 𝑥 𝑛 − 𝑥 𝑛 2 −2 2 𝑥 𝑛 一般にこの計算で f(x) = 0 の根を求める方法をニュートン法という 2015-05-11 C プログラミング入門 総機1 (月1)
ループを使わずに解くためには、何度も同じ計算式を書くしかない 例題2:ニュートン法 𝑥 𝑛+1 = 𝑥 𝑛 − 𝑥 𝑛 2 −2 2 𝑥 𝑛 ループを使わずに解くためには、何度も同じ計算式を書くしかない double x0 = 1.0, x1, x2, x3, x4; x1 = x0 – (x0*x0 – 2) / (2*x0); x2 = x1 – (x1*x1 – 2) / (2*x1); x3 = x2 – (x2*x2 – 2) / (2*x2); x4 = x3 – (x3*x3 – 2) / (2*x3); ... 数列の分だけ変数を書かないといけない 同じ式が何度も繰り返される 2015-05-11 C プログラミング入門 総機1 (月1)
最終的な結果のみを残せばよいので、1つの変数を次々に上書きする 例題2:ニュートン法 𝑥 𝑛+1 = 𝑥 𝑛 − 𝑥 𝑛 2 −2 2 𝑥 𝑛 最終的な結果のみを残せばよいので、1つの変数を次々に上書きする double x = 1.0; x = x – (x*x – 2) / (2*x); ... この値は、上書きされて失われる 同じ式が何度も繰り返されるのは変わらず 2015-05-11 C プログラミング入門 総機1 (月1)
while ループで繰り返し処理をまとめる 例題2:ニュートン法 𝑥 𝑛+1 = 𝑥 𝑛 − 𝑥 𝑛 2 −2 2 𝑥 𝑛 while ループで繰り返し処理をまとめる 終了条件が何か必要 double x = 1.0; while( ) { x = x – (x*x – 2) / (2*x); } ... この値は、上書きされて失われる 条件式? 一つの式だけになった 2015-05-11 C プログラミング入門 総機1 (月1)
繰り返し条件として、 𝑓 𝑥 >𝑒 を採用する場合 例題2:ニュートン法 𝑥 𝑛+1 = 𝑥 𝑛 − 𝑥 𝑛 2 −2 2 𝑥 𝑛 繰り返し条件として、 𝑓 𝑥 >𝑒 を採用する場合 𝑓 𝑥 = 𝑥 2 −2 double x = 1.0, e = 1.0e-5; while(fabs(x*x-2) > e) { x = x – (x*x – 2) / (2*x); } ... 閾値 10 −5 繰り返し条件 f(x) がゼロに近づくまで計算する fabs() は絶対値を求める関数 (math.h) 2015-05-11 C プログラミング入門 総機1 (月1)
do 文; while(条件式); do {ブロック} while(条件式); do-while 文 構文 式の評価 ブロックの実行 真 偽 文またはブロックを実行した後、条件を判定して、真の間繰り返す 後判定ループ 必ず一度は実行される 2015-05-11 C プログラミング入門 総機1 (月1)
繰り返し条件として、 𝑥 𝑛+1 − 𝑥 𝑛 >𝑒 を採用する場合 例題3:ニュートン法 繰り返し条件として、 𝑥 𝑛+1 − 𝑥 𝑛 >𝑒 を採用する場合 前回の値と比較するので、まずは1回計算が必要 double x = 1.0, xx, e = 1.0e-5; do { xx = x; x = x – (x*x – 2) / (2*x); } while(fabs(xx-x) > e); ... 一つ前の値を取っておく変数 前回の値を取っておく fabs() は絶対値を求める関数 (math.h) 前回の値との差を調べる 2015-05-11 C プログラミング入門 総機1 (月1)
for(初期化式; 条件式; 更新式) 文; for 文 最初に初期化式を評価 文またはブロックを実行 更新式を評価 構文 またはブロック 初期化式の評価 最初に初期化式を評価 普通は代入式がかかれる 文またはブロックを実行 更新式を評価 条件式が真なら 2. に戻る 条件式の評価 偽 真 ブロックの実行 更新式の評価 2015-05-11 C プログラミング入門 総機1 (月1)
ループ変数(ループカウンタ)により反復回数を制御 ループ変数を使った for 文 ループ変数(ループカウンタ)により反復回数を制御 i, j, k, n, m などがよくつかわれるが, 何でも可 int i; // ループ変数 for(i = 0; i < 10; ++i) { printf("%d ", i); } i++ でもよい 初期化式 条件式 更新式 1. 初期化 i = 0 2. 条件判定 i < 10 10 i ループ終了後の値 3. 実行 printf() 4. 更新 ++i 0 1 2 3 4 5 6 7 8 9 ▮ 丁度10回 繰り返している 2015-05-11 C プログラミング入門 総機1 (月1)
for 文の更新式の例 更新式の異なるループの結果 for(i=0; i < 10; i=i*i+1) { printf("%d ", i); } 0 1 2 5 ▮ 26 i for(i=0; i < 10; i=i+3) { printf("%d ", i); } 0 3 6 9 ▮ 12 i for(i=0; i < 10; --i) { printf("%d ", i); } 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 … 変数 i の表現範囲を超えると正の値になって止まる可能性はある 2015-05-11 C プログラミング入門 総機1 (月1)
for は while に特別な処理を加えたもの 等価な書き換えが可能 int i; for(i = 0; i < 10; ++i) { printf("%d ", i); } int i; i = 0; while(i < 10) { printf("%d ", i); ++i; } 初期化式 条件式 更新式 2015-05-11 C プログラミング入門 総機1 (月1)
どれを使えばいいの? 固定回数繰り返す場合 ある条件の下で不定回数繰り返す場合 for while でも可能 (等価書き換え) 計算結果から条件を判定するなら do-while 2015-05-11 C プログラミング入門 総機1 (月1)