【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文はC言語の条件分岐の要です。if-elseより読みやすくなる場面が多く、組み込み系やゲーム開発でも頻繁に登場します。この記事で基礎から応用まで一気にマスターしましょう!

この記事で学べることを以下にまとめます。

  • switch-case文の基本構文と動作の仕組みを理解できる
  • default句やbreak文の正しい使い方と役割がわかる
  • fall-through(フォールスルー)の動作原理と活用法・注意点を習得できる
  • 複数caseをまとめる書き方でコードを簡潔にできる
  • enumとswitch-caseを組み合わせた実践的な実装パターンを覚えられる
  • if-elseとswitch-caseの使い分け基準を身につけられる
📌 この記事の結論
【2026年7月最新】C言語のswitch-case文完全ガイド|基本構文・defaultの使い方・enumとの組み合わせをコード例付きで解説
C言語のswitch-case文の書き方を基本から応用まで完全解説。条件分岐の基本構文、default句の使い方、break・fall-throughの動作原理、enumを活用した文字列分岐、ループ内での挙動まで実践コード付き。

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文が使えるのは整数型だけなんですか?文字列で条件分岐したい場合はどうすればいいですか?
代表菅澤 代表菅澤
文字列を使いたい場合はif-elseとstrcmp()を組み合わせるのが基本です。または、文字列をenumや整数値に変換してからswitchに渡す方法もよく使われます。C言語のswitchは整数比較に特化した構文と覚えておきましょう。
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

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より前に書いても動作は同じです。ただし、可読性のために昇順や意味のある順番で並べることが慣習となっています。

代表菅澤 代表菅澤
サイコロ判定のような「値が明確に決まっている整数の多分岐」こそswitch-caseの真骨頂です。if-elseで同じことを書くと冗長になりがちなので、こういうケースでは積極的にswitch-caseを使いましょう。

💡 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は必ず最後に書かないといけないんですか?
代表菅澤 代表菅澤
文法上はどこでも書けますが、「最後に書く」のが強い慣習です。先頭に書いた場合も、一致するcaseがないときだけ実行されます。コードを読む人が混乱しないよう、特別な理由がない限り最後に置きましょう。

📖 用語解説: 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はバグになりやすい半面、うまく使えばコードを簡潔にできます。「意図的かどうか」をコメントや書き方で明確にすることが大切です。GCCなどの新しいコンパイラでは、意図的なfall-throughをコメント`/* fall through */`で示すと警告を抑制できます。

📖 用語解説: fall-through(フォールスルー)

switch-case文においてbreakを書かなかった場合に、一致したcaseの処理が終わっても次のcaseの処理が続けて実行される動作のこと。意図しないfall-throughは深刻なバグの原因になるが、複数caseに同一処理をさせる場合には意図的に活用することもある。

📖 用語解説: break文

switch文やループ(for/while/do-while)を即座に抜け出すための文。switch文のcase内でbreakを使うと、それ以降のcaseへのfall-throughを防ぎ、switch文全体の直後にある文に制御を移す。

Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

複数条件をまとめる書き方|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行が長くなりすぎて読みにくくなることもあります。チームのコーディング規約に従いつつ、意図が明確に伝わる書き方を選択してください。

代表菅澤 代表菅澤
case をたくさん横並びにするのと縦に並べるのはどちらが推奨ですか?
代表菅澤 代表菅澤
一般的には縦に並べるほうが多数派です。可読性が高く、コメントも付けやすいためです。ただし、母音のようにグルーピングが自明な場合は横並びも許容されます。チームやプロジェクトの規約に合わせましょう。

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(enum変数)
case ENUM_VAL:
処理実行
break
次の処理へ

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とswitch-caseの組み合わせは、C言語プログラミングの定番パターンの一つです。特に状態機械の実装では欠かせないテクニックなので、しっかりマスターしておきましょう。

📖 用語解説: 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の後処理
*/
代表菅澤 代表菅澤
switch内でcontinueを使うとforループに効くんですか。breakとcontinueで動作が違うのは初めて知りました。
代表菅澤 代表菅澤
そうです、これは重要なポイントです。breakはswitch文を抜けますが、continueはswitch文を「素通り」して外側のループに作用します。混乱しやすいので、コメントを付けて意図を明示することを強くおすすめします。

📖 用語解説: 条件分岐

プログラムの実行において、条件の真偽や値によって実行する処理を切り替える制御構造の総称。C言語ではif/else、switch-case、三項演算子(? :)が代表的な条件分岐の手段。switch-caseは整数値による多分岐に特化し、if-elseより高速になる場合がある。

Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

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で十分読みやすい
条件が整数/enum/文字の定数比較?
分岐が3つ以上?
switch-caseを選択
可読性・保守性UP

実際のコードで判断基準を確認してみましょう。

#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も賢く最適化するため、パフォーマンスの差を気にするより可読性を優先するのが現実的な判断です。どちらを使うかは「コードの意図が自然に伝わるか」を基準に選びましょう。

代表菅澤 代表菅澤
「整数の定数比較で3分岐以上ならswitch-case」という判断基準を頭に入れておくと、現場でほぼ迷わなくなります。範囲比較・文字列比較・複合条件はif-elseと覚えておけばOKです。

💡 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に含まれているか」を警告できるため、追加し忘れを防げます。第三に、状態機械(ステートマシン)などの複雑な状態遷移ロジックを直感的に記述できます。

AIAI鬼管理

AI鬼管理へのお問い合わせ

この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。

会社名を入力してください
業種を選択してください
お名前を入力してください
正しいメールアドレスを入力してください

1つ以上選択してください
1つ以上選択してください
月額コストを選択してください

約1時間のオンライン面談(Google Meet)です

空き枠を取得中...
面談日時を選択してください

予約確定後、Google Calendarの招待メールをお届けします。
しつこい営業は一切ございません。

監修 最終更新日: 2026年7月19日
菅澤孝平
菅澤 孝平 株式会社GENAI 代表取締役
  • AI業務自動化サービス「AI鬼管理」を運営 — Claude Code を活用し、経営者の業務を「AIエージェントに任せる仕組み」へ転換するパーソナルトレーニングを 伴走構築 で提供。日報・採用・問い合わせ対応・経費精算・議事録・データ集計・営業リスト等の定型業務を、AIに代行させる体制を経営者と一緒に作り込む
  • Claude Code 実装ノウハウを 経営者・法人クライアント に直接指導。生成AIを「便利ツール」ではなく 「業務を任せる存在」 として運用する手法を体系化
  • 「やらせ切る管理」メソッドの開発者。シンゲキ株式会社(2021年設立・鬼管理専門塾運営)にて累計3,000名以上の学習者を志望校合格に導いた管理メソッドを、AI × 経営者支援 に転用
  • 著書『3カ月で志望大学に合格できる鬼管理』(幻冬舎)、『親の過干渉こそ、最強の大学受験対策である。』(講談社)
  • メディア出演: REAL VALUE / カンニング竹山のイチバン研究所 / ええじゃないかBiz 他
  • 明治大学政治経済学部卒
現在は AI鬼管理(Claude Code活用の伴走型パーソナルトレーニング)を主事業とし、経営者と二人三脚で「AIに業務を任せる仕組み」を実装。「実行を強制する環境」を AI で構築する手法を、自社の実運用知見をもとに発信している。