C++位运算符 #
一、位运算符概述 #
位运算符直接对整数的二进制位进行操作。
1.1 运算符列表 #
| 运算符 | 名称 | 示例 | 说明 |
|---|---|---|---|
& |
位与 | a & b |
按位与 |
| |
位或 | a | b |
按位或 |
^ |
异或 | a ^ b |
按位异或 |
~ |
取反 | ~a |
按位取反 |
<< |
左移 | a << n |
左移n位 |
>> |
右移 | a >> n |
右移n位 |
1.2 二进制基础 #
cpp
// 十进制转二进制
// 5 = 0000 0101
// 3 = 0000 0011
// 10 = 0000 1010
// 15 = 0000 1111
#include <iostream>
#include <bitset>
int main() {
int x = 5;
// 输出二进制(C++11)
std::cout << std::bitset<8>(x) << std::endl; // 00000101
return 0;
}
二、位与运算符 & #
2.1 运算规则 #
text
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
2.2 基本示例 #
cpp
int a = 5; // 0101
int b = 3; // 0011
int c = a & b; // 0001 = 1
// 详细过程:
// 0101 (5)
// & 0011 (3)
// ------
// 0001 (1)
2.3 常见应用 #
掩码操作 #
cpp
int value = 0b11010110;
int mask = 0b00001111; // 低4位掩码
// 提取低4位
int low4 = value & mask; // 0b00000110 = 6
// 检查特定位
int bit3 = value & 0b00001000; // 检查第3位是否为1
if (bit3) {
std::cout << "第3位是1" << std::endl;
}
判断奇偶 #
cpp
int n = 7;
// 使用位与判断奇偶
if (n & 1) {
std::cout << "奇数" << std::endl;
} else {
std::cout << "偶数" << std::endl;
}
清除特定位 #
cpp
int value = 0b11111111;
// 清除第3位(设为0)
value = value & ~0b00001000; // 0b11110111
// 清除多个位
value = value & ~0b00001111; // 清除低4位
三、位或运算符 | #
3.1 运算规则 #
text
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
3.2 基本示例 #
cpp
int a = 5; // 0101
int b = 3; // 0011
int c = a | b; // 0111 = 7
// 详细过程:
// 0101 (5)
// | 0011 (3)
// ------
// 0111 (7)
3.3 常见应用 #
设置特定位 #
cpp
int value = 0b10100000;
// 设置第3位为1
value = value | 0b00001000; // 0b10101000
// 设置多个位
value = value | 0b00001111; // 设置低4位
组合标志 #
cpp
// 权限标志
const int READ = 0b001; // 1
const int WRITE = 0b010; // 2
const int EXECUTE = 0b100; // 4
// 组合权限
int permission = READ | WRITE; // 0b011 = 3
// 检查权限
if (permission & READ) {
std::cout << "有读权限" << std::endl;
}
if (permission & WRITE) {
std::cout << "有写权限" << std::endl;
}
if (permission & EXECUTE) {
std::cout << "有执行权限" << std::endl;
}
四、异或运算符 ^ #
4.1 运算规则 #
text
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
4.2 基本示例 #
cpp
int a = 5; // 0101
int b = 3; // 0011
int c = a ^ b; // 0110 = 6
// 详细过程:
// 0101 (5)
// ^ 0011 (3)
// ------
// 0110 (6)
4.3 异或特性 #
cpp
// 1. 任何数与0异或,结果不变
int a = 5 ^ 0; // 5
// 2. 任何数与自身异或,结果为0
int b = 5 ^ 5; // 0
// 3. 异或满足交换律和结合律
int c = 5 ^ 3 ^ 5; // 3
4.4 常见应用 #
交换两个数 #
cpp
int x = 5, y = 3;
// 使用异或交换(不需要临时变量)
x = x ^ y; // x = 5 ^ 3 = 6
y = x ^ y; // y = 6 ^ 3 = 5
x = x ^ y; // x = 6 ^ 5 = 3
// 现在x = 3, y = 5
简单加密 #
cpp
char data = 'A';
char key = 0x55;
// 加密
char encrypted = data ^ key;
// 解密
char decrypted = encrypted ^ key; // 'A'
找出只出现一次的数 #
cpp
int arr[] = {1, 2, 3, 2, 1};
int result = 0;
for (int n : arr) {
result ^= n;
}
// result = 3(只出现一次的数)
五、取反运算符 ~ #
5.1 运算规则 #
text
~0 = 1
~1 = 0
5.2 基本示例 #
cpp
unsigned char a = 5; // 0000 0101
unsigned char b = ~a; // 1111 1010 = 250
// 有符号数
char c = 5; // 0000 0101
char d = ~c; // 1111 1010 = -6(补码)
5.3 常见应用 #
创建掩码 #
cpp
int value = 0b11111111;
// 清除低4位
int mask = ~0b00001111; // 0b11110000
int result = value & mask; // 0b11110000
六、左移运算符 << #
6.1 运算规则 #
左移n位相当于乘以2^n(对于无溢出的正数)。
cpp
int a = 5; // 0000 0101
int b = a << 1; // 0000 1010 = 10
int c = a << 2; // 0001 0100 = 20
int d = a << 3; // 0010 1000 = 40
6.2 基本示例 #
cpp
int x = 1;
// 左移
x << 1; // 2
x << 2; // 4
x << 3; // 8
6.3 常见应用 #
快速乘法 #
cpp
int n = 10;
// 乘以2
int doubled = n << 1; // 20
// 乘以4
int quadrupled = n << 2; // 40
// 乘以8
int octupled = n << 3; // 80
创建掩码 #
cpp
// 创建第n位的掩码
int bit(int n) {
return 1 << n;
}
// 使用
int mask = bit(3); // 0b00001000
七、右移运算符 >> #
7.1 运算规则 #
右移n位相当于除以2^n(向下取整)。
cpp
int a = 20; // 0001 0100
int b = a >> 1; // 0000 1010 = 10
int c = a >> 2; // 0000 0101 = 5
int d = a >> 3; // 0000 0010 = 2
7.2 算术右移 vs 逻辑右移 #
cpp
// 有符号数:算术右移(保留符号位)
int x = -8; // 1111 1000(补码)
int y = x >> 1; // 1111 1100 = -4
// 无符号数:逻辑右移(补0)
unsigned int a = 0b10000000;
unsigned int b = a >> 1; // 0b01000000
7.3 常见应用 #
快速除法 #
cpp
int n = 100;
// 除以2
int half = n >> 1; // 50
// 除以4
int quarter = n >> 2; // 25
// 除以8
int eighth = n >> 3; // 12
提取位 #
cpp
int value = 0b11010110;
// 提取第n位
bool getBit(int value, int n) {
return (value >> n) & 1;
}
// 使用
bool bit2 = getBit(value, 2); // true (第2位是1)
八、位运算综合应用 #
8.1 位操作函数 #
cpp
// 设置第n位为1
int setBit(int num, int n) {
return num | (1 << n);
}
// 清除第n位(设为0)
int clearBit(int num, int n) {
return num & ~(1 << n);
}
// 切换第n位
int toggleBit(int num, int n) {
return num ^ (1 << n);
}
// 检查第n位是否为1
bool isBitSet(int num, int n) {
return (num & (1 << n)) != 0;
}
// 修改第n位为指定值
int changeBit(int num, int n, bool value) {
if (value) {
return setBit(num, n);
} else {
return clearBit(num, n);
}
}
8.2 统计二进制中1的个数 #
cpp
int countOnes(int n) {
int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
// 更高效的方法
int countOnes2(int n) {
int count = 0;
while (n) {
n &= n - 1; // 清除最低位的1
count++;
}
return count;
}
// C++20:使用std::popcount
#include <bit>
int count = std::popcount(n);
8.3 判断是否是2的幂 #
cpp
bool isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
// 示例
isPowerOfTwo(8); // true (1000)
isPowerOfTwo(6); // false (0110)
8.4 颜色操作 #
cpp
// RGB颜色打包
int packColor(unsigned char r, unsigned char g, unsigned char b) {
return (r << 16) | (g << 8) | b;
}
// 解包
unsigned char getRed(int color) { return (color >> 16) & 0xFF; }
unsigned char getGreen(int color) { return (color >> 8) & 0xFF; }
unsigned char getBlue(int color) { return color & 0xFF; }
// 使用
int color = packColor(255, 128, 64); // 0xFF8040
九、位运算与逻辑运算的区别 #
cpp
// 位运算:对每一位进行操作
int a = 5 & 3; // 1
int b = 5 | 3; // 7
// 逻辑运算:返回布尔值,短路求值
bool c = 5 && 3; // true
bool d = 5 || 0; // true
// 常见错误
if (x & 1) { } // 检查奇偶,正确
if (x && 1) { } // 检查x非零,不是奇偶检查!
十、最佳实践 #
10.1 使用unsigned类型 #
cpp
// 推荐:使用unsigned避免符号位问题
unsigned int x = 0xFFFFFFFF;
unsigned int y = x >> 1; // 0x7FFFFFFF
// 有符号数右移可能有问题
int a = -1;
int b = a >> 1; // 结果取决于编译器
10.2 使用括号 #
cpp
// 位运算优先级较低
int result = a & b == c; // 错误!等价于 a & (b == c)
int result = (a & b) == c; // 正确
10.3 使用有意义的常量 #
cpp
// 不推荐
int flags = 0b00001111;
// 推荐
const int LOW_NIBBLE_MASK = 0x0F;
int flags = LOW_NIBBLE_MASK;
十一、总结 #
位运算符一览 #
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
& |
位与 | 5 & 3 |
1 |
| |
位或 | 5 | 3 |
7 |
^ |
异或 | 5 ^ 3 |
6 |
~ |
取反 | ~5 |
-6 |
<< |
左移 | 5 << 1 |
10 |
>> |
右移 | 5 >> 1 |
2 |
常见应用 #
| 应用 | 方法 |
|---|---|
| 判断奇偶 | n & 1 |
| 乘以2 | n << 1 |
| 除以2 | n >> 1 |
| 设置位 | n | (1 << i) |
| 清除位 | n & ~(1 << i) |
| 切换位 | n ^ (1 << i) |
| 检查位 | n & (1 << i) |
下一步,让我们学习赋值运算符!
最后更新:2026-03-26