while 文 (1) 繰り返しの必要性 while の形式と動作 繰り返しにより平 根を求める ( 演習 ) 繰り返しにより 程式の解を求める ( 課題 )
Hello. をたくさん表示しよう Hello. を画面に 3 回表示するには, 以下で OK. #include <stdio.h> int main() { printf("hello. n"); printf("hello. n"); printf("hello. n"); では,Hello. を 100 回表示するにはどうしたらいい? 勿論, printf("hello Hello. n n"); を100 個書けばいいのだが, そんな面倒なことはしたくない! これを実現するためには, 繰り返しを使う 1
while 文の形式と動作 形式 while ( 式 ) 文 動作 (1) 式を評価 ( 計算 ) する. (2) 式の値が真ならば文を実行し,(1) に戻る. 式の値が偽ならば while 文を終了する. 文が複数の文から構成されるときは, if 文のときと同様に,{ で囲む. 2
繰り返しの際に良く使う式 (a) (b) 変数 = 変数 + 1 ; 変数に記憶している値を 1 増やす 変数 = 変数 - 1 ; 変数に記憶している値を 1 減らす ex. i=i+1; この代入文を実行すると 1 右辺が計算される. 現在の i の値 (i が記憶している値 ) に1 加えた値が右辺の値となる. 2 右辺の値を, 左辺の変数 i に代入する. 結果として, この文を実行すると i の値が1 増える. これらの式はプログラムで非常によく使われるため, 専用の表現があり, (a) と同じ結果になるのが変数 ++( たとえば i++) (b) と同じ結果になるのが変数 --( たとえば i--) この他にも,++i, --i があるが, 上記との違いは参考テキストを参照. 3
Hello. を 100 回表示するプログラム (1/8) #include <stdio.h> int main() { int i; 変数 i は繰り返しの実行回数を記憶 i = 0 ; while(i < 100){ printf("hello. n"); この2 文を実行すると, i=i+1; i の値が1 増加. 画面に Hello. と表示され, 4
Hello. を 100 回表示するプログラム (2/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; i に記憶されている値 0 画面 (Window) 5
Hello. を 100 回表示するプログラム (3/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; i に記憶されている値 0 画面 (Window) i=0 ゆえ, 繰り返しの条件 i<100 は真 6
Hello. を 100 回表示するプログラム (4/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; i に記憶されている値 1 画面 (Window) Hello. 7
Hello. を 100 回表示するプログラム (5/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; i に記憶されている値 1 画面 (Window) Hello. i=1 ゆえ, 繰り返しの条件 i<100 は真 8
Hello. を 100 回表示するプログラム (6/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; i に記憶されている値 2 画面 (Window) Hello. Hello. 9
Hello. を 100 回表示するプログラム (7/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; 100 回実行したとき i に記憶されている値 100 画面 (Window) Hello. Hello. Hello. 100 回表示 Hello. 10
Hello. を 100 回表示するプログラム (8/8) プログラムの実行過程 #include <stdio.h> int main() { int i; i = 0 ; while(i < 100){ printf("hello. n"); i=i+1; i に記憶されている値 100 画面 (Window) Hello. Hello. Hello. Hello. i=100 ゆえ, 繰り返しの条件 i<100 は偽 while 文終了 11
指定数だけ Hello. と表示するプログラム 右のプログラムは, 整数を 1 つ読み込み, 読み込んだ数だけ Hello.(+ 改行 ) を画面に表示するプログラム. #include <stdio.h> int main() { int n; /* 表示回数を表わす */ int i; /* 繰り返しのカウント */ /* 表示回数の入力 */ printf( tf(" 何回表示しますか :"); scanf("%d",&n); /* 表示 */ i = 0 ; while(i < n){ printf("hello. n"); i=i+1; 12
演習 : a の平方根を求める (1/2) 次頁の解説を参考にして, 実数を 1 つ読み込み, この数の平方根を繰り返しを用いて求めるプログラムを作ろう. 本演習では, 繰り返しの回数は 10 回とし, 各回で求まった平方根の近似値を表示するようにすること. 実は, 次頁で説明する方法は, ニュートン法という, 方程式の数値計算による一般的な解法を x*x-a=0 に特化したもの. 13
演習 : a の平方根を求める (2/2) 縦, 横の長さがそれぞれ x, y の長方形 ( 面積 a) を考える. 最初は,x=a, y=1 であるとする. 毎回の繰り返しで, 縦, 横の長さを以下のように変更. このように変更すると, 面積は a のままで,x, y は以前より近い値になる ( つまり, 正方形に近づく ). これを繰り返せば,x, y の値はそれぞれ a に近づく. a 面積 a a+1 2 面積 a a 正方形 面積 a 1 a a+1 2 a 14
break 文,continue 文 (1/2) 繰り返しの中 ( 以下の図のの部分 ) で,break 文が実行されると, その時点で,while 文を強制的に終了する. while( 条件 1) { if( 条件 2) break; [ 補足 ] continue 文繰り返しの中 (while 文や for 文により繰り返し実行される文の中 ) で, continue 文に出会う (continue 文を実行する ) と, それ以降の文を無視し,while 文であれば, 次の繰り返しをするか否かの条件判定,for 文であれば, 次の繰り返しの準備 ( 第 6 回の資料の for 文の形式と動作 の動作 (3) のところ ) に実行が移る. 15
break 文,continue 文 (2/2) ex. #include <stdio.h> int main() { int x,y; printf(" 割り算をします n"); while(1){ printf(" 一つ目の数は :"); scanf( f("%d",&x); &); printf(" 二つ目の数は :"); scanf("%d",&y); if(y==0){ 2つの整数を入力し, その割り算の答えを表示する ということを繰り返すプログラム. ただし, 二つ目の数が 0 の場合, 繰り返しを終了. printf(" 二つ目の数が 0 でしたので終わります n"); break; printf("%d %d = %d n",x,y,x/y); printf(" お疲れ様... n"); 16
演習問題の修正版 17 break を使えば, 先の演習問題を, x と y の更新の繰り返しは 100 回までで, その最中に, x-y < EPS になった場合は, 繰り返しを強制終了する というようなことも可能. ただし, EPS は 分 さな正の数とする ( たとえば,0.00001). 0 00001)
繰り返しによる方程式の解法 : 二分法 (1/3) 二分法は, ニュートン法と同様に, 方程式の代表的な数値計算による解法の一つ. 関数 f(x) が 区間 a x b で連続で,f(a) と f(b) が異符号 ならば, 区間 a < x < b のどこかに f(x)=0 となる x が存在するはず. 計算の各繰り返しで, その区間幅を半分に狭めていくことにより解を 1 つ求めるのが二分法. 今, f(a) とf(b) が異符号 ( つまり,f(x)=0 の解が存在する区間の下限が a, 上限が b ) とする. a と b の中点 c( つまり,c = (a+b)/2 です ) を考え,f(c) の符号に関して次頁のように場合分けすると, 解が存在する区間が狭まる ( あるいは解が見つかる ). 18
繰り返しによる方程式の解法 : 二分法 (2/3) f(a) と f(c) が同符号 y y=f(x) a c x b f(b) と f(c) が同符号 y y=f(x) a x c b y a f(c)=0 c b y=f(x) x y y y a c b x y=f(x) a c b x y=f(x) a c b x y=f(x) 下限が c 上限が c 解が c y a c y=f(x) b x f(a) と f(c) が同符号の場合でも, 左図のように, 区間 a < x < c にも解がある場合があるが, 解を1つもとめればいいので, この区間は考慮に入れない. 19
繰り返しによる方程式の解法 : 二分法 (3/3) 以上より, 区間 a<x<b における f(x)=0 の解を二分法で求めるには 1. 最初に条件として与えた区間の下限を a, 上限を b に代入する. 2.f(a),f(b) の値を求め, これを変数 fa,fb に代入する. 3. 区間の幅, すなわち,b-a が十分に小さくなる ( 一応,0.000001 以下が十分に小さいとしよう ) まで,while 文により, 以下を繰り返す. (1) a と b の中点を求め c に代入する. また,f(c) の値を求めこれを変数 fc に代入する. (2) fc = = 0 ならば, break 文により while 文を終了. fa と fc が同符号ならば, a に c を代入し,fa に fc を代入する. それ以外, すなわち,fb と fc が同符号ならば, b に c を代入し,fb に fc を代入する. 4.c が求める解なので c の値を表示する. 20
課題 4 ( 二分法による方程式の解法 ) 二分法により, の解を区間 0 < x < 1 の範囲内で 1 つ求めるプログラムを作れ. f(0)=-2,f(1)=1 であり, 勿論 f(x) は 0 x 1で連続であるから,f(x)=0 の解は,0 と 1 の間, 少なくとも一つあり, 二分法によって解の一つが求まることは保証されている. f(a) の値を求め fa に代入するには, 地道にやるならば, fa=a*a*a*a-3*a*a*a+6*a*a-a-2; 本当はマクロ定義を利用して f(x) を定義し, fa=f(a); とできるが, マクロ定義については省略 ( 参考テキスト参照 ). x * y > 0 ならば, 変数 x と y の値は同符号 21