C の基本:分岐
条件によって処理を変える
条件式が真か偽かで処理を変えるのが条件分岐(conditional branch)であり、Cでは次の様なif文によって実現されます。
if (条件式1)
条件式1が真の場合の処理
else if (条件式2)
条件式2が真の場合の処理
...
else if (条件式N)
条件式Nが真の場合の処理
else
条件式が全て偽の場合の処理
else if部分の数はいくつでもよく、else ifやelseは省略可能です。また処理内容は単一の文で書いても、ブロックを用いてもよいです。
if (cond)
printf("cond is true.");
if (cond)
{
printf("cond is true.");
}
(ただし、某社の gotofail バグの様なものを防ぐ為に単文でも{ }を省略すべきでないという見方もあります。参考:「EXP19-C. if、for、while 文の本体は波括弧で囲む」、「AppleがiOS7.0.6で修正したSSLバグの簡単な解説 - Qiita」)
ラベルと無条件分岐
何も条件を付けず、必ず処理が飛ぶ様にする事もできます。
ジャンプする先はラベル(label)により指定します。
ラベル名:
何らかの文
goto文によってそのラベルへ飛ぶ事ができます。
goto ラベル名;
gotoは関数の色々な所から共通のエラー処理へ飛ばす場合や、
int some_process(void)
{
...
if (x == 0)
goto fail;
...
return 0;
fail:
fprintf(stderr, "Error!");
free_allocated_memory();
return -1;
}
深いループから抜ける場合などに有効です。
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (data[i][j] == 0)
goto exit_loop;
...
}
}
exit_loop: ;
値による場合分け
switch文を使うと
if (x == 1)
pattern1();
else if (x == 2)
pattern2();
else if (x == 3)
pattern3();
の様な場合分けをより簡単に書く事ができます。
switch (式)
{
case 値1 :
式が値1になる場合の処理
...
case 値2:
式が値2になる場合の処理
...
default:
どれにも当て嵌らない場合の処理
...
}
式の値に対応するcaseがあればそこへ飛び、無ければdefaultに飛びます。defaultは省略可能です。
飛んだ後は特に何もアフターケアが無く飛びっぱなしので、処理の最後にbreak;を書かないとその後のcaseも立て続けに実行されてしまいます。(フォールスルーと呼ばれます。)つまり、上のif文と同じ処理をするには
switch (x)
{
case 1:
pattern_one();
break;
case 2:
pattern_two();
break;
case 3:
pattern_three();
break;
}
と書く必要があります。