switch Statements
switch picks one of several branches based on the value of an integer expression. It's tidier than a long else if chain when you're comparing one value against many constants — menu choices, commands, states.
Basic switch
#include <stdio.h> int main(void) { 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("Some other day\n"); break; } return 0; }
Wednesday
The expression is evaluated once and execution jumps to the matching case. break leaves the switch; default runs when nothing matches.
What can be switched on
- The expression must be an integer type —
int,char, anenum… - Each
caselabel must be a constant known at compile time: a literal, an enum constant or a#define. Not a variable, a range, adoubleor a string. - No two labels can have the same value.
Fall-through
Without break, execution simply continues into the next case. That's useful when several values share code:
#include <stdio.h> int main(void) { const char *word = "Programming"; int vowels = 0, others = 0; for (int i = 0; word[i] != '\0'; i++) { switch (word[i]) { case 'a': case 'e': case 'i': case 'o': case 'u': case 'A': case 'E': case 'I': case 'O': case 'U': vowels++; break; default: others++; break; } } printf("%d vowels, %d other letters\n", vowels, others); return 0; }
3 vowels, 8 other letters
Forgetting a break by accident is a common bug. Compilers can warn about it with -Wimplicit-fallthrough; when you fall through on purpose after some code, say so with a comment such as // fall through (or C23's [[fallthrough]];).
#include <stdio.h> int main(void) { int level = 2; printf("Unlocked:"); switch (level) { case 3: printf(" castle"); // fall through case 2: printf(" forest"); // fall through case 1: printf(" village"); break; } printf("\n"); return 0; }
Unlocked: forest village
A command menu
#include <stdio.h> int main(void) { const char commands[] = "+-*/x"; double a = 12, b = 4; for (int i = 0; commands[i] != '\0'; i++) { char op = commands[i]; switch (op) { case '+': printf("%g + %g = %g\n", a, b, a + b); break; case '-': printf("%g - %g = %g\n", a, b, a - b); break; case '*': printf("%g * %g = %g\n", a, b, a * b); break; case '/': if (b == 0) { printf("cannot divide by zero\n"); } else { printf("%g / %g = %g\n", a, b, a / b); } break; default: printf("unknown operator '%c'\n", op); break; } } return 0; }
12 + 4 = 16 12 - 4 = 8 12 * 4 = 48 12 / 4 = 3 unknown operator 'x'
Short cases can sit on one line. A case with several statements, or with its own variables, is clearer with braces: case '/': { … break; }.
switch with enums
Switching on an enum has a bonus: with -Wall, the compiler warns if you forgot to handle one of its values (as long as there's no default):
#include <stdio.h> enum light { RED, AMBER, GREEN }; const char *action(enum light l) { switch (l) { case RED: return "stop"; case GREEN: return "go"; } return "?"; } int main(void) { printf("%s\n", action(AMBER)); return 0; }
main.c:6:13: warning: enumeration value 'AMBER' not handled in switch [-Wswitch]
switch or if?
Use switch for one integer value compared against many constants. Use if/else if for ranges (score >= 90), conditions on different variables, floating-point values or strings.
Try it yourself
Print the number of days in each month of 2026 using a switch with grouped cases.
1:31 2:28 3:31 4:30 5:31 6:30 7:31 8:31 9:30 10:31 11:30 12:31