The C Path — learn C, visually

🌱 C Basics

switch, case, default: the multi-way jump

⏱ 12 min · free interactive lesson · quizzes, visualizations & a real compiler

▶ Open the interactive lesson — free, no signup
Why you're learning this

In 1990, half of AT&T's long-distance phone network went silent for nine hours — engineers traced the collapse to one misplaced break in a C switch statement. This lesson hands you the clean tool for menus and multi-way choices, then walks you straight into, and safely back out of, the exact trap behind that outage.

When one value needs comparing against many fixed possibilities — a menu choice, a keypress, a day number — an else-if ladder works but reads like bureaucracy. C offers a dedicated construct built from four keywords: switch, case, default, and break.

menu.c
#include <stdio.h>

int main(void) {
    char op = '*';
    int a = 6, b = 7;

    switch (op) {
    case '+':
        printf("%d\n", a + b);
        break;
    case '-':
        printf("%d\n", a - b);
        break;
    case '*':
        printf("%d\n", a * b);
        break;
    default:
        printf("unknown operator '%c'\n", op);
        break;
    }
    return 0;
}
terminal
$ gcc menu.c -o menu && ./menu
42

How it flows: switch (expr) evaluates the expression once, jumps straight to the matching case label, and runs from there. break exits the switch; default catches anything unmatched (put one in — it's your safety net):

This spot has an interactive flow widget — open the interactive lesson to play with it.

🧠 Checkpoint: What is the job of default: in a switch?

  • It runs before every case
  • It handles any value no case label matched
  • It marks the fastest case
  • It is required by the compiler
Show answer

It handles any value no case label matched — default is the catch-all branch (and it may appear anywhere among the cases, though last is conventional). It’s optional — but omitting it means unmatched values silently do nothing.

The famous gotcha: fallthrough

Here's the part that surprises everyone: case labels are just labels, not walls. If you omit break, execution barrels straight into the next case:

fallthrough.c — one break missing
#include <stdio.h>

int main(void) {
    int level = 1;

    switch (level) {
    case 1:
        printf("Bronze perks\n");
        /* no break — falls through! */
    case 2:
        printf("Silver perks\n");
        break;
    case 3:
        printf("Gold perks\n");
        break;
    }
    return 0;
}
terminal
$ gcc fallthrough.c -o ft && ./ft
Bronze perks
Silver perks
# level is 1, yet the case-2 code ran too!
💀

A forgotten break is the #1 switch bug — the code compiles happily and quietly runs too many cases. GCC's -Wimplicit-fallthrough (included in -Wextra) warns you; in C23 you can mark intentional fallthrough with the [[fallthrough]] attribute so the warning stays useful.

But fallthrough isn't purely a trap — it's also a feature. Stacking case labels with no code between them is the idiomatic way to say "these values share a branch":

grouping.c — fallthrough used well
#include <stdio.h>

int main(void) {
    char c = 'E';

    switch (c) {
    case 'a': case 'e': case 'i': case 'o': case 'u':
    case 'A': case 'E': case 'I': case 'O': case 'U':
        printf("'%c' is a vowel\n", c);
        break;
    default:
        printf("'%c' is not a vowel\n", c);
        break;
    }
    return 0;
}

🧠 Checkpoint: In fallthrough.c, what would level = 3 print?

  • Gold perks
  • Bronze, Silver and Gold perks
  • Silver perks then Gold perks
  • Nothing
Show answer

Gold perks — switch jumps DIRECTLY to case 3: — earlier cases are never touched. Fallthrough only flows downward from wherever you land, and case 3 ends with a break.

The fine print: integers only

A switch works on integer types onlyint, char (it's a small integer!), enum values, long… Each case label must be a constant integer expression, known at compile time, with no duplicates. That means:

💡

switch vs if-ladder: use switch when comparing one integer expression against fixed constants — it states that intent clearly, the compiler checks for duplicate cases, and it can compile to a lightning-fast jump table. Use an if-ladder for ranges (score >= 90), floats, strings, or conditions on different variables.

This spot has an interactive editor widget — open the interactive lesson to play with it.

🧠 Checkpoint: Which of these can legally follow case in standard C?

  • case "add":
  • case 3.5:
  • case x: where x is a variable
  • case 'q':
Show answer

case 'q': — Case labels must be compile-time constant INTEGER expressions. A char literal like 'q' is an integer (113), so it qualifies. Strings, floats, and runtime variables are all out.

Branching lets programs choose a path; next comes the real superpower — doing something over and over with while.

▶ Practice this lesson interactively (with live gcc)