本讲定位:三级”三块连讲”(进制 → 编码 → 位运算)的收官一讲,也是三级客观题最稳定的得分区。官方大纲三级知识块 3 把六个运算符全部点名:
&、|、~、^、<<、>>。这一讲的知识量不大——六张真值表加起来不到十行——但每一个运算符都自带一个坑:~5不是 5、-8 >> 1不是 $-4$ 那么显然、a & 1 == 0根本不是你想的意思。本讲的时间要全部花在坑上,不是花在定义上。对应官方大纲:三级知识块 3「位运算」——与(
&)、或(|)、非(~)、异或(^)、左移(<<)、右移(>>)。前置知识:三级第 01 讲(进制转换)、三级第 02 讲(原码反码补码——
~和负数右移完全依赖补码,不懂补码本讲无法进行)、一级第 06 讲(关系运算与逻辑运算——本讲要和它逐条对比)。代码说明:本讲所有代码均已用 g++ 11.5(
-std=c++11)编译运行验证,输出结果即为文中标注结果。
第一道(单选):
表达式
12 & 10的值是( ) A. 8 B. 14 C. 2 D. 22
第二道(单选):
在 C++ 中,
~5的值是( ) A. 5 B. $-5$ C. $-6$ D. 250
第三道(判断):
对于任意非负整数
n,表达式n << 2的值等于n * 4。( )
答案:第一道选 A,第二道选 C,第三道正确(在不溢出的前提下)。
- $12 = $
1100,$10 = $1010,按位与得1000= 8。~5 = -6。这不是巧合,有一条可以直接背的公式:$\sim n = -n-1$。理解它需要补码(第 02 讲)。- 左移 $k$ 位就是乘 $2^k$,
n << 2= $n \times 4$。这是位运算最常用的实战价值。
这三道题分别对应本讲三块:双目位运算的手算、~ 与补码的联动、移位与乘除 2 的幂。
我们之前学的所有运算都是把整数当一个数来算(+、-、*、/、%)。
位运算不一样:它把整数看成一串二进制位,然后一位一位地处理。
$$ 12\ \&\ 10 \quad\Longrightarrow\quad \begin{matrix} & 1&1&0&0 \\ \&\ & 1&0&1&0 \\ \hline & 1&0&0&0\end{matrix} \quad = 8 $$
六个运算符分成两类:
| 类别 | 运算符 | 特点 |
|---|---|---|
| 逐位对齐(双目) | &(与)、` |
(或)、^`(异或) |
| 整体搬动 / 翻转 | ~(取反,单目)、<<(左移)、>>(右移) |
作用在整个二进制串上 |
⚠️ 手算位运算的唯一正确姿势:先把两个数写成二进制,右端对齐,位数补齐,再逐位算。「口算」在这里没有捷径,尤其是三个数以上的表达式。考场上一定要在卷子边上写二进制,凭感觉必错。