逻辑运算符三个——&&(且)\|\|(或)!(非)——把多个"真假"串成一个总判断。&& 像串联电路、\|\| 像并联电路。而短路求值让程序"够定结论就停",还能顺手挡住除零爆炸——这是本节的灵魂。
一、三个门口的规矩
&& \|\| 是二元运算符(两边各一个条件);! 是一元运算符(只管一个,写在前面)。
| 运算符 | 读作 | 规矩 | 生活比方 |
|---|---|---|---|
&& |
且(both) | 两个都真才真,有一个假就假 | 串联电路:断一处全断 |
\|\| |
或(either) | 有一个真就真,全假才假 | 并联电路:通一路就通 |
! |
非(not) | 真变假、假变真 | 反着说 |
拿"进门"打比方:&& 是两道门都要开才进得去;\|\| 是任一道门开着就能进;! 是把门的状态倒过来(开着说成关着)。
二、真值表(必背但不用死背)
| 甲 | 乙 | 甲 && 乙 | 甲 || 乙 | !甲 |
|---|---|---|---|---|
| 真 | 真 | 真 | 真 | 假 |
| 真 | 假 | 假 | 真 | 假 |
| 假 | 真 | 假 | 真 | 真 |
| 假 | 假 | 假 | 假 | 真 |
不用死背:&& 是"挑刺型"(找到假就判假);\|\| 是"给过型"(找到真就判真)。
三、操作数不是 bool 怎么办?——非 0 即真
回看 2.4.3 的铁律。逻辑运算符的操作数如果是数字,按"非 0 即真"处理:
cout << (5 && 3) << endl; // 1:5 真、3 真,且为真
cout << (5 && 0) << endl; // 0:0 即假
cout << (!7) << endl; // 0:7 真取非得假
所以 if (n) 就是 if (n != 0) 的简写——程序员圈约定俗成,两种都要认识。
四、灵魂:短路求值(short-circuit)
&& 一看左边是假,右边根本不算——因为"且"有假必假,右边真假都改变不了结论。同理,|| 一看左边是真,右边直接跳过。
这不只是省时间,还能防炸:
int n = 0;
if (n != 0 && 100 / n > 10) // 安全!
cout << "比值够大";
如果 n 是 0:左边 n != 0 为假 → 短路 → 右边 100 / n 根本不执行 → 程序不会除零崩溃。要是把条件反过来写 100 / n > 10 && n != 0,n=0 时先算除法——当场炸掉。"防炸条件写左边"是重要的惯用法。
同理防越界(第 7 章数组时你会再用一次):
if (i < 10 && arr[i] > 0) // i 越界时右边的取元素不会跑
五、教材实例01:求逻辑表达式的值
教材的实例 01 收在这篇。思路:人脑按优先级替编译器分步算。
#include <iostream>
using namespace std;
int main() {
int a = 5, b = 3, c = 8;
// 第 1 步:先算三个比较(优先级高于逻辑)
// a > b -> 5 > 3 -> 1(真)
// b < c -> 3 < 8 -> 1(真)
// a == c -> 5 == 8 -> 0(假)
cout << ((a > b) && (b < c)) << endl; // 1 && 1 = 1
cout << ((a > b) || (a == c)) << endl; // 1 || 0 = 1
cout << !(a == c) << endl; // !0 = 1
cout << ((a > b) && !(b > c)) << endl; // 1 && !0 = 1 && 1 = 1
return 0;
}
看到什么算成功:输出 1 1 1 1。解题套路固定三步:比较先变真假 → 逻辑门逐层合并 → 非 ! 最后翻转。试着在纸上把每一步写出来,跟程序输出对照。
30 秒实验:把 b 改成 0,看第三行 !(a == c)——不受影响;再看第一行 (a > b) && (b < c)——还是 1。然后把 a 改成 2:第一行变 0(一真一假),体会"挑刺型"。
六、常见误区
- "
a < b < c能判断 b 在 a 和 c 之间"——不能! 它先算a < b得 0 或 1,再拿 0/1 跟c比。判"b 在中间"要写a < b && b < c。这是数学思维直接搬进代码的经典错误。 - "
&&和||一定要两边都算"——不一定,短路求值够定结论就停。 - "写成
&\|(单个)效果一样"——单个的&\|是位运算符(3.1.5),不走短路、干的是二进制的活。逻辑判断必须写双写的。 - "条件越长越安全"——恰恰相反,短路链条里放对顺序(防炸的放左)才是安全。
自测四问(点开对答案)
1. `3 > 2 && 2 > 5` 的值?——`0`(`&&` 挑刺:右边假,整体假)。 2. `3 > 2 || 2 > 5` 的值?——`1`(`||` 给过:左边真,短路结束)。 3. `n = 0` 时 `(n != 0) && (100/n > 1)` 会崩溃吗?——不会,左边假触发短路,除法不执行。 4. 怎么正确表达"x 在 1 到 100 之间"?——`x >= 1 && x <= 100`,不能写 `1 <= x <= 100`。- ☐ 3.1.4 赋值运算符(下一节)