4 位运算基础

正在加载视频播放器…

GESP C++ 三级:位运算精讲

核心目标:掌握六种位运算符 & | ^ ~ << >> 的规则与运算方法,理解补码下的位运算,能熟练求值、判断奇偶、交换变量、取位/设位/清位、统计 1 的个数。
位运算直接操作二进制补码;& 同 1 为 1,| 有 1 为 1,^ 不同为 1,~ 取反,<< 左移乘 2 的幂,>> 右移除 2 的幂。

一、位运算基础

1. 什么是位运算

位运算是直接对整数的二进制补码逐位进行操作的运算。计算机中所有整数都以补码存储,因此位运算对正数和负数都适用。

2. 补码回顾

  • 正数:原码 = 反码 = 补码。
  • 负数:补码 = 反码 + 1。
  • 8 位补码范围:-128 ~ 127。
  • 位运算时,先写出操作数的补码,逐位运算,结果再按补码解释。

3. 六种位运算符总览

运算符 名称 运算规则 优先级
~ 按位非 每一位取反,0 变 1,1 变 0 高
<< 左移 所有位左移,右边补 0 中
>> 右移 所有位右移,左边补符号位
& 按位与 两个位都为 1 时结果为 1 低
^ 按位异或 两个位不同时结果为 1
` 按位或 两个位有一个为 1 时结果为 1

注意:位运算符优先级低于算术运算符,不确定时加括号。& 和 | 不要与逻辑运算符 &&、|| 混淆。

二、按位与 &

1. 规则

两个相应位都为 1 时,结果位才为 1,否则为 0。

  1010 1100
& 1100 1010
──────────
  1000 1000

2. 示例

int a = 5;   // 0101
int b = 3;   // 0011
cout << (a & b) << endl;   // 0001 = 1

3. 常见用途

用途 写法 说明
判断奇偶 n & 1 结果为 1 是奇数,0 是偶数
取某一位 (n >> k) & 1 取第 k 位(从 0 开始)
清零某一位 n & ~(1 << k) 第 k 位变 0
保留某些位 n & mask mask(掩码) 中为 1 的位保留

(mask掩码:用一串二进制数字当 “遮罩”,只保留想要的二进制位,屏蔽其他位。)

三、按位或 |

1. 规则

两个相应位中有一个为 1,结果位就为 1。

  1010 1100
| 1100 1010
──────────
  1110 1110

2. 示例

int a = 5;   // 0101
int b = 3;   // 0011
cout << (a | b) << endl;   // 0111 = 7

3. 常见用途

用途 写法 说明
设置某一位为 1 `n (1 << k)`

四、按位异或 ^

1. 规则

两个相应位不同时结果为 1,相同时为 0。

  1010 1100
^ 1100 1010
──────────
  0110 0110

2. 示例

int a = 5;   // 0101
int b = 3;   // 0011
cout << (a ^ b) << endl;   // 0110 = 6

3. 常见用途

用途 写法 说明
交换两个变量 a ^= b; b ^= a; a ^= b; 无需临时变量
判断相等 a ^ b == 0 相等则结果为 0
翻转某一位 n ^ (1 << k) 第 k 位取反
找只出现一次的数 全部异或 其他数出现两次

五、按位非 ~

1. 规则

每一位取反,0 变 1,1 变 0。

~ 0000 0101
──────────
  1111 1010

2. 示例

int a = 5;   // 0000 0101
cout << ~a << endl;   // 1111 1010,补码解释为 -6

3. 重要结论

对于整数 n,~n = -n - 1。

~5 == -6
~0 == -1
~-1 == 0

4. 常见用途

  • 配合 & 清零某一位:n & ~(1 << k)。
  • 构造掩码。

六、左移 <<

1. 规则

所有位向左移动指定的位数,右边空出的位补 0。

0000 0101 << 1
──────────────
0000 1010

2. 示例

int a = 5;
cout << (a << 1) << endl;   // 10
cout << (a << 2) << endl;   // 20
cout << (a << 3) << endl;   // 40

3. 数学意义

左移 n 位相当于乘以 2n2^n。

a << 1  ==  a * 2
a << 2  ==  a * 4
a << 3  ==  a * 8

4. 常见用途

  • 快速乘以 2 的幂。
  • 构造 1 << k 表示第 k 位为 1 的掩码。
  • 位运算题目中用于取位、设位。

5. 注意

左移可能导致溢出,超出类型范围时结果不确定。

七、右移 >>

1. 规则

所有位向右移动指定的位数。

0000 1010 >> 1
──────────────
0000 0101

2. 示例

int a = 20;
cout << (a >> 1) << endl;   // 10
cout << (a >> 2) << endl;   // 5

3. 数学意义

右移 n 位相当于除以 2n2^n,向下取整。

a >> 1  ==  a / 2
a >> 2  ==  a / 4
a >> 3  ==  a / 8

4. 负数右移

负数右移是算术右移,左边补符号位(1),结果向下取整。

-5 >> 1   // -3,不是 -2

因为 -5 的补码右移一位后,结果补码解释为 -3。

5. 注意

  • 右移不改变符号位。
  • 对负数右移要小心,不要简单理解为除以 2。

八、位运算优先级

从高到低:

~ 
<<  >>
&
^
|

但整体上,位运算符优先级低于算术运算符。例如:

1 << 2 + 3   // 先算 2+3=5,再算 1<<5 = 32
(1 << 2) + 3 // 先算 1<<2=4,再加 3 = 7

建议:不确定时加括号。

九、位运算与逻辑运算的区别

位运算 逻辑运算 区别
& && & 逐位与,&& 整体逻辑与
`
~ ! ~ 逐位取反,! 逻辑非
^ 无 异或,不同为 1

