switch 语句的基本语法
switch (expression) {
case constant1:
// 当 expression 的值等于 constant1 时,执行这里的代码
break; // 可选,用于跳出 switch 语句
case constant2:
// 当 expression 的值等于 constant2 时,执行这里的代码
break; // 可选
default:
// 当 expression 的值不匹配任何一个 case 时,执行这里的代码
break; // 可选
}
关键点:

(图片来源网络,侵删)
expression(表达式):必须是一个整型表达式(int,char,short,long等),但不能是float,double或字符串。constant1,constant2(常量):必须是整型常量或常量表达式,每个case标签的值必须是唯一的。break语句:当执行完一个case中的代码后,如果没有break语句,程序会继续执行下一个case的代码,这被称为 "case 穿透" (fall-through),在大多数情况下,我们都需要break来防止这种情况。default:可选的,如果没有任何一个case匹配,则执行default后面的代码,它的位置可以任意,但通常放在最后。
简单例子:根据数字输出星期几
这是一个非常经典的 switch 例子,根据输入的数字(1-7)输出对应的星期名称。
#include <stdio.h>
int main() {
int day;
printf("请输入一个数字 (1-7): ");
scanf("%d", &day);
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("输入无效,请输入 1 到 7 之间的数字,\n");
break;
}
return 0;
}
代码解释:
- 程序提示用户输入一个数字。
scanf读取用户输入并存储在day变量中。switch (day)开始判断day的值。day是1,则执行case 1:后面的代码,打印 "星期一",然后遇到break,switch语句结束。day的值不匹配任何case(比如输入了 8),则执行default:后面的代码,提示输入无效。
进阶例子:利用 "Case 穿透" (Fall-through)
"case 穿透" 是一个有用的特性,我们可以用它来处理一个范围,或者将多个情况合并到同一种处理方式中。
例子:根据成绩评定等级 (A, B, C, D, F)

(图片来源网络,侵删)
假设评分标准:
- 90-100: A
- 80-89: B
- 70-79: C
- 60-69: D
- 0-59: F
我们可以利用 switch 的特性,通过整数除法将分数范围转换成离散的值。
#include <stdio.h>
int main() {
int score;
char grade;
printf("请输入你的成绩 (0-100): ");
scanf("%d", &score);
// 使用 score / 10 来将范围转换为离散值
// 95 -> 9, 85 -> 8, 75 -> 7, 65 -> 6, 55 -> 5
switch (score / 10) {
case 10:
case 9:
grade = 'A';
break;
case 8:
grade = 'B';
break;
case 7:
grade = 'C';
break;
case 6:
grade = 'D';
break;
default: // 处理 5, 4, 3, 2, 1, 0 以及负数或大于100的无效输入
if (score >= 0 && score < 60) {
grade = 'F';
} else {
printf("无效的成绩输入!\n");
return 1; // 提前退出程序
}
break;
}
printf("你的成绩等级是: %c\n", grade);
return 0;
}
代码解释:
score / 10是一个巧妙的技巧,它将90-100的分数都变成9或10。case 10:后面没有break,所以程序会继续向下执行,进入case 9:,然后设置grade = 'A',最后遇到break退出switch。- 这样,我们就用两个
case(10和9) 处理了90-100这个范围,实现了多对一的情况处理。 default分支处理了所有小于 60 的情况以及无效输入。
重要注意事项
-
switch的表达式必须是整型:不能是float或double。
(图片来源网络,侵删)// 错误示例 float f = 2.5; switch (f) { // 编译错误 // ... } -
case标签的值必须是唯一的:不能有两个case使用相同的常量值。// 错误示例 switch (x) { case 1: // ... case 1: // 编译错误:重复的 case 值 // ... } -
别忘了
break! 除非你明确想利用 "case 穿透",否则在每个case的末尾都应该加上break,这是初学者最容易犯的错误。// 错误示例(忘记break) int x = 2; switch (x) { case 1: printf("One\n"); case 2: printf("Two\n"); // 会执行 case 3: printf("Three\n"); // 也会执行!因为没有break default: printf("Default\n"); // 也会执行! } // 输出结果将是: // Two // Three // Default -
default是可选的:但加上它是一个好习惯,可以处理所有预料之外的情况,使程序更健壮。 -
switch的作用域:在 C99 及之后的标准中,你可以在switch语句内部声明变量,但要注意变量的作用域和初始化问题。
switch vs. if-else if
| 特性 | switch 语句 |
if-else if 语句 |
|---|---|---|
| 可读性 | 当检查一个变量对多个离散值时,switch 通常更清晰。 |
当检查多个复杂的条件或范围时,if-else if 更直观。 |
| 灵活性 | 较低,只能检查整型表达式。 | 非常高,可以检查任何类型的表达式(如 float, string, 复杂逻辑)。 |
| 性能 | 在某些编译器和架构下,switch 可能被优化成一个跳转表,效率更高。 |
通常是一系列比较,效率可能稍低。 |
| "穿透"特性 | 原生支持,可用于特定场景。 | 不存在,每个 else if 都是独立的。 |
- 当你需要根据一个整型变量的具体值来执行不同的代码块时,优先使用
switch。 - 当你需要检查范围(如
x > 10 && x < 20)、浮点数、字符串或复杂的逻辑条件时,使用if-else if。
