switch 语句是一种多分支选择结构,它允许一个变量或表达式在多个不同的值之间进行匹配,并根据匹配的值执行对应的代码块,它通常可以替代复杂的 if-else if-else 结构,使代码更清晰、更易读。
switch 语句的基本语法
switch 语句的基本结构如下:
switch (expression) {
case constant_expression1:
// 当 expression 的值等于 constant_expression1 时,执行这里的代码
statement1;
break; // 可选,但强烈推荐
case constant_expression2:
// 当 expression 的值等于 constant_expression2 时,执行这里的代码
statement2;
break; // 可选,但强烈推荐
case constant_expression3:
// 当 expression 的值等于 constant_expression3 时,执行这里的代码
statement3;
break; // 可选,但强烈推荐
default:
// expression 的值与所有 case 都不匹配时,执行这里的代码
default_statement;
break; // 可选
}
语法详解
switch (expression)
expression:这是要被测试的表达式,它必须是整型(int,char,short,long等)或枚举类型。浮点数(float,double)和字符串是不允许的。- 表达式的值会依次与每个
case后面的常量表达式进行比较。
case constant_expression:
constant_expression:这是一个常量表达式(1, 'A',100),它必须是编译时常量,不能是变量。case标签本身只是一个入口点,当switch表达式的值与某个case的值匹配时,程序就会从该case处开始执行。- 注意:
case后面的值必须是唯一的,不能有重复。
statement;
- 这是匹配的
case对应要执行的一条或多条语句。
break;
- 这是
switch语句中最关键也最容易出错的部分。 break语句的作用是立即跳出switch语句,防止程序“穿透”(fall through)到下一个case中去执行。- 如果没有
break,程序会从匹配的case开始,依次执行后面所有的case代码,直到遇到break或switch语句结束,这种行为被称为“贯穿”或“穿透”,有时可以有意利用它,但大多数情况下都是需要break来避免的。
default:
default是一个可选的分支,相当于if-else结构中的else。switch表达式的值与任何一个case都不匹配,程序就会执行default分支中的代码。default分支可以放在switch语句的任何位置,但为了代码清晰,通常放在最后。default分支后面也可以有break,但这不是必需的,因为default分支是最后一个分支,执行完自然就会退出switch。
完整示例
示例 1:基本用法(带 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"); // day 的值是 3,匹配这个 case
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期日\n");
break;
default:
printf("无效的输入\n"); // day 不在 1-7 之间,执行这里
break;
}
return 0;
}
输出:
星期三
示例 2:“穿透”(Fall Through)现象
这个例子展示了如果没有 break 会发生什么。
#include <stdio.h>
int main() {
char grade = 'B';
switch (grade) {
case 'A':
printf("优秀!\n");
break;
case 'B':
printf("良好!\n"); // 匹配 'B',开始执行
case 'C':
printf("及格,\n"); // 没有break,继续执行
case 'D':
printf("需要努力,\n"); // 没有break,继续执行
default:
printf("成绩已录入,\n"); // 没有break,继续执行
}
return 0;
}
输出:
良好!
及格。
需要努力。
成绩已录入。
程序从 case 'B' 开始,因为没有 break,所以一路“穿透”执行了后面的所有语句。
示例 3:利用“穿透”特性
虽然不常见,但有时我们可以利用“穿透”特性来简化代码,为多个等级设置相同的处理逻辑。
#include <stdio.h>
int main() {
char grade = 'C';
switch (grade) {
case 'A':
printf("成绩:A\n");
break;
case 'B':
case 'C': // 如果是 'B' 或 'C',都会执行这里的代码
printf("成绩:B 或 C\n");
break;
case 'D':
printf("成绩:D\n");
break;
default:
printf("未知成绩\n");
}
return 0;
}
输出:
成绩:B 或 C
switch 与 if-else if-else 的选择
| 特性 | switch 语句 |
if-else if-else 语句 |
|---|---|---|
| 判断条件 | 只能针对单一变量或表达式的离散值进行判断。 | 可以针对任意复杂条件进行判断,包括范围、逻辑组合等。 |
| 数据类型 | 限制较多:只能是整型或枚举类型。 | 非常灵活:可以用于任何数据类型(int, float, char, string 等)。 |
| 代码可读性 | 当分支较多且都是基于同一变量的离散值时,switch 结构更清晰。 |
当条件逻辑复杂或涉及范围判断时,if-else 结构更直观。 |
| 性能 | 在某些编译器和场景下,switch 可能会被优化成一个“跳转表”(Jump Table),执行效率可能更高。 |
通常是一系列的条件判断,效率取决于条件的顺序和复杂度。 |
- 如果你要判断的是一个整型变量,并且它的取值是有限的、确定的几个离散值,优先使用
switch。 - 如果你的判断条件涉及范围(如
x > 10)、逻辑组合(如x > 5 && y < 20),或者判断的是浮点数、字符串,那么你必须使用if-else。
重要注意事项
switch的表达式必须是整型:int,char,long,enum都可以,但float,double,char*(字符串) 不行。case的值必须是常量:不能是变量,case x:是错误的,但case 100:是正确的。- 不要忘记
break:这是初学者最常犯的错误,除非你确实需要“穿透”行为,否则在每个case的代码块末尾都加上break。 default是一个好习惯:即使你认为自己已经覆盖了所有情况,也最好加上default分支,用于处理意外情况,这能让程序更健壮。
