条件分岐 if

Last-modified: 2014-04-30 (水) 19:34:11
 

目標

if 文を利用して、条件分岐が書けるようになる。

プログラムの構造化定理

プログラムは次の3つの構造の組み合わせで、どんなことでも表現できることが数学的に証明されています。

  • 連接 (順次)
  • 分岐 (選択)
  • 繰り返し

連接は、上から下にへ、書かれた順番でプログラムを実行するという意味です。
これは、今までのプログラムで無意識に利用してきました。

今日は、2番目の分岐にあたる構造を勉強します。

分岐とは

分岐とはどのようなものか、簡単な例で例えてみましょう。

学校がある日に、台風が来たと仮定します。
その時、朝起きたあなたは次のような行動を取るでしょう。

  • 暴風警報が出ているか調べる
    • 暴風警報が出ている
      自宅待機
    • 暴風警報が出ていない
      仕方ないので学校へ行く

これをC言語で表現すると、次のようになります。

if(暴風警報が出ている場合){
    自宅待機;
}

else {
    仕方ないので学校へ行く;
}

C言語で分岐を実現するためには、上の例のように if 文と呼ばれるものを使用します。
if 文では、このように、「もし~なら~をする。」といった処理を行うことができます。

if 文の形式

if 文は次のような形式で使用します。

  • 形式1
    if(条件){
        条件が成り立った時に実行する文;
    }
  • 形式2
    if(条件){
        条件が成り立った時に実行する文;
    }
    
    else {
        条件が成り立たないときに実行する文;
    }
  • 形式3
    if(条件1){
        条件1が成り立った時に実行する文;
    }
    
    else if(条件2){
        条件2が成り立った時に実行する文;
    }
    
    else if(条件3){
        条件3が成り立った時に実行する文;
    }
    
    ...
    
    else {
        条件が1つも成り立たないときに実行する文;
    }

形式 1, 2, 3 とありますが、形式 1, 2 は形式 3 を省略したものです。
形式 3 では、条件が 3 つ指定してありますが、これはいくつでも構いません。
形式 3 で、最後の else を省略することも可能です。

また、条件が成り立った時、成り立たなかった時に実行する文は1行でなくても構いません。

関係演算子

条件を表す際には関係演算子と呼ばれるものを利用します。
関係演算子は、名前の通り2つの値の関係を表すものです。
それに対して、四則演算に使う演算子のことを、算術演算子と呼びます。

関係演算子では、2つの値を比較し、その結果をで表します。
一般的に、真の場合は 1、偽の場合は 0 が比較結果になります *1
C言語では、0 以外の値は、すべて真として扱われます。

関係演算子の一覧

C言語数学での表現意味C言語の例例の意味
===等号a == ba と b は等しい
!=不等号a != ba と b は等しくない
>>大なりa > ba のほうが b より大きい
<<小なりa < ba のほうが b より小さい
>=以上a >= ba は b 以上である
<=以下a <= ba は b 以下である

数学で使う記号と類似しているためすぐに覚えられると想いますが、
初心者は == を間違えやすい傾向にあります。

C言語では、= は代入を表します。== には代入の意味はありません。
=== では意味は全く異なりますので注意してください。

if 文の例

if の使用例です。
どうしてこうなるのか、自分で実行して考えてみてください。

例1

ゼロ未満の数が入力されたら、エラーを表示する。

int n;

scanf("%d", &n);

if(n < 0){
    printf("ゼロ以上の数を入力してください。");
}

例2

ユーザーが入力した数が、ゼロであるか表示する。

int n;

scanf("%d", &n);

if(n == 0){
    printf("ゼロです。\n");
}

else {
    printf("ゼロではありません。\n");
}

例3

ユーザーが入力した数が、0 より大きいか、0 より小さいか表示する。

int n;

scanf("%d", &n);

if(n > 0){
    printf("ゼロより大きいです。\n");
}

else if(n < 0){
    printf("ゼロより小さいです。\n");
}

else {
    printf("ゼロです。\n");
}

例4

ユーザーが入力した数が 100 より大きいか、50 より大きいか、50より小さいかを表示する。

int n;

scanf("%d", &n);

if(n > 100){
    printf("100より大きいです。\n");
}

else if(n > 50){
    printf("50より大きく、100以下です。\n");
}

else {
    printf("50より小さいです。\n");
}

論理演算子

複数の条件を組み合わせてひとつの条件にしたい場合、論理演算子と呼ばれるものを使います。
論理演算子には次の3つがあります。

条件式意味例の意味
条件1 && 条件2AND (かつ)x > 0 && y == 0x が 0 より大きい、かつ y が 0
条件1 || 条件2OR (または)x == 1 || y == 3x が 1 もしくは y が 3
!条件NOT (否定)!(x < 0)x が 0 未満でない

次のように使用します。

if(a == 0 && b == 0){
    printf("a も b もゼロです。\n");
}

これら論理演算子は、複数組み合わせることができます。

if(a == 0 && b == 0 && (c == 0 || d == 0)){
    printf("a,b が 0 であり、c か d のどちらかも 0 です。\n");
}

switch 文

条件分岐を実現するために、if 文の他にも switch 文というものも用意されています。
興味のある方は、調べてみてください。

課題

課題1

int 型の変数 a を用意し、標準入力から読み込み、その数が偶数であるか奇数であるか判定しなさい。

実行例

./a.out
3
奇数です
./a.out
4
偶数です

課題2

標準入力 で作成した2次方程式のプログラムを改造し、重解の場合は 1 つだけ表示するようにしなさい。重解の判定には、判別式を用いること。

実行例

./a.out
1 1 -6
2.000000 -3.000000
./a.out
1 8 16
-4.000000
./a.out
2 5 3
-1.000000 -1.500000

課題3

int 型の変数 a を用意し、標準入力から入力してください。
もし、変数 a が

  • 3 の倍数であるならば Fizz
  • 5 の倍数ならば Buzz
  • 3 の倍数でも 5 の倍数でもあるならば FizzBuzz
  • それ以外の場合は a 自身

を出力しなさい。

実行例

./a.out
6
Fizz
./a.out
25
Buzz
./a.out
30
FizzBuzz
./a.out
22
22

課題4

int 型の変数 year を用意し、標準入力から読み込み、変数 year が

  • うるう年であれば leap year
  • うるう年でなければ not leap year

を出力しなさい*2

実行例

./a.out
2012
leap year
./a.out
2015
not leap year
./a.out
1900
not leap year
./a.out
2000
leap year

挑戦課題

 


*1 真の場合が 1 であることは厳密には保証されていないので、これに依存するコードを書くのはやめましょう。
*2 うるう年の定義って何だったかなぁ