switch 语句是一种多路分支结构,它允许一个变量或表达式与一系列值(称为 case)进行比较,并根据匹配的值执行相应的代码块,它通常可以替代复杂的 if-else if-else 链,使代码更清晰、更易读。

(图片来源网络,侵删)
基本语法
switch 语句的基本结构如下:
switch (expression) {
case constant1:
// 当 expression 等于 constant1 时执行的代码
break;
case constant2:
// 当 expression 等于 constant2 时执行的代码
break;
case constant3:
// 当 expression 等于 constant3 时执行的代码
break;
default:
// 当 expression 不匹配任何一个 case 时执行的代码
break;
}
语法详解
a. switch (expression)
expression是一个整型表达式(包括int,char,enum类型,或者它们的short,long等变体),在 C 语言中,float,double,string等类型不能用于switch。- 这个表达式的值会与每个
case后面的constant进行比较。
b. case constant:
constant必须是一个常量或常量表达式(如10, 'A',2*5)。不能是变量(如int x = 10; case x:是错误的)。- 每个
case的值必须是唯一的,如果两个case有相同的值,编译器会报错。 - 当
expression的值与某个case的值匹配时,程序会开始执行该case后面的代码,并继续执行之后所有case的代码,直到遇到break语句或switch语句的末尾,这被称为“贯穿”(fall-through),是switch的一个重要特性。
c. break;
break语句用于终止switch语句的执行,当执行到break时,程序会立即跳出switch结构,继续执行switch语句后面的代码。- 如果没有
break,程序会“贯穿”到下一个case,这通常不是我们想要的结果,但在某些特定场景下可以被利用。
d. default:
default是一个可选的分支。expression的值不与任何一个case匹配,程序就会执行default后面的代码。default可以放在switch结构的任何位置,但通常习惯放在最后。default分支也可以没有break,因为它本身就是switch的出口。
示例代码
示例 1:基本用法(带 break)
这是一个最常见、最标准的用法,每个 case 都有自己的 break。
#include <stdio.h>
int main() {
int day = 3;
char* dayName;
switch (day) {
case 1:
dayName = "Monday";
break;
case 2:
dayName = "Tuesday";
break;
case 3:
dayName = "Wednesday";
break;
case 4:
dayName = "Thursday";
break;
case 5:
dayName = "Friday";
break;
case 6:
dayName = "Saturday";
break;
case 7:
dayName = "Sunday";
break;
default:
dayName = "Invalid day";
break;
}
printf("Day %d is %s\n", day, dayName); // 输出: Day 3 is Wednesday
return 0;
}
流程分析:
day的值是3。switch开始匹配case。case 1,case 2不匹配,跳过。case 3匹配,执行dayName = "Wednesday";。- 遇到
break;,立即跳出switch结构。 - 执行
printf语句。
示例 2:“贯穿”(Fall-Through)特性
switch 的“贯穿”特性在某些情况下非常有用,例如处理多个值对应同一种操作。

(图片来源网络,侵删)
#include <stdio.h>
int main() {
char grade = 'B';
switch (grade) {
case 'A':
printf("Excellent!\n");
break;
case 'B':
case 'C':
printf("Good job!\n"); // 当 grade 是 'B' 或 'C' 时,都会执行这句
break;
case 'D':
printf("You passed.\n");
break;
case 'F':
printf("Sorry, you failed.\n");
break;
default:
printf("Invalid grade.\n");
break;
}
return 0;
}
流程分析:
grade的值是'B'。case 'A'不匹配。case 'B'匹配,开始执行printf("Good job!\n");。- 因为没有
break,程序继续向下执行case 'C'的代码(虽然它不匹配,但“贯穿”的代码是直接执行的)。 case 'C'的代码执行完毕后,遇到break;,跳出switch。- 输出结果为:
Good job!
示例 3:没有 break 的情况(通常为 bug)
忘记写 break 是一个非常常见的错误。
#include <stdio.h>
int main() {
int number = 2;
switch (number) {
case 1:
printf("This is case 1.\n");
case 2:
printf("This is case 2.\n");
case 3:
printf("This is case 3.\n");
default:
printf("This is the default case.\n");
}
return 0;
}
输出结果:
This is case 2.
This is case 3.
This is the default case.
流程分析:

(图片来源网络,侵删)
number是2,匹配case 2。- 执行
printf("This is case 2.\n");。 - 没有
break,程序“贯穿”到case 3,执行printf("This is case 3.\n");。 - 仍然没有
break,程序继续“贯穿”到default,执行printf("This is the default case.\n");。 switch结束。
switch vs. if-else if-else
| 特性 | switch 语句 |
if-else if-else 语句 |
|---|---|---|
| 可读性 | 当检查一个变量与多个离散值相等时,switch 更清晰。 |
当条件复杂(如范围检查 x > 10 && x < 20)时,if 更自然。 |
| 灵活性 | 限制:只能用于相等性检查。 | 灵活:可以使用任何关系运算符(>, <, , )和逻辑运算符(&&, )。 |
| 数据类型 | 只能用于整型 (int, char, enum 等)。 |
可以用于任何数据类型(int, float, double, string 等)。 |
| 执行效率 | 在某些编译器和架构下,switch 可能会被编译成跳转表(jump table),比一连串的 if-else 判断更快。 |
通常效率也不错,但对于大量离散值,可能不如 switch 高效。 |
如何选择?
- 如果你要检查一个整型变量是否等于几个特定的常量值,优先使用
switch。 - 如果你的条件涉及范围、复合条件,或者变量类型不是整型,那么必须使用
if-else。
重要注意事项
-
case值必须唯一:不能有两个case标签具有相同的值。// 错误示例 switch (x) { case 10: // ... case 10: // 编译错误: duplicate case value // ... } -
expression必须是整型:不能使用浮点数或字符串。// 错误示例 switch (3.14) { // 编译错误: switch quantity not an integer // ... } -
break的必要性:除非你刻意利用“贯穿”特性,否则几乎每个case的最后都应该有一个break,一些现代编译器(如 GCC)在检测到缺少break的情况时会发出警告。 -
default的位置:default可以放在任何位置,但放在最后是最符合逻辑和阅读习惯的。
switch 是 C 语言中一个强大而优雅的控制流工具,特别适用于处理基于单个整型变量的多路分支,理解其“贯穿”特性是掌握 switch 的关键,通过合理使用 switch,你可以写出比冗长的 if-else if-else 链更简洁、更易读的代码。
