🌱 C Basics
switch, case, default: the multi-way jump
▶ Open the interactive lesson — free, no signupIn 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.
#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;
}$ 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:
#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;
}$ 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":
#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 only — int, 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:
- No strings:
case "yes":won't compile (you'll usestrcmpin an if-ladder instead). - No floats:
case 3.14:is rejected. - No runtime values or ranges:
case x:andcase 1 ... 5:aren't standard C (the latter is a GCC extension).
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 variablecase '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.