C言語のきほん|switch文の注意点

switchは便利だけど、油断すると落とし穴。使えない条件・書き方のコツ・break事故をまとめて回避しよう。

switch文は、値の選択肢を並べて分岐できるので、とても読みやすくなります。
ただし、万能ではありません。使える型が決まっていたり、複雑な条件には向かなかったり、breakを書き忘れると想定外の動きになったりします。

ここでは、switch文でつまずきやすいポイントを、実例と一緒にやさしく整理していきます。
「switchで書けると思ったのに書けなかった」
「なぜか同じ表示が2回出た」
みたいな“あるある”を、ここでまとめて回避しちゃいましょう。

switch文を使えない場合

式やcaseが整数型以外のとき

switch (式) の 式 と、caseの値(定数式)は、基本的に 整数型または文字型 でなければいけません。

switchで扱えるswitchで扱えない補足
int / char / enum などdouble / float / 文字列小数や文字列で分岐したいならifを使う

たとえば、小数で分岐したいのに switch (3.14) みたいに書くのはできません。
小数が必要な場面は、ifで範囲判定するほうが自然です。

複雑な条件(範囲や論理式)を使いたいとき

switchは「一致」で分岐します。
なので、こういう判定はできません。

  • x が 0 より大きく 10 未満
  • x が 0 以上 100 以下
  • x が A かつ B

これは if の得意分野です。

やりたいこと向いている構文
値がこれなら…と列挙switch
範囲判定、大小比較、論理式if

記述上の注意1:複数のcaseを一度に書けない

よくやりたくなるのがこれです。

  • case 1, 2, 3: みたいにまとめたい

でもC言語のswitchではこの書き方はできません。
複数の値で同じ処理にしたい場合は、caseを縦に並べます。

正しい書き方(caseを並べる)

switch (value) {
case 1:
case 2:
case 3:
    /* 1,2,3のとき同じ処理 */
    break;
default:
    break;
}

ここで大事なのは、case 1: のあとに break を置かないこと。
break を置くと、case 2 と case 3 が同じ処理に合流できなくなります。

合流のイメージ

case 1:
case 2:
case 3:
  ↓ 同じ場所に合流
同じ処理
  ↓
breakで抜ける

記述上の注意2:caseの順番は自由。でも読みやすさは意識しよう

switchのcaseは、昇順や降順に並べる必要はありません。順不同でOKです。

ただ、読んだ人が探しやすいように、ふつうは昇順・降順で揃えるのがおすすめです。

順番動作可読性
バラバラ問題なく動く探しにくくなりがち
昇順/降順問題なく動くぱっと見で分かりやすい

breakの注意:書き忘れると次のcaseも実行される

switchで一番多い事故が break の書き忘れです。
break がないと、条件に一致したcaseの処理をしたあと、次のcaseへそのまま落ちていきます(フォールスルー)。

フォールスルーの流れ

式がcase 2に一致
   ↓
case 2 の文を実行
   ↓ breakが無い
case 3 の文も実行
   ↓
defaultも実行してしまうことがある

意図してフォールスルーを使うテクニックもありますが、学習段階ではまず「breakは基本、毎回書く」で大丈夫です。

サンプルプログラム

曜日番号を入力して、平日か休日かを表示するプログラム例です。

  • 1〜5:平日
  • 6,7:休日
  • それ以外:入力エラー

複数caseのまとめ書きが気持ちよく使える例です。

ファイル名:8_9_1.c

// switch文の注意点(複数caseのまとめ方)を確認するプログラム
#include <stdio.h>

int main(void)
{
    int day;

    printf("曜日番号を入力してください(1:月 2:火 3:水 4:木 5:金 6:土 7:日)> ");
    scanf("%d", &day);

    switch (day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        printf("平日です。がんばろう。\n");
        break;

    case 6:
    case 7:
        printf("休日です。ゆっくり休もう。\n");
        break;

    default:
        printf("入力エラー:1~7の番号で入力してください。\n");
        break;
    }

    return 0;
}

実行イメージ

曜日番号を入力してください(1:月 2:火 3:水 4:木 5:金 6:土 7:日)> 6
休日です。ゆっくり休もう。

曜日番号を入力してください(1:月 2:火 3:水 4:木 5:金 6:土 7:日)> 9
入力エラー:1~7の番号で入力してください。

実践問題

時間帯を表す番号を入力し、switch文を使ってあいさつを表示してください。

  • 1:おはようございます
  • 2:こんにちは
  • 3:こんばんは
  • それ以外:正しい番号を入力してください

実行例1(有効)

時間帯を入力してください(1:朝 2:昼 3:夜)> 2
こんにちは。

実行例2(無効)

時間帯を入力してください(1:朝 2:昼 3:夜)> 0
正しい番号を入力してください。

解答例

// switch文を使って時間帯に応じたあいさつを表示するプログラム
#include <stdio.h>

int main(void)
{
    int t;

    printf("時間帯を入力してください(1:朝 2:昼 3:夜)> ");
    scanf("%d", &t);

    switch (t) {
    case 1:
        printf("おはようございます。\n");
        break;
    case 2:
        printf("こんにちは。\n");
        break;
    case 3:
        printf("こんばんは。\n");
        break;
    default:
        printf("正しい番号を入力してください。\n");
        break;
    }

    return 0;
}

解説:switchが向いている条件・向いていない条件を見分けよう

この問題がswitch向きなのは、条件が「1か2か3か」のように 具体的な値の一致だからです。
もし「1〜3の範囲ならOK」のような範囲判定や、「0以上なら…」みたいな条件になるなら、ifのほうが自然になります。

確認問題:switch文の確認(○×)

次の文が正しければ○、間違っていれば×。

  1. switch文の式にはdouble型の値を使える
  2. caseラベルには変数を指定できる
  3. case 1, 2, 3: のようにカンマ区切りで複数指定できる
  4. 複数のcaseで同じ処理をしたい場合、caseを連続して並べて書ける
  5. switch文ではbreakを省略すると次のcaseも実行される
  6. defaultを省略するとコンパイルエラーになる
  7. caseの順番は昇順で書かないと動作が変わる
  8. switch文は範囲判定(例:xが1以上10以下)には向かない
  9. 1つのcaseに複数行の文を書けるが、必ず{}で囲む必要がある
  10. defaultはどのcaseにも一致しない場合の処理を書く場所で、書くのが推奨される

解答と解説

  1. ×:switchの式は整数型や文字型が基本です。doubleやfloatは使えません。
  2. ×:caseの右側は定数式である必要があります。変数は使えません。
  3. ×:case 1, 2, 3: のような書き方はできません。caseを並べます。
  4. ○:case 1: case 2: case 3: のように並べて同じ処理に合流できます。
  5. ○:breakがないとフォールスルーして次のcaseも実行されます。
  6. ×:defaultは省略してもコンパイルエラーにはなりません。
  7. ×:caseの順番は自由です。動作は変わりません(可読性のため整列がおすすめ)。
  8. ○:範囲や論理式の条件はifの得意分野です。switchは一致で分岐します。
  9. ×:1つのcaseに複数行書けますが、{}で囲む必要はありません(書いてもOKですが必須ではありません)。
  10. ○:defaultがあると想定外の入力にも対応でき、意図が明確になります。