int i;
i = 0;
while (i < 5) {
printf("おはようさん\n");
i++;
}
for というキーワードを使えば、これを次のように簡略化できます。
for (i = 0; i < 5; i++) {
printf("おはようさん\n");
}
これも for ( ) に続く { } 内が単一の文のときは、{ } を省略できます。
for (i = 0; i < 5; i++)
printf("おはようさん\n");
for の ( ) 内は ; に区切られた3つの部分からなり、
それぞれ「前処理」「継続条件」「継続処理」を記述します。
これらは右のような順序で実行されます。
for (前処理; 継続条件; 継続処理) {
繰り返すプログラム;
...
}
上の例では、i は 0→1→2→3→4 と変化し、
i == 5 となったときに条件を満たさなくなり、
繰り返しを終了します。
for の用途は while 同様、 一定回数の繰り返しだけに限りません。 次の例は、文字列の1字1字を取り出します。
for (i = 0; str[i] != '\0'; i++) {
printf("%d 文字目は %c\n", i, str[i]);
}
これは文字型の配列変数 str に格納されている文字列を、
先頭から1字ずつ取り出して出力します。
文字列の最後は '\0' で終わっていますから、
これが現れたら繰り返しを終了します。
for の継続条件を省略すると、処理を無限に繰り返します。
for (i = 0; ; i++) { ... }
i を1ずつ増しながら { ... } 内の処理を無限に繰り返します。
for ( ; ; ) { ... }
{ ... } 内の処理を無限に繰り返します。
while は ( ) 内の条件を省略できません。 上と同じことを行う場合には、条件として非 0 の整数値を指定します。
while (1) { ... }
条件において非 0 の整数は真を表し、0 は偽を表します。
while と同様、break や continue によって繰り返しを中断/継続できます。
for ( ; ; ) {
scanf("%d", &x);
if (x == 0) break; /* 0 が入力されたら終わり */
sum += x;
}
この例は入力された数値を合計します。
改行だけが入力されると繰り返しを終わります。
int i;
i = 10;
do {
printf("Hello\n");
}
while (--i > 0);
while () { ... } とは異なり、
繰り返しの継続条件の判定を { ... } の実行後に行うため、
継続条件によらず最低一回は処理を実行します。
上の例では、最初 i = 1 でも i = 0 でも1回 Hello が表示されます。
int i;
i = 0;
while (i < 5) {
if (i == 3) break;
printf("%d 回目\n", ++i);
}
これは i == 3 になったところで break が実行されて
while による繰り返しが終わるので「2 回目」までしか出力されません。
int i;
i = 0;
while (i < 5) {
if (i == 3) continue;
printf("%d 回目\n", ++i);
}
これは i == 3 になったところで continue が実行されて
残りの部分(printf)が飛ばされるので「3 回目」は出力されません。
int x;
scanf("%d", &x);
if (x == 1) {
printf("1番の処理\n");
}
else if (x == 2) {
printf("2番の処理\n");
}
else if (x == 3) {
printf("3番の処理\n");
}
else if (x == 4) {
printf("4番の処理\n");
}
else {
printf("そのような処理はできません\n");
}
この例のように、ある整数値に対して、
実行する処理が決まっているときは、switch を使うと便利です。
int x;
scanf("%d", &x);
switch (x) {
case 1: /* x == 1 のときここから下を実行 */
printf("1番の処理\n");
break;
case 2: /* x == 2 のときここから下を実行 */
printf("2番の処理\n");
break;
case 3: /* x == 3 のときここから下を実行 */
printf("3番の処理\n");
break;
case 4: /* x == 4 のときここから下を実行 */
printf("4番の処理\n");
break;
default: /* 上のいずれにも該当しないときここから下を実行 */
printf("そのような処理はできません\n");
break;
}
switch は、
switch (x) {
case 1:
printf("1番の処理\n");
case 2:
printf("2番の処理\n");
break;
...
上の例のように case 2: の前の break が無い場合は、
x == 1 のときは case 1: の処理の後 case 2: の処理も実行されます。
for (i = 0; i < 100; i++) {
switch (data[i]) {
case 0:
printf("%d番目のデータが0になっています\n");
break; /* この break は switch から抜け出すだけ */
}
}
for (i = 0; i < 100; i++) {
if (data[i] == 0) {
printf("%d番目のデータが0になっています\n");
break; /* この break は for による繰り返しを終了する */
}
}
上の1つ目の例のように switch を使った場合に、
2つ目の例のように for の外側まで脱出したいときには、
goto を使うことができます。
for (i = 0; i < 100; i++) {
switch (data[i]) {
case 0:
printf("%d番目のデータが0になっています\n");
goto out_of_loop; /* out_of_loop というラベルに直行 */
}
}
out_of_loop:
printf("終了\n");
「goto ラベル;」とすると、
そこから(同じ関数内にある)「ラベル:」が書かれたところに処理を移します。
「ラベル:」の後ろには文が必要です。
実行する処理がなければ、空文(セミコロン ";" のみ)を置いてください。
for や while による繰り返しが2重になっている場合も同様です。
for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
if (data[i][j] == 0) goto exit_loop;
}
}
exit_loop:
printf("(%d,%d) のデータが0です\n", i, j);
goto は安易に使うべきではありません。
エラー処理など、goto を使わないことによって、
かえってソースプログラムの可読性(読みやすさ)を下げることが
明らかな場合だけに限定して使用した方が無難でしょう。