今までのプログラムでは、書かれた指示をその順番にやっていきました。
今度はなにかの条件によって、やるかどうかを決める書き方を学びます。これを条件分岐といいます。
もっとも単純な条件分岐は次のようになものです。
if (条件) { 真の時に実行される文1; ... }
プログラムでは条件がかなうことを「真(しん)」、かなわないことを「偽(ぎ)」といいます。英語では true(トゥルー)と false(フォールス) です。
true と false という特別な値を定義する言語も多いのですが、C言語では条件には整数を使い、0 だったら「偽」。その他は「真」とします。
以下の課題は Hello.c と同様に実習します。
~/c$ gcc k0401.c -o k0401
)~/c$ ./k0401
)ifを使ったプログラムです。この色の部分は4回出てきますがまったく同じです。コピーすればよいでしょう。
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: }
行頭の番号とコロン(:)は解説のためにつけてあるものなので、プログラムには入力しません。
文字はここからエディタにコピーできますが、不要な改行やスペースが一緒にコピーされるとコンパイルできなくなることがあります。コピー後に不要なものを削除したり訂正する必要がないか確認しましょう。
重要なところはコピーせず自分で入力したほうが記憶に残ります。
int a = 1;
if (a){
{ }
内を実行します。a = 0;
if (a){
{ }
内を実行します。実行結果はこうなります。
~/c$ ./k0401 aの値は 1 なので、真 の扱いになります aの値は -1 なので、真 の扱いになります aの値は 2 なので、真 の扱いになります
a=0 の時だけ表示されていません。
条件に使う変数が増えました。k0401.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: }
int a = 1;
int b = 0;
if (a){
{ }
内を実行します。if (b){
{ }
内を実行します。実行結果は次のとおり。
~/c$ ./k0402 if の例を始めます aの値は 1 なので、真 の扱いになります if の例は終わりです。
if (条件) の条件の部分はこれまでやってきた様に整数の変数に加えて加減乗除の計算式も書けます。でもこれはC言語が「偽」を 0 で表し、その他を「真」としているのでできることです。本来はここは「真」「偽」の結果を計算してくれる比較演算式を書きます。
k0402.cに比べて色のついた部分が異なっています。条件部分とprintfの内部です。ifが4つに増えていますが、書き換えてから3行コピーしてまた少し書き換えると楽ができます。
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: }
if ( a == b ){
==
という演算子は a と b が等しいかどうかの判断をして等しいなら「真」の値を返します。if ( a != b ){
!=
という演算子は a と b が等しいかどうかの判断をして等くないなら「真」の値を返します。if ( a > b ){
>
という演算子は a の方が b より大きいかどうかの判断をして a が大きければ「真」の値を返します。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 |
k0403.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: }
if ( a == b ){ a,b が等しいときの処理; }else{ a,b が等しくないときの処理; }
if ( a > b ){ a > b であるときの処理; }else{ a > b でないときの処理; }
実行結果は
~/c$ ./k0404 if の例を始めます a と b は等しくない a は b より大きい if の例は終わりです。
k0404.c に比べてこの色の部分が違います。
また、[ - - - - ] でくくられた x1,x2,x3,x4 には次の語群から適当なものをいれて完成させなさい。
[a,b は等しい] [a,b は等しくない] [a は b より小さい] [a は b より小さくない]
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 の数値を変えても正しくなるか確認しなさい。(ソースを変更したら必ずもう一度コンパイルすること。ソースを変更してもコンパイルしなおさなければ元のままです)
k0404.c に比べて、この色の部分が異なるだけです。
a > b
を調べて偽となったときに a < b
とは限りません。a == b
の場合が考えられるからです。そこでa == b
もチェックして最後に a は b より小さいと判断するやり方です。
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: }
if ( a > b ){ a > b であるときの処理; }else if ( a == b ){ a==b であるときの処理; }else{ その他のときの処理 (事実上は a < b); }
実行結果は
~/c$ ./k0406 if の例を始めます a は b より小さい if の例は終わりです。
a,b の値を変えてためしてみて下さい。
k0406.c に比べて、この色の部分が異なるだけです。
15:-18:を書き換えたら、17:18:をコピーして40を30に変えるなどの工夫をすると楽ができます。
「20以上」という言い方は普通20かもしれないし20より大きいかもしれないという意味です。
a が10きざみでどのレベルにあるか調べるプログラムです。
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 以上 (こうはなりません)
k0407.c に比べて、この色の部分が異なるだけです。
a が10きざみでどのレベルにあるか調べるという意味では失敗のプログラムです。
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 がどんな値の時ですか
k0408.c に比べて、この色の部分が異なるだけです。
これも a が10きざみでどのレベルにあるか調べるという意味では失敗のプログラムです。
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 がどんな値の時ですか
k0409.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 未満
k0304.c に比べて、2:-12:は同じです。13:-21:は書き換えなければなりませんが、hen[i][0]+hen[i][1]-hen[i][2]の部分はそのまま使えます。
13:-21:ができたら、24:-32: 35:-43: 46:-54:はそれをコピーするだけです。
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{ どの条件も偽のときに実行される文; ... }聖愛中学高等学校