本讲定位:CSP-J 初赛系列的”升级”讲。七年真题统计(见
cspj-exam-analysis-2019-2025.md):2021、2022 连续两年阅读程序第一段整段考位运算(popcount/lowbit、位交织 Morton 码,各 10.5 分),2025 选择题位运算占 4 分;这个考点在阅读程序里已”欠账”三年,2026 回归概率高——所以本讲按能手动模拟整段程序的强度练,不是背几条口诀就走。本讲直接建立在第 02 讲的补码之上:所有位运算都发生在补码位上,负数参与时的行为(2021 判断题陷阱)必须用”取反加一”推导,两讲连着学。逻辑运算部分覆盖短路求值(2025 完善程序原题)与真值表(2020/2025 选择题)。
前置知识:第 02 讲(二进制与补码)。
适合对象:CSP-J 初赛。标注 ⭐ 的小节为进阶内容,第一遍学习可以跳过。
位运算把整数当作一排二进制位,每一位独立参与运算。总表(以 8 位举例,x = 0b1100,即 12):
| 运算符 | 名称 | 规则(对每一位) | 例 |
|---|---|---|---|
& |
按位与 | 两个都是 1 才得 1 | 12 & 10 = 1100 & 1010 = 1000 = 8 |
| ` | ` | 按位或 | 有一个 1 就得 1 |
^ |
按位异或 | 不同得 1,相同得 0 | 12 ^ 10 = 0110 = 6 |
~ |
按位取反 | 0 变 1、1 变 0(全部位) | ~12 = $-13$ |
<< |
左移 | 整体左挪,右边补 0 | 3 << 2 = 12 |
>> |
右移 | 整体右挪,挤掉最低位 | 12 >> 2 = 3 |
手算的标准动作:把两个数上下对齐写成二进制,逐位套规则。阅读程序遇到位运算,草稿纸上列位就是”列变量表”的位运算版。
~ 为什么是 $-13$:补码在场~x 翻转全部 32 位。翻转后的位模式按补码解读,恰好满足 ~x + x = 全 1 = -1(第 02 讲:全 1 是 $-1$),所以
$$ \sim x = -x - 1 $$
~12 = -13、~0 = -1。反过来 $-x = \sim x + 1$——这就是第 02 讲”取反加一”口诀的代数形式,第 3.3 节推导 lowbit 全靠它。
== 还低&、|、^ 的优先级低于比较运算符。于是:
if (x & 1 == 0) // 实际是 x & (1 == 0),即 x & 0,永远为假!
if ((x & 1) == 0) // 想表达的意思:x 是偶数
这是位运算判断题的高频冷枪。防御规矩:位运算参与比较,一律加括号。(<< 的优先级也低于 +:1 << 2 + 3 是 1 << 5 = 32。记不住就加括号。)
^ 不是乘方C++ 里 2^10 的值是 8——^ 是异或(10 ^ 1010 = 1000),不是幂。求幂要用循环或 pow。选择题拿 2^3、10^2 做过手脚,见到指数形状的 ^ 先冷静。
左移一位等于乘 2,右移一位等于除以 2: