4-4 while 文 for 文と同様 ある処理を繰り返し実行するためのものだが for 文と違うのは while 文で指定するのは 継続条件のみであるということ for 文で書かれた左のプログラムを while 文で書き換えると右のようになる /* 読込んだ正の整数値までカウントアップ (for 文 ) */ int i, no; for (i = 0; i <= no; i++) printf( %d, i); printf( n ); /* 読込んだ正の整数値までカウントアップ (while 文 ) */ int i=0; int no; while (i <= no) printf( %d, i); printf( n ); 同じ色でマーキングされたところが 対応する処理内容 見て分るとおり 書き方は異なるが プログラム実行に必要な要素は 両方とも同じである つまり 基本的に for 文で書かれたプログラムは while 文で書き換えることができるし 当然その逆も言える 問題 4-5 次の文を while 文で書き換えよ int no, total, i; total = 0; no = 10; for (i = 1; i <= no; i++) total += i; printf( 1 から %d までの和は %d です n, i, no, total);
次のプログラムを while 文を使って作成せよ 問題 4-6 1. 整数を指定された数だけ入力し その合計 平均 最高 最低を出力する 2.2 の n 乗を表示する ただし n は 0 n 30 の整数とし それ以外はエラー表示して終了する 2. の実行結果 ( その 1) 2 の n 乗を表示します n はいくつですか :4 2^0 : 1 2^1 : 2 2^2 : 4 2^3 : 8 2^4 : 16 1. の実行結果整数は何個ですか :5 No.1 : 10 No.2 : 56 No.3 : 82 No.4 : 72 No.5 : 27 合計 :247 平均 :49.40 最大 :82(No.3) 最小 :10(No.1) 2. の実行結果 ( その 2) 2 の n 乗を表示します n はいくつですか :32 その値は受け付けません!! 4-5 do~while 文今までは範囲外の数値が入力されたときは エラー表示をして終了していた しかし実際は 適切な数値が入力されるまで 入力を促すことが多い そんなとき使えるのが do~while 文である 右のプログラムはその例 do で処理を囲み 最後の while で継続条件を判定し もし ( ) 内の条件を満たしていれば 再び 内の処理を繰り返し そうでなければ次の行に移る while 文と違うのは 継続判定が最後にあること つまり do 文の場合は必ず 1 回は 内の処理を行うが while 文の場合は一度も実行されないこともある /* 読込んだ正の整数値は奇数か偶数か */ int no; do if (no <= 0) printf( 正の整数です!! n ); while (no <= 0); if (no % 2) printf( %d は奇数です n, no); else printf( %d は偶数です n, no);
ちなみに for 文や while 文を使っても 同じ処理をさせようと思えばできが do 文を使った方 がスッキリしていると思う /* 読込んだ正の整数値は奇数か偶数か */ int no; no = 0; for ( ; no <= 0; ) if (no <= 0) printf( 正の整数です!! n ); /* 読込んだ正の整数値は奇数か偶数か */ int no; no = 0; while (no <= 0) if (no <= 0) printf( 正の整数です!! n ); if (no % 2) printf( %d は奇数です n, no); else printf( %d は偶数です n, no); if (no % 2) printf( %d は奇数です n, no); else printf( %d は偶数です n, no); 問題 4-7 の 1. を次のように修正しなさい 問題 4-7 入力する整数の数を制限しない 入力される整数は 0~100 とする -1 が入力されたら入力を中止し 合計等の表示を行う もちろん -1 は合計等に含めない 次のプログラムは あらかじめ決められた数を当てるというものである 空欄を埋めて完成せよ 問題 4-8 int no = 89; /* 当てさせる数 */ int x; /* 入力する数 */ 1 printf( 数を当てて下さい : ); scanf( %d, 2 ); if ( 3 ) printf( もっと大きいです n ); else printf( もっと小さいです n ); 4 ( 5 ); printf( 正解です n );
次のプログラムを実行したらどうなるか 選択肢から選びなさい なお main 文の中のみ書いてある 問題 4-9 1) int a=5; while (a) printf( %d, a); a--; 2) int a=5; while (a>0) printf( %d, a--); 選択肢 1012 200000 301234 443210 5543210 654321 71111 811111 9 無限ループになる 10コンパイルエラー 3) int a=5; do printf( %d, --a); while (a>0); 4) int a=5, i=0; do int b = a-i; printf( %d, b); while (b>0); 5) int a=1, b=5; while (a<b--) printf( %d, a); a++;
問題解答 4-5 int no, total, i; total = 0; no = 10; i = 1; while (i <= no) total += i; printf( 1 から %d までの和は %d です n, i, no, total);
4-6 1. int no, max, min, point; /* no: 整数の個数 max: 最大値 min: 最小値 point: 入力する整数 */ int max_num, min_num /* max_num: 最大値の番号 min_num: 最小値の番号 */ double total=0, ave; /* total: 合計 ave: 平均 */ int i; /* i: ループ用 */ printf( 整数は何個ですか : ); i = 1; max_num = min_num = 1; /* 最小 最大の番号をとりあえず 1 とする */ while (i <= no) printf( No.%d:, i); scanf( %d, &point); if (i == 1) /* max, min には初期値が必要なので */ min = point; /* No.1 の値を初期値とした */ max = point; total += point; /* 合計値に入力した値を加算 */ if (point < min) /* point が min より小さかったら */ min_num = i; min = point; if (point > max) /* point が max より大きかったら */ max_num = i; max = point; /* i をひとつ増やす */ ave = total / no; /* 平均の計算 */ /* 結果の表示 */ printf( 合計 :%.0f n, total); printf( 平均 :%.2f n, ave); printf( 最大 :%d(no.%d) n, max, max_num); printf( 最小 :%d(no.%d) n, min, min_num); 分りづらいのは max_num = min_num = 1 という代入の仕方ではないだろうか これを訳せば 最初に min_num に 1 を代入し 次に max_num に min_num を代入する となる こういう書き方をして 複数の変数に同じ数値を代入する方法がある また i=1 のときの point の値を max と min に代入するのは 何も代入されていないと後の値との比較ができないから 代入する値の範囲があらかじめ決まっていれば それらを max と min に代入できるが 今回は範囲を決めていないため その他の箇所については じっくり見てもらえれば理解できると思う
2. 4-7 int n, i, sum=1; printf( 2 の n 乗を表示します n ); printf( n はいくつですか : ); scanf( %d, &n); if (n<0 n > 30) printf( その値は受け付けません!! n ); else i = 0; while (i <= n) printf( 2^%d:%d n, i, sum); sum *= 2;
4-7 int max, min, point; /* max: 最大値 min: 最小値 point: 入力する整数 */ int max_num, min_num; /* max_num: 最大値の番号 min_num: 最小値の番号 */ double total=0, ave; /* total: 合計 ave: 平均 */ int i; /* i: ループ用 */ i = 1; max = 0; min = 100; while ( i ) /* 値の入力 */ do printf( No.%d:, i); scanf( %d, &point); if ((point < 0 point > 100) && point!= -1) printf( 0 から 100 までです!! n ); while ((point < 0 point > 100) && point!= -1); if (point == -1) --i; break; total += point; /* 合計値に入力した値を加算 */ if (point < min) /* point が min より小さかったら */ min_num = i; min = point; if (point > max) /* point が max より大きかったら */ max_num = i; max = point; ave = total / i; /* 平均の計算 */ /* 結果の表示 */ printf( 合計 :%.0f n, total); printf( 平均 :%.2f n, ave); printf( 最大 :%d(no.%d) n, max, max_num); printf( 最小 :%d(no.%d) n, min, min_num); 今回は入力値の範囲が決まっているので それを元に max min を初期化している 水色の部分が 入力の終了条件 ( 入力値が -1 の時 ) に関わるところ i が余計にインクリメント ( 増加 ) されているので break する前に戻している
4-8 1 do: 繰り返し文であることは想像できると思う ループ文の 最後の括弧の次に続きがあるので do が入ることが分る 2 x: 変数は二つのみ no には既に値が入っているので ここでは x を用いる コメント文にもその旨書いてある 3 x < no: もっと大きいです というのは no の方が入力した値より大きいということ 4 while:do の締めくくりは while 5 x!= no:x が no と等しくなるまで 入力を続ける 4-9 1)6:c 言語の場合 条件の評価が 1 以外のとき真 0 のとき偽となる 2)6:printf( %d, a); a--; とほぼ同じ意味となる 3)4: 最初の printf 文を実行する前に a は 1 減って 4 となる a=0 まで表示して 直後の while でループから抜ける 4)5:3) 同様 b=0 を表示した後ループを抜ける 5)7: ちょっと意地悪問題 間違いではなく わざとこういう書き方をした 最後の a++ はループの外 丁寧に書くと int a=1, b=5; while (a < b--) printf( %d, a); a++; a はループ中は 1 のまま b はループに入ったとき 5 B=5,4,3,2 のとき printf を実行するので 1 を 4 回表示する