C in 100 Seconds: Switch Statement | Episode 6
Video: C in 100 Seconds: Switch — case, break, default | Episode 6 by Taught by Celeste AI - AI Coding Coach
C Switch / Case
switch (value) { case X: ... break; default: ... }. Cleaner than long if-else chains for branching on a single value. Always includebreakunless you intentionally want fall-through.
switch is C's structured way of dispatching on integer values. Forget the break and you get fall-through bugs that haunt early C code.
The basic shape
#include <stdio.h>
int main() {
int day = 3;
switch (day) {
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
default:
printf("Other day\n");
}
return 0;
}
Output: Wednesday.
The switch (day) evaluates day once. Each case N: is a label; execution jumps to the matching one. break exits the switch.
case labels are integer constants
switch (x) {
case 1: ... // OK
case 1 + 2: ... // OK (constant expression)
case 'A': ... // OK (char is an int)
case some_var: ... // ERROR — must be constant
case 1.5: ... // ERROR — no floats
}
case requires a compile-time constant integer expression. No variables, no floats, no strings. C++17 has if constexpr and pattern matching extensions; C does not.
Fall-through
Without break, execution falls through to the next case:
switch (grade) {
case 'A':
case 'B':
printf("Good job\n");
break;
case 'C':
printf("OK\n");
break;
default:
printf("Try harder\n");
}
'A' falls through to 'B''s block. Useful for "multiple cases, one action."
But unintentional fall-through is a notorious bug source:
switch (cmd) {
case 'q':
quit = 1; // forgot break!
case 's':
save(); // ALSO runs after 'q'
break;
}
Modern compilers warn (-Wimplicit-fallthrough). C23 introduces [[fallthrough]]:
switch (cmd) {
case 'q':
quit = 1;
[[fallthrough]]; // explicit; suppresses warning
case 's':
save();
break;
}
For older C, the convention is a comment:
case 'q':
quit = 1;
/* fall through */
case 's':
save();
break;
default
switch (x) {
case 1: ...; break;
case 2: ...; break;
default:
// runs if no case matches
}
default is optional but recommended — without it, an unexpected value silently does nothing.
default doesn't have to be last (some codebases put it first), but convention is last.
switch vs if-else chain
// switch — clearer for many cases on one value
switch (day) {
case 1: monday(); break;
case 2: tuesday(); break;
case 3: wednesday(); break;
// ...
}
// if-else — clearer for ranges or multiple variables
if (score >= 90) ...
else if (score >= 80) ...
else if (age > 18 && score > 70) ...
Use switch for "match this exact value." Use if-else for ranges, multi-variable conditions, or non-integer comparisons.
switch is also faster on many compilers — they generate jump tables (one indirect branch) instead of sequential comparisons.
Variables in case bodies
A case body isn't a new scope by default. Declaring a variable inside is fine, but you need braces:
switch (x) {
case 1: { // braces start a block scope
int y = 5;
printf("%d\n", y);
break;
}
case 2: {
int y = 10; // different y; OK because of braces
printf("%d\n", y);
break;
}
}
Without braces, the second int y would clash. With braces, each case gets its own scope.
Range cases (GCC extension)
switch (grade_pct) {
case 0 ... 59: printf("F\n"); break; // GCC/Clang only
case 60 ... 69: printf("D\n"); break;
case 70 ... 79: printf("C\n"); break;
case 80 ... 89: printf("B\n"); break;
case 90 ... 100: printf("A\n"); break;
}
case A ... B: is a GCC/Clang extension — not portable. For portable code, use if-else chains for ranges.
Switch on chars
char c = 'a';
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u':
printf("Vowel\n");
break;
default:
printf("Consonant\n");
}
Chars are integers (1-byte) in C. Cases for 'a', 'e', etc. Multi-case fall-through is the idiom for "any of these."
Common mistakes
Forgetting break. Falls through to the next case. Compiler may warn; tests should catch. Always be explicit.
case "string":. Strings aren't integers. Switch only works on int-compatible values. For string dispatch, use a hash map or chained strcmps.
Variables without braces. case 1: int x = 5; errors because the declaration isn't in a block. Add { ... } around the body.
case with non-constant. case n: (where n is a variable) doesn't compile.
Ranges in standard C. case 1 ... 10: is GCC-only.
Ordering matters less. Unlike if-else, switch jumps directly. But matching cases all execute (if no break), in source order, after the first match.
What's next
Episode 7: while loops. while, do-while, and choosing between them.
Recap
switch (val) { case X: ... break; case Y: ... break; default: ... }. Cases must be compile-time integer constants. Forget break and you fall through. Use intentional fall-through (multiple cases with no body) for "any of these." default for "everything else." Wrap case bodies in { } if declaring variables inside. For ranges, use if-else (or GCC's case A ... B: extension).
Next episode: while loops.