12. 流程控制(下):switch语句、break在switch中的作用、default分支、switch与if的选择
好,咱们接着聊流程控制。上一章我们把 if-else 翻来覆去讲透了,这一章轮到它的好兄弟——switch 语句登场。
说实话,我刚开始学 C 语言那会儿,总觉得 switch 有点鸡肋。心想:不就是个 if-else 的变种吗?后来做项目做多了才发现,这玩意儿用对了地方,代码能清爽一大截。今天我就把 switch 的底裤扒干净,让你一次看明白。
12.1 switch 语句的基本结构
switch 语句长什么样?看个例子你就懂了:
#include <stdio.h>
int main() {
int score = 85;
int level = score / 10; // 取十位数
switch (level) {
case 10:
case 9:
printf("优秀\n");
break;
case 8:
printf("良好\n");
break;
case 7:
printf("中等\n");
break;
case 6:
printf("及格\n");
break;
default:
printf("不及格\n");
break;
}
return 0;
}
这个代码把分数按十位数分组。85 分对应 level=8,输出"良好"。
switch 的执行流程其实很简单:
- 先计算括号里的表达式,得到一个整数值
- 然后从上往下找匹配的
case标签 - 找到了就从这个 case 开始执行,直到遇到
break或 switch 结束 - 如果所有 case 都不匹配,就走
default
嗯,这里有个关键点:switch 只能判断整数类型(包括 char、enum)。浮点数、字符串?不行,老老实实用 if。
12.2 break 在 switch 中的作用
break 在 switch 里是个什么角色?说白了就是"到此为止,别往下跑了"。
我见过不少新手踩这个坑。他们以为每个 case 执行完会自动跳出,其实不会!C 语言的 switch 有个特性叫"穿透"(fall-through)——如果没有 break,执行完一个 case 会继续往下走。
看这个例子:
int day = 2;
switch (day) {
case 1:
printf("周一\n");
case 2:
printf("周二\n");
case 3:
printf("周三\n");
default:
printf("其他\n");
}
// 输出:
// 周二
// 周三
// 其他
为什么会这样?因为 day=2 匹配了 case 2,然后一路往下执行,直到 switch 结束。没有 break 拦住它。
不过穿透也不全是坏事。有时候我们故意利用它:
char grade = 'A';
switch (grade) {
case 'A':
case 'B':
printf("通过\n");
break;
case 'C':
case 'D':
printf("补考\n");
break;
default:
printf("重修\n");
break;
}
这里 A 和 B 共享同一个输出,C 和 D 共享另一个。省去了重复代码,挺干净的。
12.3 default 分支
default 相当于 switch 里的"兜底条款"。所有 case 都不匹配时,就执行它。
我个人习惯把 default 写在最后,虽然语法上它可以在任何位置。但写在最后最符合阅读习惯,你想想看,从上往下读,先看正常情况,最后看异常处理,逻辑很顺。
default 要不要加 break?我的建议是:加。虽然 default 在最后,不加 break 也不会出问题,但万一以后有人在 default 后面又加了 case 呢?这种事我在代码评审里见过不止一次。加个 break 花不了半秒钟,但能省掉一个潜在的坑。
12.4 switch 与 if 的选择
这是很多初学者纠结的问题:什么时候用 switch,什么时候用 if?
我总结了一个简单的判断标准:
| 场景 | 推荐用 | 原因 |
|---|---|---|
| 判断单个整数的多个固定值 | switch | 代码清晰,可读性强 |
| 判断范围(如 x > 10) | if | switch 不支持范围判断 |
| 判断浮点数或字符串 | if | switch 只支持整数类型 |
| 分支数量少(2-3 个) | if | switch 显得大材小用 |
| 分支数量多(4 个以上) | switch | if-else 链太长,阅读困难 |
| 需要复杂条件组合 | if | switch 只能做等值判断 |
说白了,switch 适合"多选一"的场景,if 适合"条件判断"的场景。两者各有各的用武之地。
我记得有一次做嵌入式菜单系统,用户按键对应 12 种操作。用 if-else 写了 12 层嵌套,自己看着都头疼。后来改成 switch,代码瞬间清爽了,维护起来也方便。这就是选对工具的威力。
12.5 知识体系总览
下面这张图把 switch 的核心知识点串起来了,你可以对照着复习:
12.6 避坑指南
最后,我把自己这些年踩过的坑整理一下,你写代码时多留个心眼:
- 别忘了 break:这是 switch 第一坑。我每次写 case 都是先写 break 再写逻辑,顺序反了就容易忘。
- case 后面必须是常量:不能写变量,不能写表达式。比如
case a:是错的,case 1+2:也是错的(虽然有些编译器支持,但标准 C 不允许)。 - default 不是必须的:但建议加上。哪怕什么都不做,也写个
default: break;,表明你考虑过这种情况。 - switch 嵌套要谨慎:switch 里再套 switch,可读性会急剧下降。如果遇到这种情况,考虑拆成函数。
- 变量声明要小心:在 case 里声明变量,需要用花括号括起来,否则可能编译报错。
好了,switch 的内容就这些。记住一句话:switch 是 if 的补充,不是替代。选对工具,代码才能写得漂亮。
公众号:蓝海资料掘金营,微信deep3321