C言語のきほん|switch文による条件分岐

選択肢が増えたらswitchの出番。条件分岐をスパッと読みやすく整理しよう。

多分岐の条件文」で出てきた if~else if~else~ は、幅広い条件を順番にチェックできてとても便利でした。
ただ、条件が「具体的な値のどれかに一致するか」で分岐したいとき、ifをずらーっと並べると、だんだん見づらくなってきます。

たとえば、入力が 1 ならこれ、2 ならそれ、3 ならあれ…みたいに「選択肢を列挙する」タイプの分岐です。
こういう場面で switch文 を使うと、分岐が 一覧っぽく並ぶので、読みやすく・書きやすくなります。

イメージとしては、ifが「条件を順番に照合していく」感じなのに対して、switchは「値に応じて分岐先をパッと選ぶ」感じです。

switch文の基本構文

まずは基本形を、意味が分かるように整理します。

switch (式) {
case 定数式1:
    文1;
    break;
case 定数式2:
    文2;
    break;
...
default:
    文m;
    break;
}

要素ごとの役割(重要ポイントを表で整理)

要素役割大事な注意
分岐の元になる値(結果が整数型または文字型)doubleなどの浮動小数点は使えない
case 定数式分岐先の目印(ラベル)case 1: のように case と値の間にスペースが必要(case1: はコンパイルエラー)
一致したcaseで実行される処理1つのcaseに複数行書ける({}は不要)
breakswitchを抜けるないと次のcaseも続けて実行される(フォールスルー)
defaultどのcaseにも一致しないときの処理省略可能だけど、基本は書くのがおすすめ

switchの式で使える型

switch (式) の 式 は、結果が 整数型または文字型 になる必要があります。

使える例使えない例理由
int, char, short, long, enumdouble, float浮動小数点はswitchで扱えない

もし「小数で分岐したい」なら、if文を使うか、整数に変換してからswitchするのが定番です。

caseラベルのルール(コンパイルエラーになりやすいところ)

caseの右側は 定数式 である必要があります。つまり、基本は「固定の値」です。

OK例NG例なぜNG?
case 1:case x:xが変数だと定数ではない
case 'a':case 1.5:浮動小数点の定数は不可
case 10+2:case scanf(...):実行時に決まるものは不可

それと、地味だけど大事なのがスペース。
case 1: はOK、case1: はアウトです。

breakがないとどうなる?(フォールスルー)

switch文の超重要ポイントがこれです。
breakを書かないと、次のcaseもそのまま実行されます。

フォールスルーのイメージ図

基本的には「意図的にやるとき以外は、breakを必ず書く」でOKです。
慣れないうちは breakを書き忘れて「なんかいっぱい表示される…」ってなりがちです。

サンプルプログラム

元の例は a,b,c で果物名でしたね。
ここでは別の分かりやすい例として、数字でメニューを選ぶプログラムに変えます。

仕様

  • 数字を入力してメニューを選ぶ
  • 1:開始します
  • 2:設定を開きます
  • 3:終了します
  • それ以外:不明な選択です

ファイル名:8_8_1.c

// switch文を使ってメニュー選択の結果を表示するプログラム
#include <stdio.h>

int main(void)
{
    int menu;

    printf("メニュー番号を入力してください(1:開始 2:設定 3:終了)> ");
    scanf("%d", &menu);

    switch (menu) {
    case 1:
        printf("開始します。\n");
        break;
    case 2:
        printf("設定を開きます。\n");
        break;
    case 3:
        printf("終了します。\n");
        break;
    default:
        printf("不明な選択です。もう一度入力してください。\n");
        break;
    }

    return 0;
}

実行のイメージ

メニュー番号を入力してください(1:開始 2:設定 3:終了)> 2
設定を開きます。

メニュー番号を入力してください(1:開始 2:設定 3:終了)> 9
不明な選択です。もう一度入力してください。

switchを使うと読みやすい理由(ifとの比較)

同じことはifでも書けますが、選択肢が増えるほどswitchの方がスッキリします。

特徴の比較

観点if~else if~else~switch
得意範囲判定、複雑な条件、複数条件の組み合わせ値の一致で分岐(選択肢の列挙)
見た目条件が長くなりがちcaseが並んで一覧性が高い
注意点条件の順番が重要な場合があるbreak忘れに注意

scanfで文字を読むときの空白(参考)

元の例にあった scanf(" %c", &ch) の先頭スペースは、改行などの空白を読み飛ばすためでした。
今回のサンプルは int を読むのでそこまで気にしなくてOKですが、もし char を読むswitchを作るなら覚えておくと便利です。

  • %c は空白も拾う(Enterの改行も拾う)
  • だから " %c" のように先頭にスペースを入れて、空白を読み飛ばす

この癖を知ってると「え、入力してないのに勝手に分岐した!」みたいな事故が減ります。

図で理解するswitchの流れ

最後に、switchの流れを図っぽくまとめます。