1.1.5 逻辑运算
本节导学
这一节不是单纯记几个符号,而是训练你把程序中的条件表达式“拆成可计算的步骤”。字幕里先把运算分成三类:加减乘除属于算术运算,比较大小或相等属于关系运算,判断真假值的组合属于逻辑运算。软件设计师考试很少单独考“逻辑电路”,但会把这些规则藏在条件判断、表达式求值和程序阅读题里。
学习时要抓住一条主线:算术表达式先得到数值,关系表达式把数值比较成真/假,逻辑表达式再把多个真/假组合成最终结论。如果中间把 = 与 ==、& 与 &&、| 与 || 混在一起,后面的推理通常都会错。
从普通计算到真假判断
程序里的“运算”可以按结果类型来理解:
| 类型 | 典型符号 | 结果是什么 | 在程序中的作用 |
|---|---|---|---|
| 算术运算 | +、-、*、/、% | 数值 | 先算出可比较的量,例如 a + b * c |
| 关系运算 | <、>、<=、>=、==、!= | 真/假 | 把数值比较转成条件,例如 score >= 60 |
| 逻辑运算 | !、&&、` | 、^` | |
| 位运算 | &、` | 、^、~、<<、>>` | 二进制位模式 |
关系运算符里,<= 与 >= 在程序中通常写成两个字符,不是数学里连写的一个符号。相等比较用 ==,单个 = 在很多语言里表示赋值。这个区别很基础,却是表达式题最容易被设置陷阱的地方:a == b 是问“是否相等”,a = b 是把 b 的值写入 a。
关系运算内部也有优先级。大小比较 <、>、<=、>= 通常高于相等比较 ==、!=。在更大的表达式中,算术运算又高于关系运算,所以 a + b > c 会先计算 a + b,再与 c 比较。
逻辑变量与二进制直觉
逻辑运算处理的是真假值。为了便于计算,可以把假看成 0,把真看成 1。这与二进制电信号的直觉一致:低/断可以对应 0,高/通可以对应 1。课程提到逻辑表达式可以进一步映射到逻辑电路,不过软件设计师上午题更常考的是表达式求值,而不是要求你画门电路。
四种核心逻辑运算如下:
| 运算 | 常见写法 | 判定规则 | 电路直觉 | 最容易错的地方 |
|---|---|---|---|---|
| 非 | !A、NOT A | 真变假,假变真 | 反相器 | ! 的优先级很高,常先算 |
| 与 | A && B、A AND B | 两边同时为真才真 | 串联电路,任一处断则不通 | 看到一个假即可确定整体为假 |
| 或 | `A | B、A OR B` | 两边同时为假才假 | |
| 异或 | A ^ B、A XOR B | 两边不同为真,相同为假 | “是否不同”的检测 | 不要把异或当成普通或 |
真值表是最稳的判断工具。遇到陌生表达式时,把参与运算的逻辑变量列成 0/1,再逐列计算,通常比凭感觉快。
| A | B | !A | A OR B | A AND B | A XOR B |
|---|---|---|---|---|---|
| 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 1 | 1 | 0 |
异或在考试里常被用来考“相同为 0,不同为 1”。它的含义不是“只要有一个为真就为真”,而是“恰好不同才为真”。所以 1 XOR 1 = 0,0 XOR 1 = 1。
优先级:先决定谁先算
表达式题的难点经常不是某个运算规则本身,而是多个运算混在一起时的求值顺序。课程里强调了两组顺序:
| 层级 | 运算 | 说明 |
|---|---|---|
| 1 | ! | 逻辑非优先级很高,通常先取反 |
| 2 | 算术运算 | 先乘除取余,再加减 |
| 3 | 大小关系 | <、>、<=、>= |
| 4 | 相等关系 | ==、!= |
| 5 | 逻辑与 | &&,两边都真才真 |
| 6 | 逻辑或 | ` |
| 7 | 赋值 | = 通常最后发生 |
括号永远优先。考试中如果表达式较长,最可靠的方法是在草稿纸上给每一层加括号。例如:
a + b * c > d && !flag可以拆成:
((a + (b * c)) > d) && (!flag)这一步做完,后面只是机械计算。
短路求值:结果已定就不再算
多数程序语言对 && 和 || 采用短路求值:
| 表达式 | 左边情况 | 是否继续算右边 | 原因 |
|---|---|---|---|
A && B | A 为假 | 不算 B | 与运算只要一边假,整体必假 |
A && B | A 为真 | 继续算 B | 还需要看 B 是否也真 |
| `A | B` | A 为真 | |
| `A | B` | A 为假 |
短路不是课程字幕的主体,但它和本节知识自然相连,软考程序题常用它考“右侧表达式有没有执行”。如果右侧包含 i++、函数调用或赋值,先判断短路条件,再判断变量是否改变。
位运算不要和逻辑运算混用
字幕这一节主要讲逻辑运算,但备考时必须把位运算顺手区分出来。&& 和 || 的对象是“真假”;& 和 | 的对象是“每一个二进制位”。例如:
1010 & 0110 = 0010
1010 | 0110 = 1110掩码题的本质是“保留想看的位,屏蔽不关心的位”。判断低 4 位是否全为 0:
(A & 0x000F) == 0其中 0x000F 的低 4 位为 1,其余位为 0。按位与以后,只剩下 A 的低 4 位;如果结果为 0,说明低 4 位全是 0。判断第 k 位是否为 1,常见写法是:
(A & (1 << k)) != 0做题路线
- 先标记每个符号属于算术、关系、逻辑还是位运算。
- 把
=与==、&与&&、|与||分清楚。 - 按优先级加括号,必要时先写出每一步的中间结果。
- 把关系表达式化成真/假,再套逻辑运算真值表。
- 遇到
&&、||且右侧有副作用时,先检查是否短路。
🧪 例题(按难度)
简单(3题)
例题1(优先级)
例题2(短路 + 赋值副作用)
设 a=1, b=2, m=1, n=1,表达式:
(a > b) && (m = 0)
求最终 m 的值。
例题3(位运算掩码)
字长 16 位,A=0x005A。判断 A 的低 4 位是否全为 0,应使用哪个条件最合适?
困难(1题)
int a = 0, b = 0;
if (a != 0 && (++b > 0)) {
// ...
}执行后 b 的值是:
📚 本课小结
- 关系运算先于逻辑运算;赋值通常最后
- 逻辑运算:
!>&&>|| - 短路会影响“后半段是否执行”
- 位运算常配合掩码做“某几位”判断