一、按位与的概念
按位与运算符为 &,它将两个操作数对应的二进制位的每一位一一对应,并进行逻辑与操作。
运算规则:两个对应位都为 1 时,结果位为 1;否则结果位为 0。
| 位a | 位b | a & b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
二、按位与的常见用途
1. 将操作数中的若干位置零(其他位不变)
利用 0 & x = 0 的特性,将需要清零的位与 0 进行按位与,需要保留的位与 1 进行按位与。
示例:将 char 型变量 a 的最低位置零,其余位保持不变。
a = a & 0xfe;
分析:0xfe 的二进制为 11111110(最低位为 0,其余位为 1)。a 与 0xfe 按位与后,最低位被强制清零,其余位保持原值不变。
2. 取操作数中的若干指定位
利用 x & 1 = x 的特性,将需要提取的位与 1 进行按位与,不需要的位与 0 进行按位与。
示例:假设有 char c 和 int a,取出 a 的低字节(低 8 位),置于 c 中。
c = a & 0xff;
分析:0xff 的二进制为低 8 位全 1(00000000 00000000 00000000 11111111)。a 与 0xff 按位与后,高 24 位全部清零,低 8 位保持原值,即提取了 a 的低字节。
三、代码示例
以下代码演示了按位与运算的实际应用:
#include <iostream>
using namespace std;
int main()
{
// 示例1:将最低位置零
unsigned char a = 0x9b; // 二进制 10011011
a = a & 0xfe; // 0xfe = 11111110
cout << "a after clear lowest bit: " << hex << (int)a << endl;
// 结果:10011010,十六进制 9a
// 示例2:提取低字节
int num = 0x12345678;
unsigned char c = num & 0xff;
cout << "low byte of num: " << hex << (int)c << endl;
// 结果:78
// 示例3:判断奇偶性
int x = 17;
if (x & 1)
cout << x << " is odd" << endl;
else
cout << x << " is even" << endl;
// x & 1 结果为 1,说明最低位为 1,是奇数
// 示例4:将指定位置零(第3位置零,从0开始计数)
unsigned char flags = 0xff; // 11111111
flags = flags & ~(1 << 3); // ~(1 << 3) = 11110111
cout << "flags after clear bit 3: " << hex << (int)flags << endl;
// 结果:f7
// 示例5:提取指定位(取第4到第7位)
unsigned char value = 0xab; // 10101011
unsigned char nibble = (value >> 4) & 0x0f;
cout << "high nibble: " << hex << (int)nibble << endl;
// 结果:a
return 0;
}Code language: PHP (php)
四、注意事项
- 按位与 & 不要与逻辑与 && 混淆。& 是对每一位进行运算,&& 是对整体布尔值进行运算。
- 对负数进行按位与时,结果依赖于该数在计算机中的二进制表示方式(通常为补码)。
- 将位置零时,掩码中需要清零的位设为 0,需要保留的位设为 1。
- 提取位时,掩码中需要提取的位设为 1,其余位设为 0,然后按位与。
五、小结
- 按位与(&)将两个操作数逐位进行逻辑与运算。
- 主要用途:将指定位置零、提取指定位、判断奇偶、掩码操作。
- 置零操作:目标位与 0 按位与,其余位与 1 按位与。
- 提取操作:目标位与 1 按位与,其余位与 0 按位与。
- 实际开发中常用于状态标志的读取和修改。