if语句括号内禁用赋值表达式,须用==比较;浮点数比较应使用std::abs(a-b)<ε;嵌套if需用{}明确分支;条件中避免副作用和耗时操作;容器判空用.empty()而非.size();复杂逻辑应封装为命名函数。

if 语句括号里不能写赋值表达式
很多人一上来就写 if (x = 5),结果逻辑永远走 true 分支——这不是判断,是赋值。C++ 中 = 是赋值运算符,返回被赋的值(这里是 5),非零即真。
正确写法必须用 ==: if (x == 5)。编译器通常会警告这种误用,但不是所有情况都报,尤其当左边是引用或重载了 = 时更隐蔽。
- 习惯性开启编译器警告:
-Wall -Wextra,能捕获大部分这类问题 - 把常量放左边(如
if (5 == x))可让编译器直接报错,避免手滑写成= - 涉及浮点数比较时,
==不可靠,得用std::abs(a - b)
else if 和 else 的匹配只看最近的未配对 if
缩进不等于逻辑嵌套。C++ 没有“作用域级”的 else 匹配,else 总是绑定到它前面最近的那个、还没被 else 占用的 if 上。
比如这段代码:
立即学习“C++免费学习笔记(深入)”;
if (a > 0)
if (b > 0)
std::cout << "both positive";
else
std::cout << "a <= 0";看起来像在说“如果 a>0 且 b>0…否则 aelse 是和内层 if (b > 0) 配对的——因为它是离它最近的未配对 if。
- 用大括号
{}显式包裹每个分支,哪怕只有一行,彻底消除歧义 - 别依赖缩进判断逻辑流向,IDE 的自动缩进有时会误导人
- 复杂多条件优先考虑
switch或查表(如std::map+ lambda),比堆砌else if更易读、易维护
条件表达式里避免副作用和长计算
if 条件求值是短路的:一旦能确定真假,后续子表达式就不执行。这既是优化,也是陷阱。
比如 if (ptr != nullptr && ptr->valid()) 安全;但 if (func1() && func2()) 中,如果 func1() 有副作用(比如修改全局状态),而你又依赖 func2() 一定执行,那就错了。
- 把有副作用的调用提前到
if外,明确其执行时机 - 耗时操作(如文件读取、网络请求)别塞进条件里,既难调试,又破坏单一职责
- 需要两个函数都执行再判断结果?改用临时变量:
auto r1 = func1(); auto r2 = func2(); if (r1 && r2)
bool 类型转换容易隐式失真
C++ 允许很多类型隐式转为 bool,比如指针、整数、甚至自定义类(如果有 operator bool())。看着方便,实则危险。
比如 if (vec.size()) 在空容器时为 false,没问题;但 if (vec.capacity()) 就可能误判——空 vector 的 capacity 可能非零(预留空间),结果逻辑走偏。
- 容器判空请用
.empty(),而不是.size() != 0或直接用.size() - 指针判空用
if (ptr)没问题,但注意std::unique_ptr和std::shared_ptr也支持该写法 - 自定义类型若提供
explicit operator bool(),就能阻止意外的算术上下文转换,强制显式调用
最麻烦的往往不是语法写错,而是条件本身语义模糊——比如“用户已登录”这个判断,背后可能是 token 有效期、网络连通性、服务端状态多个维度,这时候 if 里塞一堆逻辑不如拆成独立函数,名字就叫 is_user_authenticated()。









