トラック6・🔀制御構造

else if / else の分かれ道設計

読む目安 約11分・ゴール:else / else if で複数の分かれ道を作れるようになり、範囲判定の順序を正しく設計できる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

天気予報を見て服を決めます。「雨なら傘、曇りなら折りたたみ、それ以外なら帽子」。道は2本ではなく3本です。分かれ道が3本以上になったらelse ifの出番です。

if (条件A) {
    Aが真のときの処理
} else if (条件B) {
    Aが偽で、Bが真のときの処理
} else {
    どれも真でなかったときの処理
}

動きの要点はひとつだけ。上から順に確かめ、最初に真になった枝だけを実行して、残りは見ずに抜ける。これさえ押さえれば else if で迷うことはありません。

成績判定で試しましょう。

#include <stdio.h>

int main(void) {
    int score = 72;

    if (score >= 90) {
        printf("評価 A\n");
    } else if (score >= 80) {
        printf("評価 B\n");
    } else if (score >= 70) {
        printf("評価 C\n");
    } else {
        printf("評価 D\n");
    }
    return 0;
}

72点は >= 90 が偽、>= 80 も偽、>= 70 が真なので「評価 C」。ここで判定は打ち切られ、else へは行きません。

ここで、else if と「if をただ並べたもの」の違いも押さえておきましょう。if (A) { … } if (B) { … } と書くと A と B は別々に判定されるので、両方が真なら両方とも実行されます。else if でつなぐと「どれか1つだけ」になります。1つだけ選びたいのか、当てはまるものを全部実行したいのか——書く前に決めておくと、条件が増えたときに迷いません。

さて、この形には有名な落とし穴があります。順番を逆にすると、全部が最初の条件に吸い込まれます。

#include <stdio.h>

int main(void) {
    int score = 95;

    if (score >= 70) {
        printf("評価 C\n");        // 95点でもここに入ってしまう
    } else if (score >= 80) {
        printf("評価 B\n");        // ここへは永遠に来ない
    } else if (score >= 90) {
        printf("評価 A\n");        // ここも同じ
    }
    return 0;
}

95点なのに「評価 C」。else if は「上の条件がすべて偽のとき」しか評価されないので、ゆるい条件を先頭に置くと、下の枝が全部死にます。しかもコンパイルは通り、エラーも警告も出ません。範囲で分けるときは、狭い(厳しい)条件から順に並べる。これが鉄則です。

もうひとつ、最後の else を省くかどうかの話。省いても文法上は問題ありませんが、「どれにも当てはまらない値」が無言で素通りしていきます。想定外の入力ほど、あとで痛い目を見ます。とりあえず else を書いて「ここには来ないはず」というメッセージを出しておくと、来たときにすぐ気づけます。

師範else if の並びは、ふるいの目の粗さじゃ。細かいふるいから順にかけよ。粗いふるいを先に置けば、何も残らぬ

まとめます。else if は上から順、最初に真になった1本だけ。範囲判定は厳しい順に並べる。else は「想定外」の受け皿として置いておく。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

次のプログラムを実行すると、何が表示されますか。

#include <stdio.h>

int main(void) {
    int score = 85;

    if (score >= 90) {
        printf("A\n");
    } else if (score >= 80) {
        printf("B\n");
    } else if (score >= 70) {
        printf("C\n");
    } else {
        printf("D\n");
    }
    return 0;
}
  1. B
  2. B と C の2行
  3. C
  4. B と C と D の3行
答えを見る

正解:A(B)

else if は上から順に判定し、最初に真になった枝だけを実行して、残りは見ずに抜けます。85点は >= 90 が偽、>= 80 が真なので「B」を表示して、そこで終わりです。>= 70 も条件としては真ですが、そこへはたどり着きません。

確認問題 2

次のコードで、score が 95 のときに表示されるものはどれですか。

if (score >= 70) {
    printf("C\n");
} else if (score >= 80) {
    printf("B\n");
} else if (score >= 90) {
    printf("A\n");
}
  1. A
  2. B
  3. C
  4. 何も表示されない
答えを見る

正解:C(C)

95 は最初の score >= 70 で真になるので、そこで「C」を表示して終わります。else if は「上の条件がすべて偽のとき」しか評価されないため、何点であってもBやAには絶対に届きません。コンパイルは通り、警告も出ないのが厄介なところです。範囲で分けるときは、狭い(厳しい)条件から順に並べるのが鉄則です。

「制御構造」の目次

  1. 流れを変える——制御構造の全体像
  2. if文——もしも、の分かれ道
  3. else if / else の分かれ道設計
  4. 条件式の罠——= と == の悲劇
  5. 論理演算子と短絡評価
  6. switch文とfallthrough
  7. for文——回数が決まった繰り返し
  8. while文——条件が決める繰り返し
  9. do-while文と入力チェック
  10. breakとcontinueの使いどころ
  11. ループのネストと九九表
  12. 無限ループとの付き合い方

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版