case 的基本概念和作用
case 关键字用于与 switch 后面的表达式(称为“控制表达式”)的值进行匹配,程序会从上到下依次检查每个 case 后面的“常量表达式”,一旦找到与控制表达式值相匹配的 case,程序就会从这个 case 标签开始执行,并一直执行下去,直到遇到 break 语句或者 switch 语句的结束大括号 。

(图片来源网络,侵删)
一个简单的例子:
#include <stdio.h>
int main() {
int day = 3;
switch (day) {
case 1:
printf("星期一\n");
break; // 跳出 switch
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n"); // day 的值是 3,匹配到这里
break;
case 4:
printf("星期四\n");
break;
default: // 如果所有 case 都不匹配,则执行这里
printf("其他天\n");
break;
}
return 0;
}
执行流程:
switch(day)的控制表达式是day,其值为3。- 程序开始检查
case:case 1:?3不等于1,跳过。case 2:?3不等于2,跳过。case 3:?3等于3,匹配成功!
- 程序从
printf("星期三\n");开始执行。 - 遇到
break;语句,立即终止整个switch语句的执行,程序跳转到return 0;。
关键特性详解
a. case 后必须是“常量表达式”
case 后面必须是一个常量表达式,不能是变量。
错误示例:

(图片来源网络,侵删)
int x = 5;
int y = 10;
switch (x) {
case y: // 错误!y 是变量,不是常量表达式
// ...
break;
}
正确示例:
#define PI 3.14159
const int MAX = 100;
switch (x) {
case 10: // 整数字面量
case 'A': // 字符字面量,实际是其 ASCII 码值
case PI: // 宏定义的常量
case MAX: // const 常量
// ...
break;
}
b. 贯穿执行
这是 switch 语句一个非常重要的特性,如果匹配到一个 case,但该 case 分支中没有 break 语句,程序会“穿透”并继续执行下一个 case 的代码,而不再进行任何匹配。
示例:
#include <stdio.h>
int main() {
char grade = 'B';
switch (grade) {
case 'A':
printf("优秀!\n");
break;
case 'B':
case 'C':
printf("良好,\n"); // grade 是 'B',匹配到这里
// 没有 break,会继续执行下一个 case
case 'D':
printf("及格,\n"); // 上一个 case 没有break,所以这里也会被执行
break;
default:
printf("不及格,\n");
break;
}
return 0;
}
输出结果:

(图片来源网络,侵删)
良好。
及格。
应用场景:
贯穿执行非常有用,可以用来处理多个 case 执行相同代码的情况,就像上面的例子,'B' 和 'C' 都执行“良好。”的打印,所以可以把它们写在一起,共享代码,避免了重复。
c. default 分支
default 是可选的,但它是一个很好的编程习惯,当 switch 控制表达式的值与任何一个 case 的常量都不匹配时,程序会执行 default 分支的代码。
default 分支可以放在 switch 语句的任何位置(通常在末尾),但无论它在哪里,它总是在所有 case 都匹配失败后执行。
示例:
int number = 99;
switch (number) {
case 1:
printf("One");
break;
// ...
default: // 即使放在前面,逻辑也一样
printf("Number not 1");
break;
case 2:
printf("Two");
break;
}
// 输出: Number not 1
d. 数据类型限制
在 C 语言中,switch 的控制表达式和 case 的常量表达式必须是以下几种类型之一:
intcharenum(枚举类型)- 或者可以从这些类型隐式转换的类型(
short可以提升为int)。
错误示例:
float price = 9.99;
switch (price) { // 错误!float 类型不能用于 switch
case 9.99:
// ...
break;
}
switch vs. if-else if-else
什么时候用 switch,什么时候用 if-else?
| 特性 | switch 语句 |
if-else if-else 语句 |
|---|---|---|
| 判断条件 | 只能判断离散值(常量) | 可以判断任何条件(范围、表达式、布尔值等) |
| 数据类型 | 有限制 (int, char, enum) |
几乎没有限制 |
| 执行效率 | 在某些情况下可能比一长串 if-else 更高效,因为编译器可以生成“跳转表” (jump table)。 |
对于简单的条件判断,效率也很高,对于复杂范围判断,逻辑更清晰。 |
| 可读性 | 当对一个变量进行多值判断时,switch 结构通常更清晰、更易读。 |
当判断逻辑复杂或涉及多个不同变量时,if-else 更灵活、更自然。 |
选择建议:
- 如果你要判断的是一个单一变量的多个确定值,优先使用
switch。// 适合用 switch switch (day) { case 1: ... break; case 2: ... break; // ... } - 如果你要判断的是范围、多个变量或者复杂的逻辑表达式,必须使用
if-else。// 适合用 if-else if (score >= 90 && score <= 100) { // ... } else if (score >= 80) { // ... } else if (x > 5 && y < 10) { // ... }
case定义了switch语句的匹配分支。case后必须是常量表达式。break用于终止switch语句的执行,防止贯穿。- 贯穿特性 (
fall-through) 允许多个case共享同一段代码。 default处理所有case都未匹配的情况。switch适用于对单一变量的离散值进行判断,结构清晰;if-else更通用,适用于复杂条件判断。
