switch-case 是一种多分支选择结构,它可以根据一个变量的值,从多个代码块中选择一个来执行,它可以看作是 if-else if-else 链的一种更清晰、更高效的替代方案,尤其是在需要检查同一个变量的多个离散值时。

(图片来源网络,侵删)
基本语法
switch-case 语句的基本结构如下:
switch (expression) {
case constant_expression1:
// 当 expression 的值等于 constant_expression1 时,执行的代码
break;
case constant_expression2:
// 当 expression 的值等于 constant_expression2 时,执行的代码
break;
case constant_expression3:
// 当 expression 的值等于 constant_expression3 时,执行的代码
break;
default:
// 当 expression 的值不匹配任何一个 case 时,执行的代码
break;
}
语法详解
让我们分解一下这个结构中的每个部分:
-
switch (expression)switch是关键字。expression是一个整型表达式(在 C 语言标准中,必须是int或char类型,因为char在本质上是小范围的整数),不能是浮点数(如float或double)或其他复杂类型。- 这个表达式的值将和下面每个
case后面的常量进行比较。
-
case constant_expression:
(图片来源网络,侵删)case是关键字。constant_expression必须是一个常量或常量表达式(10, 'A',2*5),不能是变量。switch的表达式的值与某个case的常量值相等,程序就会跳转到该case标签处开始执行。
-
break;break是一个极其重要的关键字。- 它的作用是立即终止
switch语句的执行,并跳出switch结构,继续执行switch之后的代码。 - 如果没有
break,程序会“穿透”(fall-through)到下一个case,并继续执行其代码,直到遇到一个break或者switch语句结束,这种“穿透”特性既有用(可以省略重复代码),也容易出错(容易忘记break)。
-
default:default是一个可选的关键字。- 它相当于
if-else结构中的else。 switch的表达式的值不匹配任何一个case的值,程序就会跳转到default标签处执行。default语句可以放在switch结构的任何位置(通常在最后),但无论放在哪里,它都只在所有case都不匹配时才执行,为了代码清晰,强烈建议将其放在最后。default语句后面的break;也是可选的。default是最后一个case,并且后面没有其他代码,可以省略break,但为了保持一致性,通常还是加上。
执行流程
- 计算
switch(expression)的值。 - 将这个值与第一个
case的常量进行比较。 - 如果匹配,就跳转到该
case处开始执行。 - 如果不匹配,就继续与下一个
case的常量进行比较,以此类推。 - 如果所有
case都不匹配,就跳转到default语句(如果存在)开始执行。 - 在执行某个
case的代码时,如果遇到break;,则立即退出整个switch语句。 - 如果没有遇到
break;,则会继续执行下一个case的代码,这就是所谓的“穿透”。
示例代码
示例 1:基本用法(带 break)
这个例子展示了最常见、最安全的用法,每个 case 都有 break。
#include <stdio.h>
int main() {
int day = 3;
switch (day) {
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("周末\n");
break;
case 7:
printf("周末\n");
break;
default:
printf("无效的输入\n");
break;
}
return 0;
}
// 输出: 星期三
示例 2:利用“穿透”特性
假设我们想把工作日(1-5)都归为“工作日”,周末(6-7)归为“休息日”,我们可以利用穿透特性来避免重复代码。

(图片来源网络,侵删)
#include <stdio.h>
int main() {
int day = 4;
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break; // 只在最后加一个 break,前面的 case 都会穿透到这里
case 6:
case 7:
printf("休息日\n");
break;
default:
printf("无效的输入\n");
break;
}
return 0;
}
// 输出: 工作日
示例 3:忘记 break 的危险
这个例子展示了忘记 break 会发生什么。
#include <stdio.h>
int main() {
int grade = 'B'; // 'B' 的 ASCII 码是 66
switch (grade) {
case 'A':
printf("优秀!\n");
break;
case 'B':
printf("良好!\n");
// 忘记了 break!
case 'C':
printf("及格.\n");
break;
case 'D':
printf("不及格.\n");
break;
default:
printf("无效等级.\n");
break;
}
return 0;
}
// 输出:
// 良好!
// 及格.
分析:因为 grade 是 'B',程序进入了 case 'B',打印了 "良好!",由于没有 break,程序继续向下执行,进入了 case 'C',又打印了 "及格.",这通常不是我们想要的结果。
switch-case 与 if-else if-else 的比较
| 特性 | switch-case |
if-else if-else |
|---|---|---|
| 可读性 | 当检查同一个变量的多个离散值时,switch 结构更清晰、更易读。 |
当条件比较复杂(涉及范围、逻辑与/或、不同变量)时,if-else 更直观。 |
| 灵活性 | 低,只能用于整型表达式,且 case 后必须是常量。 |
高,可以用于任何类型的表达式,条件非常灵活。 |
| 性能 | 在某些情况下,编译器可以生成更高效的跳转表(jump table),执行速度可能更快。 | 通常是通过一系列比较来实现,可能不如 switch 高效。 |
| 穿透特性 | 有“穿透”特性,可以有意为之来合并多个 case,但也容易因忘记 break 而出错。 |
没有“穿透”特性,每个 if-else 块都是独立的。 |
如何选择?
- 优先使用
switch-case:当你需要根据一个整型变量的值来执行不同的操作,并且这些值是离散的、固定的,菜单选择、状态码、星期几等。 - 使用
if-else if-else:当你的条件涉及范围(如x > 10 && x < 20)、多个变量、浮点数比较或者复杂的逻辑表达式时。
switch-case是 C 语言中处理多分支选择的强大工具。- 核心要点:
switch后跟整型表达式,case后跟常量,break用于终止分支,default处理所有不匹配的情况。 - 最关键的陷阱:忘记
break会导致“穿透”行为,这通常是逻辑错误的原因。 - 善用穿透:在需要合并多个
case的逻辑时,可以有意省略break来利用穿透特性,减少代码重复。 - 与
if-else的选择:根据场景的灵活性和可读性来决定使用哪种结构。switch适用于离散整型值的判断,if-else适用于更复杂的条件。
