结论:用&&做逻辑“并且”,用||做逻辑“或者”;&和|是按位运算符,非短路,含副作用时易引发bug;混合使用需加括号明确逻辑;重载&&或||会丢失短路特性,应避免。

直接说结论:用 && 做逻辑“并且”,用 || 做逻辑“或者”;别拿 & 和 | 替代它们,除非你明确要按位运算。
什么时候该用 && 而不是 &
当你想判断“两个条件都成立”且依赖短路行为时,必须用 &&。比如指针非空再解引用:
if (ptr != nullptr && ptr->valid()) { ... }
如果 ptr 是空指针,&& 会跳过右侧调用,避免崩溃;而 & 会强行执行 ptr->valid(),触发未定义行为。
-
&&左侧为false(即 0)时,右侧表达式完全不求值 -
&不管左侧结果如何,都会计算右侧,还按整数做按位与 - 对
bool类型,a & b和a && b结果相同,但副作用不同 - 写条件判断时,
&是隐蔽 bug 温床,尤其在含自增、函数调用等副作用的表达式里
为什么 || 在多条件检查中更安全
|| 的短路特性让它天然适合“任一满足即可”的场景,比如检查多个状态标志:
立即学习“C++免费学习笔记(深入)”;
if (is_error() || timeout_expired() || user_aborted()) { cleanup(); }
只要 is_error() 返回 true,后两个函数根本不会被调用——省开销,也避免副作用干扰。
-
||左侧为true(非 0)时,右侧表达式跳过求值 -
|会强制执行所有操作数,可能引发重复日志、资源误释放、甚至死锁 - 当操作数是函数调用时,
|等价于“不管有没有用,全执行一遍” - C++ 标准不保证
|对bool的求值顺序,而||明确从左到右
&& 和 || 的优先级和结合性影响实际写法
它们都是左结合,但 && 优先级高于 ||,这直接影响混合表达式的分组:
if (a || b && c) // 等价于 a || (b && c),不是 (a || b) && c
混用时容易误判逻辑,尤其在复杂条件中。
- 不要靠记忆优先级,该加括号就加:
if ((a || b) && c) -
!a && b || c实际是((!a) && b) || c,可读性差,建议拆成 if 链或变量临时存储 - 编译器不会报错,但人容易看错;调试时发现逻辑不对,第一反应应是检查括号
- 把
&&当“必须同时满足”,||当“满足其一即可”,然后按这个语义加括号,比背优先级可靠
真正容易被忽略的是:一旦重载了 operator&& 或 operator||,短路行为就彻底消失——两个操作数必然都被求值,且顺序不确定。这不是语法糖升级,而是逻辑模型切换。除非你在写 DSL 或底层库且清楚后果,否则永远别重载这两个运算符。


















