条件分岐

条件分岐とは

今までのプログラムでは、書かれた指示をその順番にやっていきました。

今度はなにかの条件によって、やるかどうかを決める書き方を学びます。これを条件分岐といいます。

もっとも単純な条件分岐は次のようになものです。

if (条件) {
    真の時に実行される文1;
    ...
} 

プログラムでは条件がかなうことを「真(しん)」、かなわないことを「偽(ぎ)」といいます。英語では true(トゥルー)と false(フォールス) です。

true と false という特別な値を定義する言語も多いのですが、C言語では条件には整数を使い、0 だったら「偽」。その他は「真」とします。

以下の課題は Hello.c と同様に実習します。

  1. エディタでプログラムを作り、指定されたファイル名(たとえばk0401.c)で保存します
  2. コンパイルします (たとえば ~/c$ gcc k0401.c -o k0401)
  3. 実行して結果を確認します。(たとえば ~/c$ ./k0401)
  4. コンパイルに失敗したり、実行結果が思わしくなければプログラムを修正して繰り返します。

課題4-1 ifを使った条件分岐

ifを使ったプログラムです。この色の部分は4回出てきますがまったく同じです。コピーすればよいでしょう。

プログラム名 k0401.c

 1: /* 配列を使う: k0401.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 1;
 7:    if ( a ){
 8:       printf( "aの値は %d なので、真 の扱いになります\n",a );
 9:    }
10:    a = 0;
11:    if ( a ){
12:       printf( "aの値は %d なので、真 の扱いになります\n",a );
13:    }
14:    a = -1;
15:    if ( a ){
16:       printf( "aの値は %d なので、真 の扱いになります\n",a );
17:    }
18:    a = 2;
19:    if ( a ){
20:       printf( "aの値は %d なので、真 の扱いになります\n",a );
21:    }
22:
23:    return 0;
24: }

行頭の番号とコロン(:)は解説のためにつけてあるものなので、プログラムには入力しません。

文字はここからエディタにコピーできますが、不要な改行やスペースが一緒にコピーされるとコンパイルできなくなることがあります。コピー後に不要なものを削除したり訂正する必要がないか確認しましょう。

重要なところはコピーせず自分で入力したほうが記憶に残ります。

プログラム解説 k0401.c

6:int a = 1;
aという名前の整数の変数を宣言し1を代入しています。
7: if (a){
aの値を判断します。aが0以外ならば「真」で、9:までの{ }内を実行します。
8:
a の値を表示し、真と扱われたことを表示します。
ifの範囲がわかりやすいように字下げ(行頭に空白を入れ最初の文字をさげる)をしています。
9:
7: から始まるifの範囲がここまでであることを示します。この場合は最後にセミコロンは不要です。
10:a = 0;
aに0を代入しています。いままでの1は忘れます。
11: if (a){
11:から13:までは7:から9:までとまったく同じです。
aの値を判断します。aが0以外ならば「真」で、9:までの{ }内を実行します。
12:
aが0なので実行されません。
ifの範囲がわかりやすいように字下げ(行頭に空白を入れ最初の文字をさげる)をしています。
13:
11: から始まるifの範囲がここまでであることを示します。この場合は最後にセミコロンは不要です。

実行結果はこうなります。

~/c$ ./k0401
aの値は 1 なので、真 の扱いになります
aの値は -1 なので、真 の扱いになります
aの値は 2 なので、真 の扱いになります

a=0 の時だけ表示されていません。

課題4-2 ifを使った条件分岐2

条件に使う変数が増えました。k0401.cに比べて色のついた部分が異なっています。また削除する部分もあります。

プログラム名 k0402.c

 1: /* 配列を使う: k0402.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 1;
 7:    int b = 0;
 8:    printf( "if の例を始めます\n" );
 9:    if ( a ){
10:       printf( "aの値は %d なので、真 の扱いになります\n",a );
11:    }
12:
13:    if ( b ){
14:       printf( "bの値は %d なので、真 の扱いになります\n",b );
15:    }
16:    printf( "if の例は終わりです。\n" );
17:
18:    return 0;
19: }

プログラム解説 k0402.c

6:int a = 1;
aという名前の整数の変数を宣言し1を代入しています。
7:int b = 0;
bという名前の整数の変数を宣言し0を代入しています。
プログラムがうまく動いたら、a,bに1,0以外の数値を入れてコンパイルしなおし、結果をみてみるのもよいでしょう。
8:
この行はいつも実行され、「if の例を始めます」と表示されます
9: if (a){
aの値を判断します。aが0以外ならば「真」で、11:までの{ }内を実行します。
10:
a の値を表示し、真と扱われたことを表示します。
ifの範囲がわかりやすいように字下げ(行頭に空白を入れ最初の文字をさげる)をしています。
11:
9: から始まるifの範囲がここまでであることを示します。この場合は最後にセミコロンは不要です。
13: if (b){
bの値を判断します。bが0以外ならば「真」で、15:までの{ }内を実行します。
7:のb=0を変更しなければ「偽」になりますから、15:までの指示は実行されません。
14:
b の値を表示し、真と扱われたことを表示します。(偽なので実際には表示されません)
15:
13: から始まるifの範囲がここまでであることを示します。この場合は最後にセミコロンは不要です。
16:
この行はいつも実行され、「if の例は終わりです。」と表示されます

実行結果は次のとおり。

~/c$ ./k0402
if の例を始めます
aの値は 1 なので、真 の扱いになります
if の例は終わりです。

課題4-3 比較演算式

if (条件) の条件の部分はこれまでやってきた様に整数の変数に加えて加減乗除の計算式も書けます。でもこれはC言語が「偽」を 0 で表し、その他を「真」としているのでできることです。本来はここは「真」「偽」の結果を計算してくれる比較演算式を書きます。

k0402.cに比べて色のついた部分が異なっています。条件部分とprintfの内部です。ifが4つに増えていますが、書き換えてから3行コピーしてまた少し書き換えると楽ができます。

プログラム名 k0403.c

 1: /* 比較演算式: k0403.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 5;
 7:    int b = 2;
 8:    printf( "if の例を始めます\n" );
 9:    if ( a == b ){
10:       printf( "a と b は等しい\n" );
11:    }
12:    if ( a != b ){
13:       printf( "a と b は等しくない\n" );
14:    }
15:    if ( a > b ){
16:       printf( "a は b より大きい\n" );
17:    }
18:    if ( a < b ){
19:       printf( "a は b より小さい\n" );
20:    }
21:    printf( "if の例は終わりです。\n" );
22:
23:    return 0;
24: }

プログラム解説 k0403.c

9:if ( a == b ){
==という演算子は a と b が等しいかどうかの判断をして等しいなら「真」の値を返します。
この == を = と書くのは間違いなので注意すること。
10:
9:で真になると実行されます
11:
ここまでが 最初の if の範囲です。
12:if ( a != b ){
!=という演算子は a と b が等しいかどうかの判断をして等くないなら「真」の値を返します。
15:if ( a > b ){
>という演算子は a の方が b より大きいかどうかの判断をして a が大きければ「真」の値を返します。
18:if ( a < b ){
<という演算子は a の方が b より小さいかどうかの判断をして a が小さければ「真」の値を返します。

実行結果はこうなります。

~/c$ ./k0403
if の例を始めます
a と b は等しくない
a は b より大きい
if の例は終わりです。

比較演算子一覧

比較演算子 説明 真になる例 偽になる例
== 等しいとき真
= と書くのは間違い
2 == 2 3 == 4
!= 等しくないとき真 3 == 4 2 == 2
> 左辺の数が右辺より大きいときに真 8 > 2 1 > 1
< 左辺の数が右辺より小さいときに真 1 < 10 8 < 2
>= 左辺の数が右辺の数より大きいか、または等しいときに真 4 >= 4 3 >= 5
<= 左辺の数が右辺の数より小さいか、または等しいときに真 3 <= 4 9 <= 1

課題4-4 if~else

k0403.c に比べてこの色の部分だけ異なります。。

プログラム名 k0404.c

 1: /* if else : k0404.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 5;
 7:    int b = 2;
 8:    printf( "if の例を始めます\n" );
 9:    if ( a == b ){
10:       printf( "a と b は等しい\n" );
11:    }else{
12:       printf( "a と b は等しくない\n" );
13:    }
14:
15:    if ( a > b ){
16:       printf( "a は b より大きい\n" );
17:    }else{
18:       printf( "a は b より大きくはない。(a は b より小さいか 等しいかのどちらか)\n" );
19:    }
20:
21:    printf( "if の例は終わりです。\n" );
22:
23:    return 0;
24: }

プログラム解説 k0404.c

9:-13: ひとつめの if-else
if ( a == b ){
   a,b が等しいときの処理;
}else{
   a,b が等しくないときの処理;
}
この == を = と書くのは間違いなので注意すること。
15:-19: ふたつめの if-else
if ( a > b ){
   a > b であるときの処理;
}else{
   a > b でないときの処理;
}

実行結果は

~/c$ ./k0404
if の例を始めます
a と b は等しくない
a は b より大きい
if の例は終わりです。

課題4-5 なにが入る?

k0404.c に比べてこの色の部分が違います。

また、[ - - - - ] でくくられた x1,x2,x3,x4 には次の語群から適当なものをいれて完成させなさい。

[a,b は等しい] [a,b は等しくない] [a は b より小さい] [a は b より小さくない]

プログラム名 k0405.c

 1: /* if elseif : k0405.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 5;
 7:    int b = 8;
 8:    printf( "if の例を始めます\n" );
 9:    if ( a != b ){
10:       printf( "[ - - x1 - - ]\n" );
11:    }else{
12:       printf( "[ - - x2 - - ]\n" );
13:    }
14:
15:    if ( a < b ){
16:       printf( "[ - - x3 - - ]\n" );
17:    }else{
18:       printf( "[ - - x4 - - ]\n" );
19:    }
20:
21:    printf( "if の例は終わりです。\n" );
22:
23:    return 0;
24: }

完成したら、a,b の数値を変えても正しくなるか確認しなさい。(ソースを変更したら必ずもう一度コンパイルすること。ソースを変更してもコンパイルしなおさなければ元のままです)

課題4-6 if~else if~else

k0404.c に比べて、この色の部分が異なるだけです。

a > bを調べて偽となったときに a < bとは限りません。a == bの場合が考えられるからです。そこでa == bもチェックして最後に a は b より小さいと判断するやり方です。

プログラム名 k0406.c

 1: /* 多段階のif: k0406.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 5;
 7:    int b = 8;
 8:    printf( "if の例を始めます\n" );
 9:       /* 9:-13: は削除します */ 
