当需要根据一个变量的多种具体取值分别处理时,switch 比多个 if-else 更清晰,结构也更整齐。
4.4
当需要根据一个变量的多种具体取值分别处理时,switch 比多个 if-else 更清晰,结构也更整齐。
switch 的执行方式是:拿 switch 括号里表达式的值,依次和每个 case 后面的常量比较,找到第一个相等的就跳进去执行,遇到 break 就跳出整个 switch。
int、char 等)或枚举类型表达式,不能用 float、double 或 string。case 后面的值也必须是编译期就能确定的常量,不能是变量。case 结尾都要加 break,否则程序会继续执行下面的 case(称为"穿透",fall-through),大多数时候这是 bug!| 1 | int x = 1; |
| 2 | switch (x) |
| 3 | { |
| 4 | case 1: // ⚠️ 忘记写 break |
| 5 | cout << "一\n"; |
| 6 | case 2: |
| 7 | cout << "二\n"; |
| 8 | break; |
| 9 | } |
| 10 | // x=1 时,实际输出"一"和"二"两行,而不是只输出"一" |
由于 case 1: 没写 break,即使匹配上了 case 1,程序也会"顺流而下",接着把 case 2 里的代码也执行一遍,直到遇到下一个 break 或 switch 结束为止。这是初学者最容易踩的坑。
穿透大多数时候是 bug,但有一种情况下故意穿透非常实用——让多个 case 共享同一段代码,省去重复书写:
| 1 | int day = 3; |
| 2 | switch (day) |
| 3 | { |
| 4 | case 1: // 故意穿透:1~5 共享同一输出 |
| 5 | case 2: |
| 6 | case 3: |
| 7 | case 4: |
| 8 | case 5: |
| 9 | cout << "工作日\n"; |
| 10 | break; // 到这里才退出 |
| 11 | case 6: |
| 12 | case 7: |
| 13 | cout << "周末\n"; |
| 14 | break; |
| 15 | default: |
| 16 | cout << "错误输入\n"; |
| 17 | break; |
| 18 | } |
default 是保底选项,当所有 case 都不匹配时执行,类似于 else。它可以放在 switch 内的任意位置,但习惯上放最后,保持代码整洁。switch 和 if-else if-else 链在很多场景下可以互相替代,怎么选并不是随意的,取决于要判断的到底是什么:
1/2/3/4、星期几、字符是元音字母中的哪一个。分支一多,switch 的结构比一长串 else if 清晰得多。≥90、≥75……)、涉及浮点数/字符串比较,或者条件本身很复杂(需要 &&、|| 组合)。这些 switch 完全做不到,只能用 if-else。把本节内容汇总成几条最容易踩坑的规则:
switch 只能判断"是否等于某个整数/字符常量",写不出"大于60小于90"这种范围判断,也不支持 float/double/string 作为判断表达式。范围判断必须用 if-else。default 不是必需的,但省略它意味着"所有 case 都不匹配"时 switch 什么都不做,容易掩盖输入了预期之外数据的情况。养成写上 default 分支的习惯,即使只是打印一条错误提示。case 后面必须是编译期就能确定的常量(字面量或 const 常量),不能是普通变量,比如 case n:(n 是变量)会直接编译报错。