示例:

5 & 3    // 1
5 && 3   // true(非零即真)
5 | 3    // 7
5 || 3   // true

十、常见应用汇总

需求 写法 说明
判断奇偶 n & 1 1 奇,0 偶
乘以 2 的 n 次方 n << n 如 n << 3 等于 n * 8
除以 2 的 n 次方 n >> n 如 n >> 2 等于 n / 4
交换两个变量 a ^= b; b ^= a; a ^= b; 无需临时变量
取第 k 位 (n >> k) & 1 从 0 开始计数
设置第 k 位为 1 `n (1 << k)`
清零第 k 位 n & ~(1 << k)
翻转第 k 位 n ^ (1 << k)
统计二进制中 1 的个数 循环 n & 1 后 n >>= 1 或用 __builtin_popcount
判断是否为 2 的幂 n > 0 && (n & (n - 1)) == 0 2 的幂只有一位为 1

十一、GESP 三级真题示例

1. 2025年6月 第8题

二进制数 1010 | 1100 的结果是( )
A) 1000 B) 1110 C) 0110 D) 1100
答案:B
解析:逐位或,1010 | 1100 = 1110。

2. 2025年6月 第9题

以下哪个位运算可以交换两个变量的值,且不需要临时变量?( )
A) & B) | C) ^ D) ~
答案:C
解析:a ^= b; b ^= a; a ^= b; 可交换。

3. 2026年3月 第8题

0000 1111 << 3 的结果是( )
A) 0111 1000 B) 0001 1110 C) 1000 0111 D) 1111 0000
答案:A
解析:0000 1111 左移 3 位,右边补 0,得 0111 1000。

4. 三级样题

一个 int 类型的值乘以 8,等价于( )
A) << 2 B) << 3 C) >> 2 D) >> 3
答案:B
解析:乘以 8 等于乘以 232^3,即左移 3 位。

十二、易错点

  1. 位运算基于补码,负数参与运算时先转补码。
  2. ~n = -n - 1,不要忘记负数结果。
  3. << 左移可能溢出,超出类型范围结果不确定。
  4. >> 对负数是算术右移,向下取整,不是简单丢弃。
  5. ^ 是异或,不是幂运算。
  6. 不要混淆 & 和 &&、| 和 ||。
  7. 位运算符优先级低于算术运算符,建议加括号。
  8. 左移位数不能为负数,也不能超过类型位数。
  9. 交换变量时三个异或语句顺序不能错。
  10. 统计 1 的个数时,注意负数补码中 1 的个数较多。

十三、速查表

运算 规则 示例
a & b 同 1 为 1 5 & 3 = 1
`a b` 有 1 为 1
a ^ b 不同为 1 5 ^ 3 = 6
~a 取反 ~5 = -6
a << n 左移 n 位,乘 2n2^n 5 << 1 = 10
a >> n 右移 n 位,除 2n2^n 20 >> 2 = 5
n & 1 判断奇偶 1 奇,0 偶
a ^= b; b ^= a; a ^= b; 交换变量 无需临时变量
(n >> k) & 1 取第 k 位 从 0 开始
`n (1 << k)` 设置第 k 位为 1
n & ~(1 << k) 清零第 k 位
n ^ (1 << k) 翻转第 k 位

十四、总结

位运算是 GESP 三级的核心考点。

  1. 位运算直接操作二进制补码。
  2. & 同 1 为 1,| 有 1 为 1,^ 不同为 1,~ 取反。
  3. << n 相当于乘以 2n2^n,>> n 相当于除以 2n2^n。
  4. 负数右移是算术右移,向下取整。
  5. ~n = -n - 1。
  6. n & 1 判断奇偶。
  7. 异或可以交换两个变量。
  8. (n >> k) & 1 取第 k 位。
  9. n | (1 << k) 设置位,n & ~(1 << k) 清零位。
  10. 位运算优先级低于算术运算,不确定时加括号。

复习建议:重点练习位运算表达式求值、程序阅读写结果、交换变量、判断奇偶、取位/设位/清位、统计 1 的个数。考试中先写出补码,再逐位运算,最后按补码解释结果。多练真题中的选择题和程序阅读题,注意负数右移和优先级陷阱。