
switch 的 case 必须是整型常量表达式
很多人写 switch 时直接塞字符串、浮点数或变量进去,编译器立刻报错:error: statement not allowed in switch 或更模糊的 case label does not reduce to an integer constant。C++ 标准只允许 case 标签为编译期可确定的整型常量(int、char、enum、constexpr int 等),不支持 std::string 或 double。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
enum class配合static_cast转整型,比裸int更安全 - 字符串多分支?别硬套
switch,老实用if-else if或std::map查表 - 想用变量当 case?不行——哪怕它是
const int x = 5;,若未加constexpr,仍可能被拒绝(取决于上下文和编译器)
default 不写会出问题,但位置其实很自由
漏写 default 不报错,但一旦输入值没匹配任何 case,程序就静默跳过整个 switch 块——逻辑漏洞往往从这里开始。更隐蔽的问题是:有人以为 default 必须放在最后,其实它可以出现在任意 case 之间,甚至开头。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 不管有没有“兜底需求”,都显式写上
default:,哪怕只写break;或assert(false); - 把
default放最前?语法合法,但可读性差,容易让后续case被误认为属于它(尤其没加break时) - 如果所有
case已覆盖全部可能值(比如枚举全列),可用[[fallthrough]]消除编译器警告,但得手动加,不能靠编译器推断
case 穿透(fall-through)不是 bug,是特性,但极易误用
忘记写 break 导致多个 case 连续执行,是 C++ switch 最经典翻车点。错误现象通常是:输入 1,结果把 case 1、2、3 全跑了一遍,输出一堆不该出现的日志或状态变更。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 每个
case块末尾,除非明确需要穿透,否则必须加break; - C++17 起支持
[[fallthrough]]属性,写在有意穿透的case结尾,能提醒自己也告诉编译器:“这真不是漏写” - 某些编译器(如 GCC/Clang)加
-Wimplicit-fallthrough可警告潜在穿透,建议默认开启
switch 和 if-else 性能差异没你想的那么大
网上常说 “switch 编译成跳转表,比一长串 if-else 快”,但这只在 case 值密集且数量较多时成立。如果只有 3–4 个分支,或者 case 值跨度极大(比如 case 1:、case 1000:、case 999999:),编译器大概率生成的是二分查找或链式比较,性能和 if-else 差不多。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 别为“理论上更快”强行改写逻辑;优先选语义清晰的那个——值枚举用
switch,条件复杂(含函数调用、范围判断)用if-else - 真正卡性能?先 profile,再看汇编,别猜。现代编译器对两者优化都很激进
-
switch无法处理区间(比如x >= 10 && x ),这种场景硬套只会让代码又丑又错
最容易被忽略的其实是作用域:case 标签不构成作用域边界,所有 case 共享同一层作用域。想在某个 case 里定义变量又不污染别的 case?得手动加花括号 { ... }。










