在 C 语言当中 case 是 switch 选择结构里面的分支标记,用来匹配 switch 括号里面表达式的结果,匹配成功之后就执行对应 case 后面的代码,搭配 break 语句可以跳出 switch 结构,如果不写 break 就会发生穿透,继续执行后面所有 case 里面的代码,这个穿透特性既是高频考点也是新手最容易出错的地方。之所以设计 case 这种语法,是当一个变量需要和多个固定常量做等值判断的时候,相比写一长串 if else,switch 加 case 写法可读性更强,结构更整齐,但是 case 有硬性限制,它后面只能写整型字符型的常量表达式,不能写区间判断,也不能写变量,这一点和 if 有本质区别,很多初学者会尝试在 case 后面写范围条件,编译器直接报错。
基础语法结构
switch 括号里面的表达式计算结果必须是整型 字符型 枚举类型,不能是浮点数。
每一个 case 后面跟上常量值,再加冒号,然后写要执行的语句。
break 作用是终止当前 switch,执行完 break 之后就跳出整个 switch 结构。
default 是可选分支,所有 case 都匹配失败的时候才会执行 default 里面代码,default 位置可以放在任意位置,不一定要写在末尾。
基础代码示例
include
int main ()
{
int num = 2;
switch (num)
{
case 1:
printf ("数字是 1");
break;
case 2:
printf ("数字是 2");
break;
case 3:
printf ("数字是 3");
break;
default:
printf ("没有匹配的数字");
}
return 0;
}
case 穿透特性详解
穿透就是匹配到某一个 case 之后,如果该 case 末尾没有 break,程序不会停止,会继续往下执行下一个 case 里面的代码,直到遇到 break 或者整个 switch 结束。这个特性可以主动利用,比如多个分支执行相同代码,就可以把多个 case 写在一起,共用后面的执行语句,不需要重复写代码。
示例 多个 case 共用代码
switch (score)
{
case 1:
case 2:
case 3:
printf ("等级低");
break;
case 4:
case 5:
printf ("等级高");
break;
}
上面代码里面 case1 case2 case3 都没有 break,会穿透到同一个打印语句,这是 case 非常经典的优化写法。
case 使用限制要点
第一 case 后面的值必须是编译期常量,不能是变量,不能是动态计算的值,也不能写类似 case 1 到 5 这种区间表达式。
第二 同一个 switch 里面,所有 case 的常量值不能重复,重复定义编译器会报错。
第三 switch 表达式不能使用 double float 浮点数,因为浮点数存在精度误差,等值匹配不可靠。
第四 case 后面可以是空语句,也就是只有标记没有代码,就是前面提到的合并分支用法。
第五 字符类型可以直接写在 case 后面,因为 char 本质是整型,比如 case a,会按照字符对应的 ASCII 码做匹配。
相关对比表格
| 项目 | case 搭配 switch | if else 分支 |
|---|---|---|
| 判断方式 | 等值匹配 | 支持等值 大于小于 区间判断 |
| 判断对象 | 整型 字符 枚举 | 任意类型表达式 |
| 代码可读性 | 多固定值分支更清晰 | 复杂条件更灵活 |
| 穿透特性 | 存在 case 穿透 | 没有穿透机制 |
| 性能 | 编译器可优化成跳转表 | 逐个条件判断 |
深度拓展知识
编译器对于 case 分支,当分支数量比较多的时候,会自动优化成跳转表,运行效率高于连续 if else,但是如果分支很稀疏,跳转表占用内存过大,编译器又会退回成类似 if else 的比较逻辑。
default 分支不是必须写,如果业务上所有可能取值都已经被 case 覆盖,可以省略 default,但是工程规范一般建议保留 default,用来捕获意外取值,方便排查 bug。
switch 里面依然可以嵌套其他 switch,也就是内层 switch 里面同样可以写 case,嵌套的时候要注意 break 只会跳出当前所在这一层 switch,不会直接跳出外层 switch,这个是嵌套场景非常容易踩坑的点。
【常见问题】
问题 1 c 语言中 case 的用法里面忘记写 break 会出现什么情况
回答 1 c 语言中 case 的用法里面忘记写 break 会触发 case 穿透,匹配成功之后程序继续执行后面所有 case 代码,直到遇到 break 或者 switch 全部执行完毕,如果不是刻意利用穿透,就会产生逻辑错误。
问题 2 c 语言中 case 的用法能不能写变量或者区间判断
回答 2 c 语言中 case 的用法不能写变量,也不能直接写区间判断,case 后面必须是编译阶段就确定的常量,想要区间判断需要改用 if else 语句实现。
问题 3 c 语言中 case 的用法可以使用浮点数作为匹配值吗
回答 3 c 语言中 case 的用法不支持浮点数匹配,switch 表达式不能是 float 或者 double 类型,因为浮点数存在舍入误差,等值匹配不稳定,所以 case 不能用来匹配小数。
问题 4 c 语言中 case 的用法里面 default 必须放在最后吗
回答 4 c 语言中 case 的用法里面 default 不是必须放在最后,可以放在 switch 内部任意位置,但是如果 default 后面没有 break,同样会发生穿透,常规代码习惯还是把 default 写在末尾提升可读性。
【免责申明】
本文代码属于 C 语言教学演示,仅用于学习练习,不同编译器对 switch 跳转表优化策略存在差异,嵌套 switch 和 case 穿透属于需要谨慎使用的语法特性,实际项目开发请根据业务逻辑合理添加 break,本文不对所有复杂嵌套场景的运行结果做绝对保证。


