c++中switch默认穿透执行,case后不加break会顺序执行后续case;string不可用因非整型,需if-else或哈希转整数;default必须存在以保障安全;case值须为编译期常量。

switch 里为什么 case 后面不加 break 就会“掉到下一个 case”
因为 switch 在 C++ 中默认是“穿透式执行”——一旦匹配到某个 case,就从那里开始顺序往下跑,直到遇到 break 或函数结束。这不是 bug,是语言设计,但新手常误以为它会自动跳出。
- 没写
break时,case 1:和case 2:的代码会连续执行,哪怕输入是1 - 空
case(比如用于归类多个值)可以故意不加break,但必须加注释说明意图,否则后期维护极易出错 - Clang/GCC 开启
-Wimplicit-fallthrough能警告这种行为;C++17 起可用[[fallthrough]];显式标记“此处有意穿透”
char、int 能用 switch,string 为什么不行
switch 的条件表达式必须是整型或可隐式转为整型的类型(如 enum、char、short),而 std::string 是类对象,没有编译期确定的整型值,所以直接写 switch(s) 会报错:error: switch quantity not an integer。
- 想对字符串分支,得改用
if-else if链,或 C++14 起用std::map<:string std::function>></:string>模拟跳转表 - 如果字符串是固定枚举名(如 "start", "stop", "pause"),可先用
constexpr哈希函数转成整数(如consteval实现 FNV-1a),再进switch,但需确保哈希无碰撞 -
char可以用,是因为它本质是小整数;unsigned char同样合法,但signed char在某些平台可能因符号扩展导致意外匹配
default 分支不是可选的,而是安全底线
即使你“确定”所有输入都在已列 case 中,也必须写 default——否则当输入值超出预期(比如枚举新增了成员、读取外部数据出错、内存损坏),程序行为未定义,可能静默跳过逻辑或崩溃。
-
default不仅处理“漏掉的值”,更是防御性编程:可以加日志、断言或抛异常,例如default: throw std::runtime_error("unexpected enum value: " + std::to_string(x)); - 如果真想“什么也不做”,至少写
default: break;,避免被误认为遗漏 - 某些静态分析工具(如 PC-lint、clang-tidy)会警告缺失
default,尤其在switch枚举类型时
case 标签必须是常量表达式,不能是变量或函数调用
case 后的值必须在编译期能确定,所以 case i:(i 是变量)、case rand()%3:、case MyClass::kValue:(若 kValue 非 static constexpr)都会编译失败,错误信息类似:error: case label does not reduce to an integer constant。
立即学习“C++免费学习笔记(深入)”;
- 枚举成员可用,但需确保是
enum class或传统enum的显式整型值;C++11 起推荐用enum class避免隐式转换污染作用域 - 宏定义的值(如
#define CMD_OPEN 1)可以,但不如constexpr int CMD_OPEN = 1;类型安全 - 数组下标、
sizeof结果、字面量(42,'a',0xFF)都合法;但std::numeric_limits<int>::max()</int>不行,除非用constexpr版本
最麻烦的地方其实是:错误常在运行时才暴露——比如你忘了给某个 enum 成员赋值,它变成 0,又恰好和另一个 case 冲突,编译器不一定报错,但逻辑就乱了。











