本文目录导读:
在编程世界里,switch(i) 是几乎所有 C 系开发者都写过的一行代码,它简洁、直观,却暗藏许多细节,看似简单的关键字组合,用好了是屠龙刀,用不好是绊脚石。
从 if 到 switch(i)
当我们需要根据整数变量的不同取值执行不同逻辑时,用 if-else 链也能完成,但代码会显得冗长而缺乏节奏感,而 switch(i) 提供了一种表意清晰、结构整齐的写法:
int i = 2;
switch(i) {
case 1:
printf("one\n");
break;
case 2:
printf("two\n");
break;
default:
printf("other\n");
}
一眼看过去,分支条件一目了然,阅读体验远胜于一串 else if。
switch(i) 的核心规则
要真正驾驭 switch(i),必须记住三条铁律:
- switch 表达式必须是整型或枚举类型,不能是浮点数,也不能是字符串。
- case 标签必须是常量表达式,不能是变量。
- 没有 break 就会发生“穿透”,也就是继续执行下一个 case 的语句。
这三条规则,既是 switch 的力量所在,也是无数 bug 的源头。
fallthrough 陷阱
很多人第一次被 switch(i) 坑,就是因为忘了写 break。
switch(i) {
case 1:
printf("A");
case 2:
printf("B");
}
当 i = 1 时,程序会输出 AB,而不是只输出 A,这种“穿透”行为在 C/C++ 中是合法的,但很容易造成逻辑错误。
如果想故意使用穿透,现代编译器允许用 [[fallthrough]] 标注意图,让代码更安全:
switch(i) {
case 1:
printf("A");
[[fallthrough]];
case 2:
printf("B");
break;
}
default 的位置
default 不一定非得放在最后,在 switch(i) 中,case 的顺序可以任意调整,default 放在中间也合法,但为了可读性,强烈建议把 default 放在最后,作为一个最终的兜底分支。
变量声明与作用域
在 switch(i) 的 case 里直接声明变量,可能会因为没有初始化而报错。
switch(i) {
case 1:
int x = 10; // 可能编译错误
printf("%d", x);
break;
default:
break;
}
正确做法是用花括号包裹:
switch(i) {
case 1: {
int x = 10;
printf("%d", x);
break;
}
default:
break;
}
这样变量作用域清晰,也不会因跳转而引发未初始化问题。
性能与替代
switch(i) 在编译器优化下,有可能生成跳转表,执行效率比 if-else 链更高,但如果分支非常稀疏,编译器也可能退化为比较树,现代语言如 Rust 的 match 已经比 switch 强大得多,但 C 的 switch(i) 依然凭借其简单高效,在底层开发中占据不可替代的位置。
写给自己的 switch(i)
每一个 switch(i) 都是一次选择,代码里的分支,正如人生中的路口,多一个 break,少一个 fallthrough,愿你每一次 switch,都能清晰地抵达想要的 default。

