Previous: 制御構造1 繰り返し --- for文
Up: 制御構造1 繰り返し --- for文
Next: 括弧の対応関係 --- vi の便利なコマンド
Previous Page: 制御構造1 繰り返し --- for文
Next Page: 括弧の対応関係 --- vi の便利なコマンド
繰り返し(ループ)書式を以下に示す。
for ( 初期化 ; 継続条件 ; 増分処理 ){ 文 }
先に説明した3つの要素を括弧の中に書くが、セミコロンで必ず区切らなければ ならない。
従って、繰り返しは次のような順序で行なわれる。
文の実行の最中に以降の繰り返しをそれまでの継続条件の如何にかかわりなく、 終わらせるためには、break 文を用いる。
for ( i=0; i<10; i=i+1 ){ printf("おはよう\n"); }この例では、初期化は i=0 で、整数変数 i に 0 を代入し、i < 10 が真で ある内は printf を実行する。最後の i = i + 1 が実際に i の値を増やしている。
注意 i = i + 1 は、数学的には明らかにおかしいが、c 言語では正しい式である。 なぜならば、= は等号ではなく、代入演算だからであり、まず、右辺の i + 1 が実行 されて、評価される。例えば、最初に i = 0 だったならば、 i + 1 は、1 と評価され、その結果が、改めて、i に代入される。 つまり、i + 1 の結果は、一旦別の場所に 保存されているから、こうしたことが可能になる。 (このことは、i + 1 を実行しても i の値は変わらないことからも分かる。)
for ( i=10; i>0; i=i-1 ){ printf("Hello!\n"); }この例は、先の例と同じであるが、初めが i=10 で、1づつ減らしながら、 i=1 まで逆順に10回のループを回している。
int i,x; x=0; for ( i=2; i<=20; i=i+2 ){ x = x + i; }この例は、初期値は i=2 で、増分は 2 で、i が 20 になるまで、x に その値を足していっている。結果は、10 * (2 + 20)/2 = 110 となる。
x = 2; /* 初期化条件がループの外にある */ for ( ; x < 1000 ; ){ x = x * x; }この例は、間違っているようであるが、実はなんの問題もなく実行できる。 先に説明したとおり、初期化と増分処理は何の評価もしない。つまり、for 文の 実行には何の関係もしない(勿論、セミコロンを省略することは出来ない。) 従って、何もしないという意味で、空欄であってもよい。この例の場合は、
for (;;){ }これも文法的には正しい。実は、for 文は継続条件の欄も空白であってよい。 勿論、その場合、継続条件がないので、終了しない! こうしたループを無限ループという。(決してやってみないこと。) こうした無限ループを終わらせる方法は、後に勉強する。
for ( i=0; i<10; i=i+1 ){ i=2; }これは、何も恐ろしくないように見えるが、実はこれも無限ループになっている。 なぜならば、i=2; が常に実行されるので(実際は、2回目以降の増分処理で i=i+1 が継続検査の前に実行されるので、継続検査の時には必ず i=3 となっている)、 i<10 の継続検査が常に真となり、永遠に偽になることはない。
このように、c 言語では、繰り返しの変数も変数なので、ループの中で自由に値を 変えることが出来るので、注意が必要である。
i = 10; for ( ; i<10; i=i+1 ){ printf("Hello!\n"); }この例の場合、初期化を行なっておらず、ループの前で、i = 10 を実行している ので、継続検査において偽となり、ループは1回も実行されない。
for ( i=1; i<10; i=i+1 ){ if (i==5){ i=11; } }これは、一種の反則技であるが、ループ変数も変数であることを利用して、 for 文の中の if 文で、i が5に等しくなったら、強制的に i を 11 に しているために、次の継続検査で偽となり、ループを抜けてしまう。
for ( i=1; i<10; i=i+1 ){ if (i==5){ break; } }これは、例8と同じで、i の値が5になったらループを抜けるための 正式なやり方である。break は、繰り返しを止めてしまえ、という命令である。