
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文の確認(○×)
次の文が正しければ○、間違っていれば×。
- switch文の式にはdouble型の値を使える
- caseラベルには変数を指定できる
- case 1, 2, 3: のようにカンマ区切りで複数指定できる
- 複数のcaseで同じ処理をしたい場合、caseを連続して並べて書ける
- switch文ではbreakを省略すると次のcaseも実行される
- defaultを省略するとコンパイルエラーになる
- caseの順番は昇順で書かないと動作が変わる
- switch文は範囲判定(例:xが1以上10以下)には向かない
- 1つのcaseに複数行の文を書けるが、必ず{}で囲む必要がある
- defaultはどのcaseにも一致しない場合の処理を書く場所で、書くのが推奨される
解答と解説
- ×:switchの式は整数型や文字型が基本です。doubleやfloatは使えません。
- ×:caseの右側は定数式である必要があります。変数は使えません。
- ×:case 1, 2, 3: のような書き方はできません。caseを並べます。
- ○:case 1: case 2: case 3: のように並べて同じ処理に合流できます。
- ○:breakがないとフォールスルーして次のcaseも実行されます。
- ×:defaultは省略してもコンパイルエラーにはなりません。
- ×:caseの順番は自由です。動作は変わりません(可読性のため整列がおすすめ)。
- ○:範囲や論理式の条件はifの得意分野です。switchは一致で分岐します。
- ×:1つのcaseに複数行書けますが、{}で囲む必要はありません(書いてもOKですが必須ではありません)。
- ○:defaultがあると想定外の入力にも対応でき、意図が明確になります。
