if / switch 分支
更新时间:2026-08-27。本文是
languages/cpp/主题入门层第 8 篇。上一篇把 stringstream 玩明白了,这一篇回到程序的基本盘:分支。C++ 的if/switch和 C 长得几乎一样,但多了真正的bool类型、C++17 的初始化语句这些新玩法;switch的break老坑也还在。
本文要回答的问题
- C++ 的
if和 C 的if到底差在哪? switch有什么必须记住的规则?- C++17 给分支带来了什么"顺手"的新东西?
一、if / else:语法照旧,条件更严
C++ 的 if 长得跟 C 一模一样:
int score = 85;
if (score >= 90) {
std::cout << "优秀\n";
} else if (score >= 60) {
std::cout << "及格\n";
} else {
std::cout << "不及格\n";
}else if 随便链、else 可省、花括号别省——这些规矩和 C 完全一致。真正的差别在条件表达式上:
- C 里"非 0 即真",
if (3)、if (ptr)都合法; - C++ 里条件必须是能转换成
bool的东西。数字、指针一样能隐式转bool,所以if (ptr)照样能写; - 但 C++ 多了一个真正的
bool类型,还能写出更直白的if (found)——found本来就是bool变量,这行读起来比if (found != 0)舒服得多。
if (x = 5) 这个经典错别字在 C++ 里依然是错的:x = 5 是赋值表达式,值是非 0 的 int,照样转成 true,恒真。-Wall 也会警告。把 == 写对、常量放左边,老规矩一条不落。
二、switch:break 的老坑还在
switch 结构也和 C 一样:
switch (grade) {
case 'A':
std::cout << "优秀\n";
break;
case 'B':
std::cout << "良好\n";
break;
default:
std::cout << "未知等级\n";
break;
}三个要点,都是老熟人:
- 忘写
break会掉进下一个 case——这叫"贯穿"(fall-through)。C 的老坑,C++ 原样继承,编译器不会替你拦; switch的判断值在 C++ 里必须是整数、枚举或能转成这些的类型(C++17 起std::string还是不行,字符串多分支请用 if-else 链);default可省,但写上更稳——像上面那样兜个底,万一遇到没枚举到的值也不会静默路过。
有人嫌 switch 规矩多,宁可全用 if-else。说实话小项目怎么都行,但多分支用 switch 有个实打实的好处:编译器可能把它编译成跳转表(jump table),比一串 cmp 比较跳转快。这层细节到 L4 分支预测那边再展开,这里先记住"分支多的时候 switch 有性能优势"。
三、C++17 新玩法:初始化语句
if 和 switch 的括号里可以先初始化一个变量再判断:
if (int n = read_value(); n > 0) {
std::cout << "正数: " << n << "\n";
}这个 n 的作用域被限制在 if-else 块内,外面用不了。好处是"为判断而生的临时变量"不会泄漏到外层,读完即弃,代码也更紧凑。上面的写法等价于:
int n = read_value();
if (n > 0) {
std::cout << "正数: " << n << "\n";
}switch 同理:
switch (int code = get_code(); code) {
case 0:
// ...
break;
}这个特性在 C 里没有,是 C++17 的加分项。现在看不觉得多惊艳,等你后面做资源获取、错误码判断时会发现它省掉一堆临时变量名。
四、和 C 对比
| 对比项 | C | C++ |
|---|---|---|
| 条件类型 | 任意非 0 即真 | 必须可转 bool,多真 bool 类型 |
if (x = 5) | 错误,-Wall 警告 | 同样错误,同样警告 |
| 悬空 else | 有(else 跟最近 if) | 一样,靠花括号防御 |
switch 判断类型 | 整数 / 枚举 | 整数 / 枚举(string 不行) |
break 贯穿 | 要小心 | 一样要小心 |
| 初始化语句 | 无 | C++17:if (int n = f(); n) |
| 三目运算符 | cond ? a : b | 一样,if 表达式见高手层 |
五、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
if (x = 5) | 恒真 | 用 ==,开 -Wall |
| 省略花括号 | 逻辑归属错乱 | 永远写 {} |
| 悬空 else | else 配错 if | 花括号 + 缩进一致 |
| switch 忘 break | 贯穿到下一个 case | 每个 case 检查 break |
| 三目嵌套 | 读不懂 | 拆成 if-else |
| 拿 string 做 switch | 编译错误 | 用 if-else 链 |
六、与本站主线衔接
- 分支在汇编里是
cmp+jne/jle跳转,条件分支预测失败是性能热点,见 L4 分支预测; switch的跳转表实现与分支优化,见 编译优化行为(C 篇,原理通用);- C 的
if-else/switch基础讲解,见 C if-else 分支 与 C switch-case; - 下一篇进入循环:
for与while,范围 for 是 C++ 最常用的遍历写法。
一句话总结
C++ 的 if / switch 语法沿用 C,条件改成了"能转 bool 就行"并多了真 bool 类型;= 当 ==、悬空 else、switch 忘 break 三大坑一个不少,C++17 的 if (int n = f(); n) 初始化语句是加分项;多分支优先 switch,编译器有跳转表的优化空间。
上一篇:stringstream:字符串当流用 下一篇:循环:for / while