プログラミング

C言語超入門③ if文とswitch文で条件分岐しよう

if、else、比較演算子、論理演算子、switchを使い、条件によって処理を変える方法を学びます。

「60点以上なら合格。それ以外なら復習」。人ならすぐ判断できますが、プログラムには判断の順番をはっきり書く必要があります。

そのための道具が条件分岐です。今回はifで範囲を判定し、switchで選択肢を分けます。「動いたけれど、境目の値だけ間違う」を防ぐところまで見ていきましょう。

短いコードは、#include <stdio.h>を置いたプログラムのmain内で試します。入力の書き方は前回を参照してください。

1. ifは「条件を満たしたときだけ」

#include <stdio.h>

int main(void) {
    int score = 75;

    if (score >= 60) {
        printf("合格です。\n");
    }
    printf("判定を終えました。\n");
    return 0;
}
合格です。
判定を終えました。

score >= 60は「点数が60以上か」という条件です。ifの丸かっこの中で判断し、当てはまれば波かっこの中へ進みます。

値を55へ変えると、「合格です」は表示されず、「判定を終えました」だけが表示されます。最後の表示はifの外側なので、条件にかかわらず実行するからです。

C言語では、条件の結果が0なら偽、0以外なら真として扱います。比較式は、成り立つと1、成り立たないと0になります。

2. elseで「それ以外」を書く

int score = 55;

if (score >= 60) {
    printf("合格です。\n");
} else {
    printf("復習して、もう一度挑戦しましょう。\n");
}

elseは「直前のifに当てはまらなかった場合」です。改めてscore < 60と書かなくても、残った場合を受け持ちます。

この例では55が60以上ではないため、下のメッセージだけが表示されます。2つが両方実行されるわけではありません。

3. 3段階ならelse ifを使う

int score = 75;

if (score >= 80) {
    printf("よくできました。\n");
} else if (score >= 60) {
    printf("合格です。\n");
} else {
    printf("復習しましょう。\n");
}

75点のときの流れを追います。

  1. 75 >= 80は偽なので、最初の表示はしない
  2. 75 >= 60は真なので、「合格です」を表示する
  3. 残りのelseは実行せず、分岐の先へ進む

ここでscore >= 60を一番上に置くとどうなるでしょう。85点も最初の条件に当てはまり、「よくできました」の判定へ届かなくなります。

範囲が重なる条件は、狭い条件を先に置くと考えやすくなります。ただし、それが唯一の書き方ではありません。小さい値からscore < 60、score < 80の順に調べる方法もあります。

ifを別々に書いた場合とは違う

int score = 85;

if (score >= 80) {
    printf("80点以上\n");
}
if (score >= 60) {
    printf("60点以上\n");
}

これは独立した2つの判断なので、両方表示します。1つの結果だけを選ぶならif / else if / else、条件ごとに追加処理するなら独立したifが向きます。

4. 比較の記号を整理する

記号 意味 60を境にした例
== 等しい score == 60
!= 等しくない score != 60
> より大きい 60自身は含まない
< より小さい 60自身は含まない
>= 以上 60自身を含む
<= 以下 60自身を含む

特に間違えやすいのが=と==です。if (score = 60)は比較ではなく、scoreを60へ変更する代入になってしまいます。代入した値が0以外なので、条件も真になります。

「コンパイルできたから正しい」とは言えないところが、やっかいですね。-Wall -Wextraなどの警告も見ながら、比較は等号2つと確認しましょう。

MicrosoftのC言語if文の説明では、条件の真偽と分岐の範囲を確認できます。

5. 「かつ」「または」で条件を組み合わせる

記号 意味 例
&& 両方を満たす 0以上、かつ100以下
|| 少なくとも片方を満たす 0未満、または100より大きい
! 真偽を反対にする 条件を満たしていない
int score = 75;

if (score >= 0 && score <= 100) {
    printf("点数の範囲内です。\n");
}
if (score < 0 || score > 100) {
    printf("点数の範囲外です。\n");
}

0 <= score <= 100とは書きません。C言語では左の比較結果が0か1になり、その結果を100以下か調べる形になるため、意図した範囲判定になりません。

条件が長いときは、(age >= 18 && hasTicket) || isStaffのように、意味のまとまりをかっこで示すと読み間違いを減らせます。

左だけで決まれば、右は調べない

&&は左が偽なら右を実行せず、||は左が真なら右を実行しません。これが短絡評価です。

int total = 10;
int count = 0;

if (count != 0 && total / count >= 2) {
    printf("平均は2以上です。\n");
}

count != 0が偽なので、0で割る式へ進みません。逆の順番にすると先に割ってしまいます。「危険な処理をしてから確認」では遅いので、確認を左へ置きます。

6. switchでメニュー番号を選ぶ

点数のような範囲ではなく、「1なら開始、2なら設定」と決まった値を選ぶ場合はswitchが読みやすくなります。

int menu = 2;

switch (menu) {
    case 1:
        printf("ゲームを始めます。\n");
        break;
    case 2:
        printf("設定を開きます。\n");
        break;
    default:
        printf("1か2を選んでください。\n");
        break;
}

menuの値に一致するcaseから実行し、breakでswitchを抜けます。どれにも一致しないときがdefaultです。

breakを消すと、次のcaseに書かれた処理へ流れ続けます。これをフォールスルーと呼びます。後ろのcaseと値が一致したからではありません。初心者のメニューでは、各処理の最後にbreakを置く方が分かりやすいでしょう。

C言語のswitchは整数や文字定数などを使います。文字列や、case score >= 60:のような条件式による範囲判定には使いません。

7. 間違いを見つけるには、境目を試す

60点で合格、80点で上の評価なら、59・60・79・80を試します。

点数 期待する結果
59 復習
60 合格
79 合格
80 よくできました

このような境目の確認を境界値のテストと呼びます。75だけ試すより、>と>=の間違いを見つけやすくなります。

また、if (条件);のように丸かっこの直後へ;を付けると、何もしない文が条件の対象になります。波かっこの中が条件と無関係に動く原因になるので、余分なセミコロンにも注意してください。

8. 練習:正・ゼロ・負を分けよう

-999から999までの整数を1つ入力し、正の数・0・負の数に分けて表示します。入力が数として読めなかったら、計算せず終了してください。

模範解答

#include <stdio.h>

int main(void) {
    int number = 0;

    printf("integer (-999 to 999): ");
    if (scanf("%4d", &number) != 1 ||
        number < -999 || number > 999) {
        printf("入力を確認してください。\n");
        return 1;
    }

    if (number > 0) {
        printf("0より大きいです。\n");
    } else if (number == 0) {
        printf("0です。\n");
    } else {
        printf("0より小さいです。\n");
    }
    return 0;
}

解説

入力を確認した後、まず正かどうか、次に0かどうかを判定します。その両方ではない整数は負なので、最後はelseだけで足ります。

5なら最初、0なら2番目、-5なら最後へ進みます。number >= 0を最初にすると0まで最初の分岐へ入るため、ここでは>を使います。

なお、このscanfは先頭の数値部分を読む練習用です。5abcなど行全体の不正入力を拒否する方法は、最終回の入力処理で扱います。

次の一歩

分岐を書くときは、「どんな値を入れるか」「どれを表示したいか」を先に日本語で書くと、条件へ変換しやすくなります。

次は、同じ判定や表示を何度も行う繰り返しへ進みましょう。

前の回 / 次の回:繰り返し

← 記事一覧へ戻る