繰り返し処理(反復)は、コンピュータの得意技です。
まずは同じ処理を5回繰り返すプログラムを例にとって繰り返し処理の考え方について学んでいきましょう。
C言語には、繰り返し処理を記述するための命令が3種類用意されています。(実際には、3種類に加えgoto文という命令も存在しますが、ここでは考え方が異なるため割愛します)
- while文(前判定)
- for文(前判定)
- do~while文(後ろ判定)
です。1と2のwhile文とfor文は繰り返し処理の最初に繰り返す為の条件を判定する「前判定」となっています。
3のdo~while文のみ繰り返し処理のの最後に繰り返す為の条件を判定する「後ろ判定」となります。
命令は3種類ありますが、考え方は同じです。
まずはwhile文から見ていきます。
繰り返し処理(while文)
サンプルプログラム loop_while.c
/* loop_while.c */ #include <stdio.h> int main(void) { int i; i = 0; while(i < 5){ printf("Hello!\n"); i++; } return 0; }
実行結果
Hello!
Hello!
Hello!
Hello!
Hello!
「Hello!」と5回繰り返して表示するプログラムです。
実際に私たちが物事を繰り返す場合、繰り返すための条件が必要になります。
例)庭の草をむしる → 疲れたらやめる
上記の場合、「疲れたら」が条件です。
次はどうでしょうか?
例)庭の草をむしる → 3本抜いたらやめる
この場合の条件は「3本抜く」事です。
コンピュータは疲れたりしません。コンピュータ的に言えば「3本」などのように具体的な数値の方が判断しやすいものになります。
例えば何かを5回繰り返す場合、わたしたちは1,2,3,4,5と回数を数えますが、コンピュータも同じです。
ただ、コンピュータは0から始めることが何かと都合がよいので、先ほどのプログラムでも0,1,2,3,4と数えて5回カウントしています。
一定回数の繰り返し処理の場合、ポイントは3つあります。
1.カウンタ変数(回数を数えるための変数)の初期化
2.繰り返し条件の設定(1のカウンタ変数を使って条件式を設定)
3.カウンタ変数の増減(通常は、カウンタ変数を1ずつ加算)
1番から順に見ていきます。
1.カウンタ変数の初期化
カウンタ変数というのは
1, 2, 3, 4, 5… と数えるための変数です。
初期化という言葉は最初に戻す、という意味になります。今回は、1番から数えたいところですが、コンピュータは0から開始する方が何かと都合がいいので、初期値を0とすることが多いです。
i = 0;
という部分がこれに当たります。
2.繰り返し条件の設定
C言語では、繰り返すための条件を設定する必要があります。あくまで繰り返すための条件です。(プログラミング言語の多くは繰り返すための条件を記述することになっています)ですから、条件が成り立つときは繰り返しを行い、条件が成り立たなくなったら繰り返しをやめる、ということになります。
while(i < 5)の行の
i < 5
の部分が繰り返し条件です。
3.カウンタ変数の増減(通常は、カウンタ変数を1ずつ加算)
カウンタですので、一定の回数さえ数えることが出来れば、1ずつ加算しても1ずつ減算してもいいということになります。
ただ、通常は整数型の変数をインクリメント(1ずつ加算)してカウントを行うことが多いです。
i++;
の部分がこれに当たります。
ところでi = i + 1; と記述しても i++; と記述しても処理内容は同じ「1ずつ加算」です。
しかし、通常は i++; と記述することが一般的です。
理由は、処理が速いからです。インクリメント専用の回路がコンピュータには組み込まれています。
豆知識
このカウンタ用変数に必ずといって良いほどiから始まるi, j, kなどの変数名が使用されています。
理由はFortran(C言語以前に普及したプログラミング言語。フォートランと読む)という言語に由来しています。
Fortranでは、カウンタ変数にI, J, K と続く変数名しか使うことができませんでした。その名残りのようです。
実際のプログラムの流れを図示するとこんな感じです。
行番号で変数iの値を追ってみました。(ちなみにこれをトレースといいます)
※注1
10行目で変数iの値が変化していないのは、i++(後置きインクリメント)であるからです。++i(前置きインクリメント)とすれば10行目の時点で変数iが+1されます。
i++の場合は、次の処理(すなわち11行目)でiの値が+1されます。
※注2
繰り返し処理が終わる場合、11行目から13行目とはなりません。8行目から13行目といった順になります。
あくまで8行目のwhile文で条件判定をしているからです。
行番号 | 変数iの内容 | 備考 |
---|---|---|
5 | 未定 | |
7 | 0 | |
8 | 0 | 条件:0 < 5 真 |
9 | 0 | Hello! 表示 |
10 | 0 | |
11 | 1 | |
8 | 1 | 条件:1 < 5 真 |
9 | 1 | Hello! 表示 |
10 | 1 | |
11 | 2 | |
8 | 2 | 条件:2 < 5 真 |
9 | 2 | Hello! 表示 |
10 | 2 | |
11 | 3 | |
8 | 3 | 条件:3 < 5 真 |
9 | 3 | Hello! 表示 |
10 | 3 | |
11 | 4 | |
8 | 4 | 条件:4 < 5 真 |
9 | 4 | Hello! 表示 |
10 | 4 | |
11 | 5 | |
8 | 5 | 条件:5 < 5 偽 |
13 | 5 | return 0; 終了 |
一定回数の繰り返し処理のポイントは以下の3点です。
1.カウンタの初期化 i=0;
2.繰り返し条件の設定 i<5
3.カウンタ変数のインクリメント i++;
ということになります。これは次のfor文でも同じです。
この3つのポイントに注目して次のプログラムを見てください。
繰り返し処理(for文)
サンプルプログラム loop_for.c
/* loop_for.c */ #include <stdio.h> int main(void) { int i; for(i=0; i<5; i++){ printf("Hello!\n"); } return 0; }
ポイントは1行のみです。
while文では3行に分けて記述されていた
1.カウンタの初期化 i=0;
2.繰り返し条件の設定 i<5
3.カウンタ変数のインクリメント i++;
の部分が次の1行に集約されています。
for(i=0; i<5; i++){
for文は「;」で3つに分割して
for( 最初の1回だけ実行 ; 繰り返し条件 ; 2回目以降に実行)
のように処理を記述することができます。最初は面食らいますが、慣れると1行で書けるのでわたしはfor文が好きです。
while文は分かりやすいですが、for文は簡潔に記述できる感じがします。
実行結果は、先ほどのwhile文と変わりません。
実行結果
Hello!
Hello!
Hello!
Hello!
Hello!
for文を使うとwhile文より最低2行コードが短くなります。
また、while文同様に前判定のため、7行目のfor文の所から11行目に処理が移動してプログラムが終了します。
最後にdo~while文を紹介します。
繰り返し処理(do~while文)
サンプルプログラム loop_do_while.c
/* loop_do_while.c */ #include <stdio.h> int main(void) { int i; i = 0; do{ printf("Hello!\n"); i++; } while(i < 5); return 0; }
実行結果
Hello!
Hello!
Hello!
Hello!
Hello!
解説
ポイントは、8行目のdoです。
doは、英語で「~せよ」という意味なのでそのまま次のprintf関数が実行されます。
10行目の i++; でカウンタ変数を+1してから、11行目の while(i < 5); の繰り返し条件へと移ります。
do~while文には、whileの文末に「;」(セミコロン)がついています。
このセミコロンはつい忘れてしまいがちなので注意してください。
while文、for文との最大の違いは、while、forが設定した条件によっては、繰り返し処理が実行されないことがあるのに対し、do~while文は、繰り返し処理の最後に判定を行う為、必ず1回は処理を実行する、ということです。
一度も繰り返し処理をしないwhile文の例
例えば以下のプログラムは一度も9~10行目の処理を実行せずに(つまり何も表示されずに)終わります。
/* exit_while.c */ #include <stdio.h> int main(void) { int i; i = 0; while(i > 0){ printf("Hello!\n"); i++; } return 0; }
上記while文は、条件が i > 0 (変数iが0より大きい)の場合、繰り返すという意味になります。
変数iの初期値が0のため、最初から条件が偽(成り立たない)となります。
それに引き換えdo~while文で作った場合は、必ず1回は繰り返し処理を実行します。
3つの繰り返し処理を説明してきましたが、皆さんはどれがしっくりきますか?
私はfor文です。
コメント