一、字节与位的概念
在计算机中,数据以二进制形式存储。一个二进制位(bit)是最小的数据单位,只能表示 0 或 1。
一个字节(byte)由 8 个二进制位组成,是大多数高级语言处理数据的最小寻址单位。
一般高级语言只能以字节为单位处理数据,但 C 语言和 C++ 提供了对数据进行按二进制位处理的能力。这一特性使得 C++ 在底层开发、嵌入式系统、驱动程序等领域具有优势。
二、C++ 中的位运算符
C++ 提供了 6 个位运算符,用于对整型数据的二进制位进行直接操作:
| 运算符 | 名称 | 说明 |
|---|---|---|
| & | 按位与 | 两个操作数对应位都为 1 时,结果位为 1,否则为 0 |
| | | 按位或 | 两个操作数对应位有一个为 1 时,结果位为 1,否则为 0 |
| ^ | 按位异或 | 两个操作数对应位不同时,结果位为 1,相同时为 0 |
| ~ | 按位取反 | 一元运算符,将操作数每一位取反(0 变 1,1 变 0) |
| << | 左移 | 将操作数的二进制位全部左移若干位,高位丢弃,低位补 0 |
| >> | 右移 | 将操作数的二进制位全部右移若干位,低位丢弃,高位补符号位(有符号数)或补 0(无符号数) |
三、位运算符的运算规则
1. 按位与(&)
| 位a | 位b | a & b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
用途:将指定位清零、取指定位的值、判断奇偶(n & 1)。
2. 按位或(|)
| 位a | 位b | a | b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
用途:将指定位置 1。
3. 按位异或(^)
| 位a | 位b | a ^ b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
用途:翻转指定位、不使用临时变量交换两个数、数据简单加密。
4. 按位取反(~)
一元运算符,将每一位取反。
| 位a | ~a |
|---|---|
| 0 | 1 |
| 1 | 0 |
5. 左移(<<)
将操作数的二进制位向左移动指定的位数,右边空出的位补 0。
例如:5 << 2
5 的二进制为 00000101,左移 2 位后变为 00010100,即十进制的 20。
左移 n 位相当于乘以 2 的 n 次方(在不溢出的情况下)。
6. 右移(>>)
将操作数的二进制位向右移动指定的位数,右边超出的位丢弃。对于左边空出的位:
- 无符号数:补 0
- 有符号数:补符号位(正数补 0,负数补 1)
例如:20 >> 2
20 的二进制为 00010100,右移 2 位后变为 00000101,即十进制的 5。
右移 n 位相当于除以 2 的 n 次方(向下取整)。
四、代码示例
以下代码演示了各类型位运算的使用:
#include <iostream>
using namespace std;
int main()
{
unsigned int a = 6; // 二进制 00000110
unsigned int b = 11; // 二进制 00001011
// 按位与
cout << "a & b = " << (a & b) << endl;
// 00000110 & 00001011 = 00000010,十进制 2
// 按位或
cout << "a | b = " << (a | b) << endl;
// 00000110 | 00001011 = 00001111,十进制 15
// 按位异或
cout << "a ^ b = " << (a ^ b) << endl;
// 00000110 ^ 00001011 = 00001101,十进制 13
// 按位取反
cout << "~a = " << (~a) << endl;
// 00000110 取反为 11111001,这是补码形式,输出为无符号十进制
// 左移
cout << "a << 2 = " << (a << 2) << endl;
// 00000110 左移 2 位为 00011000,十进制 24
// 右移
cout << "b >> 1 = " << (b >> 1) << endl;
// 00001011 右移 1 位为 00000101,十进制 5
// 位运算复合赋值
int x = 5;
x &= 3; // x = x & 3,5 & 3 = 1
cout << "x after &= 3 : " << x << endl;
x |= 8; // x = x | 8,1 | 8 = 9
cout << "x after |= 8 : " << x << endl;
// 异或交换两个数
int m = 10, n = 20;
m = m ^ n;
n = m ^ n;
m = m ^ n;
cout << "after swap: m = " << m << ", n = " << n << endl;
return 0;
}Code language: PHP (php)
五、位运算的优先级
位运算符的优先级从高到低大致为:
~(取反)
<<、>>(移位)
&(按位与)
^(按位异或)
|(按位或)
位运算符的优先级低于算术运算符和关系运算符,因此混合使用时建议加括号明确顺序。
六、小结
- C++ 支持按位处理数据,提供 6 个位运算符:&、|、^、~、<<、>>。
- 位运算直接操作二进制位,常用于底层开发、状态标志、数据压缩等场景。
- 移位运算在不溢出时等价于乘或除以 2 的幂。
- 异或运算可用于不借助临时变量交换两个数。
- 位运算符优先级较低,混合使用时注意加括号。