switch Statements
When one variable can have many fixed values, such as a menu choice, a day number or a grade letter, a long else if chain becomes hard to read. The switch statement compares one value against a list of constants and jumps straight to the matching one.
In this lesson you will write switch statements, learn why break matters so much, group several values together, and mark deliberate fall-through with the C23 [[fallthrough]] attribute.
How switch works
A switch evaluates the expression in brackets once. It then jumps to the case label whose value matches. If nothing matches, it jumps to default, if there is one.
#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;
case 4:
printf("Thursday\n");
break;
case 5:
printf("Friday\n");
break;
default:
printf("Weekend or invalid day\n");
break;
}
return 0;
}Wednesday
The break statement ends the switch and continues after its closing brace. default is optional, but including it is good practice: it handles unexpected values, which are often the source of bugs. The break after default is not strictly needed, but it keeps every case looking the same and protects you if you add a new case below it later.
break and fall-through
A case label is only a starting point. Once C jumps to a label, it keeps running the statements below it, through any further labels, until it reaches a break or the end of the switch. This is called fall-through. Forget one break and you get a surprise:
#include <stdio.h>
int main(void)
{
int floor_choice = 2;
switch (floor_choice) {
case 1:
printf("Going to floor 1\n");
case 2:
printf("Going to floor 2\n");
case 3:
printf("Going to floor 3\n");
default:
printf("Doors closing\n");
}
return 0;
}Going to floor 2 Going to floor 3 Doors closing
The lift jumped to case 2 correctly but then fell through everything below it. With -Wextra, GCC warns "this statement may fall through" for each missing break, another reason to compile with warnings on.
Grouping cases
Fall-through is useful when several values need the same code. Stack the labels with nothing between them:
#include <stdio.h>
int main(void)
{
char ch = 'e';
switch (ch) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("%c is a vowel\n", ch);
break;
default:
printf("%c is not a vowel\n", ch);
break;
}
return 0;
}e is a vowel
Labels with no statements between them are never treated as a mistake, so the compiler does not warn here.
Intentional fall-through with [[fallthrough]]
Sometimes you really do want one case to run its own code and then continue into the next. Membership plans are a good example: a gold member gets everything a silver member gets, plus more.
#include <stdio.h>
int main(void)
{
char plan = 'S'; // G = gold, S = silver, B = basic
printf("Benefits of plan %c:\n", plan);
switch (plan) {
case 'G':
printf("- Free home delivery\n");
[[fallthrough]];
case 'S':
printf("- 10%% off every order\n");
[[fallthrough]];
case 'B':
printf("- Monthly offers by SMS\n");
break;
default:
printf("- Unknown plan\n");
break;
}
return 0;
}Benefits of plan S: - 10% off every order - Monthly offers by SMS
A silver member enters at case 'S' and falls into case 'B'. Change plan to 'G' and all three benefits print.
A menu-driven calculator
switch works naturally with char values such as operator symbols. A case can contain any statements, including an if:
#include <stdio.h>
int main(void)
{
double a = 84.0, b = 12.0;
char op = '/';
double result = 0.0;
bool ok = true;
switch (op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '*': result = a * b; break;
case '/':
if (b != 0) {
result = a / b;
} else {
ok = false;
}
break;
default:
ok = false;
break;
}
if (ok) {
printf("%.2f %c %.2f = %.2f\n", a, op, b, result);
} else {
printf("Cannot calculate\n");
}
return 0;
}84.00 / 12.00 = 7.00
Short cases may sit on one line, as the first three do. The default branch rejects any operator the program does not know.
Rules for case labels
- The
switchexpression must be an integer type:int,char,long,boolor anenum. You cannot switch on adoubleor a string. - Each
casevalue must be an integer constant expression, known at compile time: a literal such as3or'a', a#definemacro, anenumconstant, or a C23constexprvalue. Aconst intvariable or a normal variable is not allowed. - Two cases cannot have the same value; the compiler reports a duplicate case.
- Ranges such as
case 1 ... 5:are a GCC extension, not standard C. Use stacked labels or anifinstead. - If a case needs its own local variables, wrap its statements in braces:
case 1: { int bonus = 50; ... break; }. This keeps the variable's scope inside that case.
switch or if-else?
| Situation | Better choice |
|---|---|
| One variable compared with many fixed values | switch |
| Ranges, such as marks from 75 to 89 | if...else if |
| Strings, decimals or several different variables | if...else if |
| Several values sharing the same code | switch with stacked labels |
Common mistakes
- Forgetting
break. The code falls into the next case. Compile with-Wextrato get a warning. - Switching on a string.
switch (city)withcase "Pune":does not compile. Compare strings withstrcmpandif. - Using a variable as a label.
case limit:fails unlesslimitis a compile-time constant such as aconstexprvalue. - No
default. Unexpected values silently do nothing, which hides bugs.
Key points
switchjumps to thecasematching an integer value, or todefaultwhen none matches.- Execution continues through later cases until a
break; this is called fall-through. - Stack labels with nothing between them to share code between values.
- Mark deliberate fall-through with C23
[[fallthrough]];to document it and silence the warning. - Case labels must be integer constants: literals, macros,
enumvalues orconstexprvalues.
Exercise
A college canteen in Kochi numbers its items: 1 for tea (Rs 12), 2 for coffee (Rs 15), 3 for veg puff (Rs 20) and 4 for meals (Rs 60). Write a program with int choice = 3; and int quantity = 4; that uses a switch to find the item name and price, then prints the bill. For any other choice, print "Invalid choice".
Show solution
#include <stdio.h>
int main(void)
{
int choice = 3;
int quantity = 4;
int price = 0;
switch (choice) {
case 1:
printf("Tea");
price = 12;
break;
case 2:
printf("Coffee");
price = 15;
break;
case 3:
printf("Veg puff");
price = 20;
break;
case 4:
printf("Meals");
price = 60;
break;
default:
printf("Invalid choice\n");
return 1;
}
printf(" x %d = Rs %d\n", quantity, price * quantity);
return 0;
}Veg puff x 4 = Rs 80
Each case prints the item name and sets the price, then break leaves the switch. The default case returns early, so the bill line runs only for valid choices.
Quick Quiz
1. What happens if a case has no break?
Without break, C falls through and runs the statements of the following cases too.
2. Which of these can be used as a case label?
Case labels must be integer constant expressions; character literals are integers in C.
3. What does [[fallthrough]]; do in C23?
The attribute documents that falling into the next case is deliberate.
4. When is an if...else if chain better than a switch?
switch matches exact constant values only; ranges and complex conditions need if.
Learn C with a mentor
Free lessons get you started. Our Java, C & C++ Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