14:
15:    if ( a > b ){
16:        printf( "a は b より大きい\n" );
17:    }else if ( a == 0 ){
18:        printf( "a, b は等しい\n" );
19:    }else{
20:        printf( "a は b より小さい\n" );
21:    }
22:    printf( "if の例は終わりです。\n" );
23:
24:    return 0;
25: }

プログラム解説 k0406.c

17:15:の条件で偽になったもののなかでさらに絞り込む
ただの if ではありません。elseにきた「a の方が b より小さいか等しいかのどちらか」からa,bが等しい場合に絞り込みます。
19:
ここのelseは ( a > b )でもなく、( a == b )でもないものという意味です。
15:-21: if - else if - else
if ( a > b ){
   a > b であるときの処理;
}else if ( a == b ){
   a==b であるときの処理;
}else{
   その他のときの処理  (事実上は a < b);
}

実行結果は

~/c$ ./k0406
if の例を始めます
a は b より小さい
if の例は終わりです。

a,b の値を変えてためしてみて下さい。

課題4-7 たくさんの else if

k0406.c に比べて、この色の部分が異なるだけです。

15:-18:を書き換えたら、17:18:をコピーして40を30に変えるなどの工夫をすると楽ができます。

「20以上」という言い方は普通20かもしれないし20より大きいかもしれないという意味です。

