【2026年7月最新】C言語のswitch-case文完全ガイド|基本構文・defaultの使い方・enumとの組み合わせをコード例付きで解説
C言語を学習していると、必ずといっていいほど登場するのがswitch-case文です。複数の条件によって処理を分岐させる際に、if-else文の代わりとして使われる構文ですが、「なんとなく書けるけど、本当に理解できているか自信がない」という方も多いのではないでしょうか。
本記事では、C言語のswitch-case文について、基本構文から応用テクニックまでを実践的なコード例とともに丁寧に解説します。初心者の方でも理解できるよう、if-elseとの比較や具体的なユースケースを交えながら説明しますので、ぜひ最後まで読んでください。
特に、breakを書き忘れた場合のfall-through動作や、enumと組み合わせた実践的な使い方は、現場のエンジニアでも誤解しやすいポイントです。この記事を読めば、switch-case文にまつわる疑問をすべて解消できます。
この記事で学べることを以下にまとめます。
- ✓switch-case文の基本構文と動作の仕組みを理解できる
- ✓default句やbreak文の正しい使い方と役割がわかる
- ✓fall-through(フォールスルー)の動作原理と活用法・注意点を習得できる
- ✓複数caseをまとめる書き方でコードを簡潔にできる
- ✓enumとswitch-caseを組み合わせた実践的な実装パターンを覚えられる
- ✓if-elseとswitch-caseの使い分け基準を身につけられる
switch-case文とは|if-elseとの比較で理解する
switch-case文は、一つの変数や式の値によって処理を複数の分岐に振り分けるための制御構文です。英語で言えば「スイッチ(切り替え)」という名前が示すとおり、値に応じて処理を切り替えるイメージです。
たとえば、ユーザーが入力した数値によってメニュー画面の処理を切り替えたい場合、if-elseを使うと次のようになります。
/* if-else を使った場合 */
if (menu == 1) {
printf("新規作成\n");
} else if (menu == 2) {
printf("ファイルを開く\n");
} else if (menu == 3) {
printf("上書き保存\n");
} else if (menu == 4) {
printf("終了\n");
} else {
printf("無効な選択です\n");
}
同じ処理をswitch-case文で書き直すと、以下のようにすっきりします。
/* switch-case を使った場合 */
switch (menu) {
case 1:
printf("新規作成\n");
break;
case 2:
printf("ファイルを開く\n");
break;
case 3:
printf("上書き保存\n");
break;
case 4:
printf("終了\n");
break;
default:
printf("無効な選択です\n");
break;
}
if-else版と比較すると、switch-case版のほうが構造が一目でわかりやすいことがわかります。特に分岐の数が多くなればなるほど、switch-caseの可読性の優位性が際立ってきます。
ただし、switch-case文にはいくつかの制約があります。最も重要な制約は、比較できるのは整数型(int、char、enum等)の値のみという点です。float型の変数や文字列(char配列)を直接switchの条件式に使うことはできません。この制約を知らずに使おうとしてコンパイルエラーが出る初心者は非常に多いので、最初に把握しておくことが大切です。
また、caseに指定できる値は定数式(コンパイル時に値が決まるもの)に限られます。変数をcaseラベルに使うことはできません。この点もif-elseとの大きな違いの一つです。
📖 用語解説: switch文
C言語において、一つの式の値を複数のcase定数と照合し、一致したcaseラベルから処理を実行する制御構文。整数型・文字型・enum型の値に対して使用でき、多分岐処理をif-elseより読みやすく記述できる。
switch-case文の基本構文と書き方|サイコロ判定で学ぶ
switch-case文の基本的な構文を改めて確認しましょう。構文の形式は以下のとおりです。
switch (式) {
case 定数1:
/* 式の値が定数1と一致したときの処理 */
break;
case 定数2:
/* 式の値が定数2と一致したときの処理 */
break;
/* ... 必要な数だけcaseを追加 ... */
default:
/* どのcaseにも一致しなかったときの処理 */
break;
}
構文の各パーツについて説明します。
- switch ( 式 ):括弧の中に条件判定の元となる変数や式を書きます。この式の値によって、どのcaseラベルに飛ぶかが決まります。
- case 定数::コロン(:)で終わるラベルです。switchの式が定数と一致したとき、このラベル以降の処理が実行されます。
- break;:switch文のブロックを抜け出します。これを書かないと、次のcaseの処理も続けて実行されます(fall-through)。
- default::どのcaseにも一致しなかった場合の処理を書きます。省略可能ですが、書いておくことが推奨されます。
実際にサイコロ(1〜6の目)の判定を例にして、基本的なswitch-case文を書いてみましょう。
#include <stdio.h>
int main(void) {
int dice = 3; /* サイコロの目(1〜6) */
switch (dice) {
case 1:
printf("サイコロの目は1です。最小値!\n");
break;
case 2:
printf("サイコロの目は2です。\n");
break;
case 3:
printf("サイコロの目は3です。\n");
break;
case 4:
printf("サイコロの目は4です。\n");
break;
case 5:
printf("サイコロの目は5です。\n");
break;
case 6:
printf("サイコロの目は6です。最大値!\n");
break;
default:
printf("不正な値です(1〜6以外)。\n");
break;
}
return 0;
}
/* 出力: サイコロの目は3です。 */
このプログラムを実行すると、変数diceの値が3なので、case 3:にマッチして「サイコロの目は3です。」と表示されます。その後break;でswitch文全体を抜けて、return 0;に進みます。
switch文の動作を図解すると、プログラムが上からcase定数を順番に照合していき、一致したラベルにジャンプして処理を実行するイメージです。一致するcaseが見つからない場合はdefaultにジャンプします。
注意点として、caseラベルの順番は実行結果に影響しません。case 3をcase 1より前に書いても動作は同じです。ただし、可読性のために昇順や意味のある順番で並べることが慣習となっています。
💡 caseの後に複数の処理を書く
一つのcaseブロックには複数の文を書くことができます。波括弧{}で囲む必要はなく、breakまでの処理がすべて実行されます。複雑な処理を行う場合は関数に切り出すと可読性が上がります。
default句の正しい使い方|省略時のリスクと設計指針
switch-case文のdefault:句は、どのcaseにも一致しなかった場合に実行されるブロックです。構文上は省略可能ですが、実務では必ず書くことが強く推奨されています。その理由を詳しく見ていきましょう。
defaultを省略すると、想定外の値が入力されたとき、switch文全体が何もせずにスキップされます。デバッグ中はこの「無音の失敗」が非常に発見しにくいバグにつながります。たとえば、次のようなケースを考えてみてください。
#include <stdio.h>
int main(void) {
int score = 95; /* テストの点数 */
char grade;
/* defaultなしのswitch-case(危険な例) */
switch (score / 10) {
case 10:
case 9:
grade = 'A';
break;
case 8:
grade = 'B';
break;
case 7:
grade = 'C';
break;
case 6:
grade = 'D';
break;
/* 60点未満(case 0〜5)のcaseがない! */
/* defaultもない! */
}
/* gradeが初期化されていない可能性がある */
printf("成績: %c\n", grade); /* 未定義動作の危険 */
return 0;
}
上のコードでは、60点未満のscoreが来た場合にgradeが初期化されないまま使われる可能性があります。これは未定義動作(Undefined Behavior)を引き起こす危険なコードです。defaultを追加するだけで、このリスクを簡単に排除できます。
#include <stdio.h>
int main(void) {
int score = 45; /* テストの点数 */
char grade;
/* defaultありのswitch-case(正しい例) */
switch (score / 10) {
case 10:
case 9:
grade = 'A';
break;
case 8:
grade = 'B';
break;
case 7:
grade = 'C';
break;
case 6:
grade = 'D';
break;
default:
/* 60点未満、または想定外の値 */
grade = 'F';
break;
}
printf("成績: %c\n", grade); /* 出力: 成績: F */
return 0;
}
defaultを追加することで、60点未満のscoreが来ても確実にgrade = 'F'が代入されます。プログラムの動作が予測可能になり、デバッグも格段に楽になります。
また、defaultの位置については、最後に書くのが慣習ですが、C言語の文法上はどこに書いてもかまいません。先頭や中間に書いても動作しますが、可読性のために最後に書くのが一般的です。ただし、defaultにもbreakを書く習慣をつけておきましょう。将来的にcaseを追加したときにfall-throughが起きるリスクを防ぐためです。
組み込みソフトウェアや安全性が求められるシステムでは、MISRA-Cなどのコーディング規約でdefault句の記述が必須とされていることが多いです。習慣として必ず書くようにしましょう。
📖 用語解説: default句
switch文において、どのcase定数とも一致しなかった場合に実行される特別なラベル。省略可能だが、想定外の値への安全な対処のために必ず記述することが推奨される。MISRA-Cなどの安全性重視の規約では必須項目とされる。
breakとfall-throughを理解する|バグの温床を正しく把握する
switch-case文を正確に使いこなすうえで、最も重要かつ誤解が多いのがbreakとfall-through(フォールスルー)の関係です。C言語のswitch文は、caseにジャンプした後、breakに出会うまで次のcaseの処理も続けて実行してしまうという特性があります。
これを「フォールスルー(fall-through)」と呼びます。滝から水が流れ落ちるように、下のcaseへと処理が「流れ落ちる」イメージです。意図せずfall-throughが起きると、予想外の処理が実行される深刻なバグになります。
#include <stdio.h>
int main(void) {
int x = 2;
/* breakを忘れた危険な例 */
switch (x) {
case 1:
printf("case 1の処理\n");
/* breakがない! → fall-through */
case 2:
printf("case 2の処理\n");
/* breakがない! → fall-through */
case 3:
printf("case 3の処理\n");
/* breakがない! → fall-through */
case 4:
printf("case 4の処理\n");
break; /* ここで止まる */
default:
printf("defaultの処理\n");
break;
}
return 0;
}
/* 出力:
case 2の処理
case 3の処理
case 4の処理
*/
x=2なのに、case 2、case 3、case 4の処理がすべて実行されています。これがfall-throughです。breakを書き忘れると、複数のcaseブロックが連鎖して実行されてしまうことを必ず理解しておいてください。
⚠️ breakの書き忘れは重大バグの原因
switch-case文でbreakを忘れると、次のcaseの処理がそのまま実行されてしまいます(fall-through)。コンパイラはこの間違いを警告しないことが多く、実行時まで気づきにくい厄介なバグです。各caseの末尾には必ずbreakを書く習慣をつけましょう。
一方で、fall-throughを意図的に活用する場面もあります。複数のcaseに同じ処理をさせたいときに、breakなしで連続させる書き方は正規の使い方です(次のH2で詳しく解説します)。意図的にfall-throughを使う場合は、コメントで明示することが重要です。
#include <stdio.h>
int main(void) {
int month = 4; /* 4月 */
int days;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28; /* うるう年は考慮しない簡略版 */
break;
default:
days = -1; /* 無効な月 */
break;
}
if (days > 0) {
printf("%d月は%d日あります。\n", month, days);
} else {
printf("無効な月です。\n");
}
return 0;
}
/* 出力: 4月は30日あります。 */
このように、複数のcase定数に対して同じ処理をさせる場合は、意図的なfall-throughとして空のcaseラベルを連続させます。この書き方はC言語では正規の書き方であり、非常によく使われます。
📖 用語解説: fall-through(フォールスルー)
switch-case文においてbreakを書かなかった場合に、一致したcaseの処理が終わっても次のcaseの処理が続けて実行される動作のこと。意図しないfall-throughは深刻なバグの原因になるが、複数caseに同一処理をさせる場合には意図的に活用することもある。
📖 用語解説: break文
switch文やループ(for/while/do-while)を即座に抜け出すための文。switch文のcase内でbreakを使うと、それ以降のcaseへのfall-throughを防ぎ、switch文全体の直後にある文に制御を移す。
複数条件をまとめる書き方|case A: case B: の活用パターン
前のセクションで少し触れましたが、複数のcaseに対して同じ処理を実行させたい場合の書き方を詳しく解説します。これはswitch-case文の非常に実用的なテクニックで、コードの重複を減らすために広く使われています。
基本的な考え方は、処理を書かない(空の)caseラベルを連続させることで、fall-throughを利用して複数の条件を一つの処理ブロックに結びつけるというものです。
#include <stdio.h>
int main(void) {
int day = 6; /* 1=月曜日, 2=火曜日, ..., 7=日曜日 */
char *day_type;
switch (day) {
case 1: /* 月曜日 */
case 2: /* 火曜日 */
case 3: /* 水曜日 */
case 4: /* 木曜日 */
case 5: /* 金曜日 */
day_type = "平日";
break;
case 6: /* 土曜日 */
case 7: /* 日曜日 */
day_type = "休日";
break;
default:
day_type = "無効な値";
break;
}
printf("day=%d は %s です。\n", day, day_type);
return 0;
}
/* 出力: day=6 は 休日 です。 */
day=6(土曜日)の場合、case 6:にジャンプします。case 6にはコードが書かれていないため、fall-throughが発生してcase 7:以降の処理、つまりday_type = "休日";が実行されます。その後breakでswitch文を抜けます。
この書き方のポイントは、「処理を伴わないcase」はコメントで内容を明示することです。case 6: の後に何もコードがないのは意図的なfall-throughであることを示しています。コメントを省くと、breakを書き忘れたのか意図的なのか読み手にわかりにくくなります。
別の実用例として、英小文字・大文字・数字の判定を見てみましょう。
#include <stdio.h>
int main(void) {
char c = 'A';
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'A': case 'E': case 'I': case 'O': case 'U':
printf("'%c' は母音(英字)です。\n", c);
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
printf("'%c' は数字です。\n", c);
break;
default:
printf("'%c' は子音か、その他の文字です。\n", c);
break;
}
return 0;
}
/* 出力: 'A' は母音(英字)です。 */
このように、複数のcaseを一行に横並びで書くスタイルもあります。縦に並べるか横に並べるかはコーディングスタイルの問題ですが、「同じカテゴリに属するcase群」を意味的に表現するために、横並びにする書き方もよく見られます。
ただし、caseを横並びにしすぎると1行が長くなりすぎて読みにくくなることもあります。チームのコーディング規約に従いつつ、意図が明確に伝わる書き方を選択してください。
enumとswitch-caseの組み合わせ|曜日判定で学ぶ実践パターン
C言語のswitch-case文をより実践的に使うための重要テクニックが、enum(列挙型)との組み合わせです。enumを使うと、マジックナンバー(意味のない数値リテラル)をなくし、コードの意図を明確に表現できます。
まず、enumを使わない場合の問題点を見てみましょう。
/* enumを使わない場合:マジックナンバーだらけで読みにくい */
int day = 3;
switch (day) {
case 0: printf("Sunday\n"); break;
case 1: printf("Monday\n"); break;
case 2: printf("Tuesday\n"); break;
case 3: printf("Wednesday\n"); break;
case 4: printf("Thursday\n"); break;
case 5: printf("Friday\n"); break;
case 6: printf("Saturday\n"); break;
}
/* day=3 が何曜日を意味するのか、定義を見ないとわからない */
次に、enumと組み合わせた場合を見てみましょう。
#include <stdio.h>
/* 曜日を表すenumを定義 */
typedef enum {
SUNDAY = 0,
MONDAY = 1,
TUESDAY = 2,
WEDNESDAY = 3,
THURSDAY = 4,
FRIDAY = 5,
SATURDAY = 6
} DayOfWeek;
/* 曜日に応じたメッセージを返す関数 */
void print_day_info(DayOfWeek day) {
switch (day) {
case SUNDAY:
printf("日曜日:週の始まり、ゆっくり休みましょう。\n");
break;
case MONDAY:
printf("月曜日:週のスタート、頑張りましょう!\n");
break;
case TUESDAY:
printf("火曜日:週の序盤、ペース配分が大切です。\n");
break;
case WEDNESDAY:
printf("水曜日:週の中日、折り返し地点です。\n");
break;
case THURSDAY:
printf("木曜日:週末が見えてきました。\n");
break;
case FRIDAY:
printf("金曜日:週の最終日、もうひと踏ん張り!\n");
break;
case SATURDAY:
printf("土曜日:週末!思い切り楽しみましょう。\n");
break;
default:
printf("無効な曜日値です。\n");
break;
}
}
int main(void) {
DayOfWeek today = WEDNESDAY;
print_day_info(today); /* 出力: 水曜日:週の中日、折り返し地点です。 */
return 0;
}
enumを使うことで、case 3:という意味のわからない数字の代わりに、case WEDNESDAY:という意味のわかるラベルが使えるようになりました。これにより、コードを読む人が「3が何を意味するか」を別途確認する必要がなくなります。
さらに、enumとswitch-caseを組み合わせると、コンパイラが「すべてのenumの値がcaseに含まれているか」を警告できるという大きなメリットがあります(GCCなら-Wswitchオプション、またはデフォルトで警告が出ます)。enumに新しい値を追加したとき、対応するcaseを書き忘れても警告で気づけるのです。
enumとswitch-caseを組み合わせるパターンは、状態機械(ステートマシン)の実装でも非常によく使われます。組み込みソフトウェアやゲームのキャラクターAIなど、「現在の状態によって動作を切り替える」処理に最適です。
#include <stdio.h>
/* ゲームキャラクターの状態 */
typedef enum {
STATE_IDLE, /* 待機中 */
STATE_WALKING, /* 歩行中 */
STATE_JUMPING, /* ジャンプ中 */
STATE_ATTACKING /* 攻撃中 */
} CharacterState;
void update_character(CharacterState state) {
switch (state) {
case STATE_IDLE:
printf("キャラクター: 待機アニメーション再生中\n");
break;
case STATE_WALKING:
printf("キャラクター: 歩行アニメーション再生中、移動処理実行\n");
break;
case STATE_JUMPING:
printf("キャラクター: ジャンプアニメーション再生中、重力計算実行\n");
break;
case STATE_ATTACKING:
printf("キャラクター: 攻撃アニメーション再生中、当たり判定チェック\n");
break;
default:
printf("未知の状態です\n");
break;
}
}
int main(void) {
update_character(STATE_JUMPING);
/* 出力: キャラクター: ジャンプアニメーション再生中、重力計算実行 */
return 0;
}
📖 用語解説: enum(列挙型)
C言語で整数定数に名前をつけて管理するためのデータ型。`typedef enum { ... } 型名;` で定義し、コード内でマジックナンバーを排除して可読性を高める。switch-caseと組み合わせることで、すべての列挙値に対する処理の網羅性をコンパイラがチェックできる。
ループ内でのswitch-caseの挙動|breakとcontinueの違いを理解する
switch-case文をfor文やwhile文などのループの中で使う場合、breakの動作に注意が必要です。この点を誤解している初心者が非常に多いため、しっかりと理解しておきましょう。
ループ内のswitch文でbreakを実行すると、switch文を抜けるだけで、ループは抜けません。この動作を知らないと、「ループを終了させたくてbreakを書いたのに終わらない」という状況に陥ります。
#include <stdio.h>
int main(void) {
int i;
/* ループ内のswitch-case */
for (i = 1; i <= 5; i++) {
printf("i = %d: ", i);
switch (i) {
case 1:
printf("1番!\n");
break; /* switchを抜けるだけ。forループは継続する */
case 3:
printf("3番!\n");
break; /* switchを抜けるだけ。forループは継続する */
case 5:
printf("5番!\n");
break; /* switchを抜けるだけ。forループは継続する */
default:
printf("(その他)\n");
break;
}
/* switch後もforループは i=1,2,3,4,5 と続く */
}
return 0;
}
/* 出力:
i = 1: 1番!
i = 2: (その他)
i = 3: 3番!
i = 4: (その他)
i = 5: 5番!
*/
i=1のときcase 1でbreakが実行されますが、これはswitch文を抜けるだけです。forループは継続して i=2, 3, 4, 5 と処理が続きます。これは意図した動作です。
では、ループ自体を途中で抜けたい場合はどうすればいいでしょうか。方法は主に3つあります。
#include <stdio.h>
int main(void) {
int i;
int found = 0; /* フラグ変数 */
/* 方法1: フラグ変数を使ってループを抜ける */
for (i = 1; i <= 10; i++) {
switch (i % 3) {
case 0:
printf("i=%d: 3の倍数を発見!ループ終了\n", i);
found = 1;
break; /* switchを抜ける */
default:
printf("i=%d: 3の倍数ではない\n", i);
break;
}
if (found) break; /* forループを抜ける */
}
printf("\n--- 方法2: goto文を使う(限定的な使用) ---\n");
/* 方法2: goto文を使ってループを抜ける */
for (i = 1; i <= 10; i++) {
switch (i % 4) {
case 0:
printf("i=%d: 4の倍数を発見!ループ終了\n", i);
goto loop_end; /* ループ外のラベルにジャンプ */
default:
printf("i=%d: 4の倍数ではない\n", i);
break;
}
}
loop_end:
printf("ループ終了\n");
return 0;
}
⚠️ ループ内のbreakはswitchしか抜けない
switch文内でbreakを実行しても、外側のfor/while/do-whileループは継続します。ループを強制終了したい場合は、フラグ変数を使ってループの条件判定でbreakするか、goto文(慎重に)を使う必要があります。この挙動を誤解すると無限ループなどのバグにつながります。
また、continue文はswitch文の内側では特別な意味を持ちません。switch内でcontinueを書くと、switch文ではなく外側のループのcontinueとして動作します。これはbreakとは逆の動作で、「continueはswitchを飛び越えてループの次の反復に進む」という点を覚えておきましょう。
#include <stdio.h>
int main(void) {
int i;
/* switch内のcontinueはforループに作用する */
for (i = 1; i <= 5; i++) {
switch (i) {
case 3:
printf("i=3はスキップ\n");
continue; /* forループの次の反復へ(i=4へ) */
default:
printf("i=%d: 通常処理\n", i);
break;
}
printf(" i=%dの後処理\n", i); /* i=3のときはここに来ない */
}
return 0;
}
/* 出力:
i=1: 通常処理
i=1の後処理
i=2: 通常処理
i=2の後処理
i=3はスキップ ← continueでforループの次の反復へ
i=4: 通常処理
i=4の後処理
i=5: 通常処理
i=5の後処理
*/
📖 用語解説: 条件分岐
プログラムの実行において、条件の真偽や値によって実行する処理を切り替える制御構造の総称。C言語ではif/else、switch-case、三項演算子(? :)が代表的な条件分岐の手段。switch-caseは整数値による多分岐に特化し、if-elseより高速になる場合がある。
if-else vs switch-case 使い分けガイド|判断基準を整理する
C言語における条件分岐の二大手段であるif-else文とswitch-case文は、それぞれ得意な場面が異なります。適切に使い分けることで、コードの可読性とパフォーマンスを最大化できます。
まず、それぞれの特性を整理しましょう。
switch-caseが適している場面
- 整数・文字・enumの定数値による分岐:一つの変数を複数の定数値と比較する場合
- 分岐の数が多い(3つ以上):分岐が増えるほどswitch-caseの可読性が際立つ
- メニュー処理・コマンド解析:ユーザー入力やコマンドコードによる動作切り替え
- 状態機械(ステートマシン):enum値に基づく状態遷移処理
- パフォーマンス重視:コンパイラがジャンプテーブルに最適化できる場合がある
if-elseが適している場面
- 範囲比較(>、<、>=、<=):switch-caseでは範囲条件を直接書けない
- 浮動小数点(float・double)の比較:switch-caseは整数型のみ
- 文字列(char配列)の比較:switch-caseは文字列を直接扱えない
- 複合条件(&&、||):複数変数を組み合わせた条件はif-elseが適切
- 分岐が2〜3つで条件が単純:この規模ならif-elseで十分読みやすい
実際のコードで判断基準を確認してみましょう。
#include <stdio.h>
int main(void) {
int score = 75;
/* ---- if-elseが適切な例: 範囲比較 ---- */
if (score >= 90) {
printf("評価A: 優秀\n");
} else if (score >= 70) {
printf("評価B: 良好\n");
} else if (score >= 50) {
printf("評価C: 可\n");
} else {
printf("評価D: 不可\n");
}
/* scoreの範囲比較 → if-elseが自然 */
/* ---- switch-caseが適切な例: 定数値との比較 ---- */
int command = 2; /* ユーザーが入力したコマンド番号 */
switch (command) {
case 1: printf("コマンド1: リスト表示\n"); break;
case 2: printf("コマンド2: 検索\n"); break;
case 3: printf("コマンド3: 追加\n"); break;
case 4: printf("コマンド4: 削除\n"); break;
case 0: printf("コマンド0: 終了\n"); break;
default: printf("不明なコマンド\n"); break;
}
/* 定数コード値との比較 → switch-caseが自然 */
return 0;
}
コンパイラの最適化という観点では、switch-caseはコンパイラがジャンプテーブルやバイナリサーチに変換できるため、if-elseよりも高速になる場合があります。特にcase値が連続した整数(0, 1, 2, 3...)の場合、ジャンプテーブルへの最適化が行われやすく、O(1)で目的のcaseに到達できます。
ただし、現代のコンパイラはif-elseも賢く最適化するため、パフォーマンスの差を気にするより可読性を優先するのが現実的な判断です。どちらを使うかは「コードの意図が自然に伝わるか」を基準に選びましょう。
💡 switch-caseとif-elseの混在
実際のコードでは、外側をswitch-caseで大分類して、各caseの中でif-elseを使って細かい条件を処理するパターンがよく使われます。両者を組み合わせることで、可読性と表現力を両立できます。
よくある質問(FAQ)
- C言語のswitch-case文でfloat型は使えますか?
switch-case文では、switchの条件式に使える型は整数型(int, char, short, long等)とenum型のみです。float型やdouble型の浮動小数点数は使用できません。浮動小数点数の条件分岐が必要な場合は、if-else文を使用してください。また、文字列(char配列)も直接switchの条件式には使えないため、strcmp()を使ったif-else文で比較する必要があります。
- switch-case文でbreakを書き忘れるとどうなりますか?
breakを書き忘れると「fall-through(フォールスルー)」が発生します。これは、一致したcaseの処理が終わった後も、次のcaseの処理が続けて実行される動作です。意図しないfall-throughは予期しない動作やバグの原因になります。各caseの末尾には必ずbreakを書く習慣をつけてください。ただし、複数のcaseに同一の処理をさせたい場合は、意図的にbreakなしのfall-throughを活用することもあります。
- switch-case文のdefaultは省略できますか?
C言語の文法上、default句は省略できます。しかし、実務では必ず記述することが強く推奨されています。defaultを省略すると、想定外の値が入力されたときに何も処理されずに無音でスキップされ、デバッグが困難なバグの原因になります。MISRA-Cなどのコーディングガイドラインではdefaultの記述を必須としています。安全なコードを書くために、常にdefaultを書く習慣をつけましょう。
- ループの中でswitch-caseを使うときの注意点は何ですか?
ループ(for/while/do-while)の中でswitch-case文を使う場合、switch内のbreakはswitchを抜けるだけで外側のループは継続されます。ループ自体を終了させたい場合は、フラグ変数を使ってループの条件でbreakするか、goto文を使う方法があります。またcontinue文はswitch文に影響せず、外側のループの次の反復に進みます。この点はbreakの動作と異なるため混乱しやすく、コメントで意図を明示することを推奨します。
- enumとswitch-caseを組み合わせるメリットは何ですか?
enumとswitch-caseを組み合わせることで、コードの可読性と安全性が大幅に向上します。主なメリットは3つです。第一に、マジックナンバー(意味不明な数値)を排除してコードの意図が明確になります。第二に、GCCなどのコンパイラが「enumのすべての値がcaseに含まれているか」を警告できるため、追加し忘れを防げます。第三に、状態機械(ステートマシン)などの複雑な状態遷移ロジックを直感的に記述できます。
Claude Codeで業務自動化を90日で叩き込む
経営者向けの伴走型パーソナルトレーニング
Claude Code を業務に落とし込む
専門研修コース一覧
受講者本人の業務を題材に、「使いこなせる」状態になるまで伴走する研修プログラム。1対1特化型・ハンズオン・法人講座の3コースを展開中。業務特化・実装まで踏み込むタイプのClaude Code研修です。
研修コース一覧を見る →AI鬼管理へのお問い合わせ
この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。