a が10きざみでどのレベルにあるか調べるプログラムです。

プログラム名 k0407.c

 1: /* たくさんの else if: k0407.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 38;
15:    if ( a >= 50 ){
16:       printf( "a は 50 以上\n" );
17:    }else if ( a >= 40 ){
18:       printf( "a は 40 以上\n" );
19:    }else if ( a >= 30 ){
20:       printf( "a は 30 以上\n" );
21:    }else if ( a >= 20 ){
22:       printf( "a は 20 以上\n" );
23:    }else if ( a >= 10 ){
24:       printf( "a は 10 以上\n" );
25:    }else{
26:       printf( "a は 10 未満\n" );
27:    }
28:
29:    return 0;
30: }

実行結果は

~/c$ ./k0407
a は 30 以上

次の様にはなりません

~/c$ ./k0407
a は 30 以上
a は 20 以上
a は 10 以上  (こうはなりません)

課題4-8 失敗例1

k0407.c に比べて、この色の部分が異なるだけです。

a が10きざみでどのレベルにあるか調べるという意味では失敗のプログラムです。

プログラム名 k0408.c

 1: /* たくさんの else if: k0408.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 38;
15:    if ( a >= 10 ){
16:       printf( "a は 10 以上\n" );
17:    }else if ( a >= 20 ){
18:       printf( "a は 20 以上\n" );
19:    }else if ( a >= 30 ){
20:       printf( "a は 30 以上\n" );
21:    }else if ( a >= 40 ){
22:       printf( "a は 40 以上\n" );
23:    }else if ( a >= 50 ){
24:       printf( "a は 50 以上\n" );
25:    }else{
26:       printf( "どれにもあてはまりませんでした\n" );
27:     }
28:
29:    return 0;
30: }

実行結果は

~/c$ ./k0408
a は 10 以上

次の様にはなりません

~/c$ ./k0407
a は 30 以上  (こうはなりません)

「どれにもあてはまりませんでした」となるのは、a がどんな値の時ですか

課題4-9 失敗例2

k0408.c に比べて、この色の部分が異なるだけです。

これも a が10きざみでどのレベルにあるか調べるという意味では失敗のプログラムです。

プログラム名 k0409.c

 1: /* たくさんの else if: k0409.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 38;
15:    if ( a < 50 ){
16:       printf( "a は 50 未満\n" );
17:    }else if ( a < 40 ){
18:       printf( "a は 40 未満\n" );
19:    }else if ( a < 30 ){
20:       printf( "a は 30 未満\n" );
21:    }else if ( a < 20 ){
22:       printf( "a は 20 未満\n" );
23:    }else if ( a < 10 ){
24:       printf( "a は 10 未満\n" );
25:    }else{
26:       printf( "どれにもあてはまりませんでした\n" );
27:     }
28:
29:    return 0;
30: }

実行結果は

~/c$ ./k0409
a は 50 未満

次の様にはなりません

~/c$ ./k0407
a 40 未満  (こうはなりません)

「どれにもあてはまりませんでした」となるのは、a がどんな値の時ですか

課題4-10 失敗例2の修正

k0409.c に比べて、この色の部分が異なるだけです。

プログラム名 k0410.c

 1: /* 失敗例2の修正: k0410.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:    int a = 38;
15:    if ( a < 10 ){
16:       printf( "a は 10 未満\n" );
17:    }else if ( a < 20 ){
18:       printf( "a は 20 未満\n" );
19:    }else if ( a < 30 ){
20:       printf( "a は 30 未満\n" );
21:    }else if ( a < 40 ){
22:       printf( "a は 40 未満\n" );
23:    }else if ( a < 50 ){
24:       printf( "a は 50 未満\n" );
25:    }else{
26:       printf( "a は 50 以上" );
27:    }
28:
29:    return 0;
30: }

実行結果は

~/c$ ./k0410
a は 40 未満

課題4-11 三角形ができるか

k0304.c に比べて、2:-12:は同じです。13:-21:は書き換えなければなりませんが、hen[i][0]+hen[i][1]-hen[i][2]の部分はそのまま使えます。

13:-21:ができたら、24:-32: 35:-43: 46:-54:はそれをコピーするだけです。

プログラム名 k0411.c

 1: /* 三角形ができるか: k0411.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     float hen[4][3] = { {12.1, 20  , 30.5},
 7:                         {23.4, 43.1, 10.2},
 8:                         {20.4, 33.1, 20.2},
 9:                         {14.3, 25.3, 30.0} };
10:     int i;
11:
12:     i = 0;
13:     if ( 0 > hen[i][0]+hen[i][1]-hen[i][2] ){
14:         printf( "三角形はできません。\n" );
15:     }else if ( 0 > hen[i][1]+hen[i][2]-hen[i][0] ){
16:         printf( "三角形はできません。\n" );
17:     }else if ( 0 > hen[i][2]+hen[i][0]-hen[i][1] ){
18:         printf( "三角形はできません。\n" );
19:     }else{
20:         printf( "三角形ができます。\n" );
21:     }
22:
23:     i = 1;
24:     if ( 0 > hen[i][0]+hen[i][1]-hen[i][2] ){
25:         printf( "三角形はできません。\n" );
26:     }else if ( 0 > hen[i][1]+hen[i][2]-hen[i][0] ){
27:         printf( "三角形はできません。\n" );
28:     }else if ( 0 > hen[i][2]+hen[i][0]-hen[i][1] ){
29:         printf( "三角形はできません。\n" );
30:     }else{
31:         printf( "三角形ができます。\n" );
32:     }
33:
34:     i = 2;
35:     if ( 0 > hen[i][0]+hen[i][1]-hen[i][2] ){
36:         printf( "三角形はできません。\n" );
37:     }else if ( 0 > hen[i][1]+hen[i][2]-hen[i][0] ){
38          printf( "三角形はできません。\n" );
39:     }else if ( 0 > hen[i][2]+hen[i][0]-hen[i][1] ){
40:         printf( "三角形はできません。\n" );
41:     }else{
42:         printf( "三角形ができます。\n" );
43:     }
44:
45:     i = 3;
46:     if ( 0 > hen[i][0]+hen[i][1]-hen[i][2] ){
47:         printf( "三角形はできません。\n" );
48:     }else if ( 0 > hen[i][1]+hen[i][2]-hen[i][0] ){
49:         printf( "三角形はできません。\n" );
50:     }else if ( 0 > hen[i][2]+hen[i][0]-hen[i][1] ){
51:         printf( "三角形はできません。\n" );
52:     }else{
53:         printf( "三角形ができます。\n" );
54:     }
55:
56:     return 0;
57: }

実行結果は

~/c$ ./k0411
三角形ができます。
三角形はできません。
三角形ができます。
三角形ができます。

条件分岐のまとめ

elseのないもの

if (条件){
    真の時に実行される文;
}

elseのあるもの(必ずどちらかが実行される)

if (条件){
    真の時に実行される文;
    ...
}else{
    偽の時に実行される文;
    ...
}

else ifのあるもの

最後のelseはなくてもよい。

elseがある場合は必ずどれかが実行される。elseがない場合は条件によりまったく実行されないことがある。

if (条件1){
    真の時に実行される文;
    ...
}else if (条件2){
    条件1が偽で条件2が真の時に実行される文;
    ...
}else if (条件3){
    条件1も条件2も偽で条件3が真の時に実行される文;
    ...
}else{
    どの条件も偽のときに実行される文;
    ...
}
聖愛中学高等学校
http://www.seiai.ed.jp/
Oct. 2011