C 位运算符
C 语言位运算符
注意:这是C语言中比较高级的主题。如果您是编程新手,一开始可能会觉得有些棘手,但请不要担心——位运算符主要用于系统编程、硬件控制或性能优化等特殊情况。
在C语言中,位运算符允许您直接操作构成二进制数字的位(1和0)。
计算机中的每个整数都以二进制形式存储,这意味着它使用0或1的位(二进制数字)来表示。位运算符允许您比较、合并、移位或翻转这些位。
注意: 位运算仅适用于整数类型(例如 int、char 或 long)。
List of Bitwise Operators
| 运算符 | 名称 | 描述 |
|---|---|---|
| & | 与 | 如果两个位都为 1,则每个位都设置为 1 |
| | | 或 | 如果至少有一个位为 1,则每个位都设置为 1 |
| ^ | 异或 | 如果只有一个位为 1,则每个位都设置为 1 |
| ~ | 非 | 取反所有位 |
| << | 左移 | 将位向左移动(乘以 2 的幂) |
| >> | 右移 | 将位向右移动(除以 2 的幂) |
二进制示例
让我们从两个整数开始:
int a = 6; // 0110 in binary
int b = 3; // 0011 in binary
以下是不同位运算符对这些值的运算方式:
| 运算 | 二进制结果 | 十进制结果 |
|---|---|---|
| a & b | 0010 | 2 |
| a | b | 0111 | 7 |
| a ^ b | 0101 | 5 |
| ~a | ...1001 | -7 (on most systems) |
| a << 1 | 1100 | 12 |
| a >> 1 | 0011 | 3 |
十进制和二进制值
以下是一个简要的参考表,展示了十进制数转换为二进制(16 位格式)后的样子:
0 = 0000000000000000 1 = 0000000000000001 2 = 0000000000000010 3 = 0000000000000011 4 = 0000000000000100 5 = 0000000000000101 6 = 0000000000000110 7 = 0000000000000111 8 = 0000000000001000 9 = 0000000000001001 10 = 0000000000001010 11 = 0000000000001011 12 = 0000000000001100
提示: 向左每移动一位,数值就会翻倍。例如,0000000000000100 的值是 4,因为从右数第三位被置位(22 = 4)。
按位与 (&)
按位与运算符 & 比较每一位,仅当两位均为 1 时才返回 1。
示例
int a = 6; // 0110
int b = 3; // 0011
int result = a & b;
printf("Result: %d
", result); // 2 (0010)
按位或 (|)
当且仅当其中一个位为 1 时,| 运算符将另一个位设置为 1。
示例
int a = 6; // 0110
int b = 3; // 0011
int result = a | b;
printf("Result: %d
", result); // 7 (0111)
按位异或 (^)
按位异或 ^ 运算符仅当两个位不同时返回 1。
示例
int a = 6; // 0110
int b = 3; // 0011
int result = a ^ b;
printf("Result: %d
", result); // 5 (0101)
按位取反 (~)
按位取反运算符 ~ 将每一位取反(0 变为 1,1 变为 0)。
示例
int a = 5; // 00000101
int result = ~a;
printf("Result: %d
", result); // -6 on most systems
注意: ~ 的结果取决于负数的存储方式(通常是二进制补码)。例如,5 (00000101) 变为 11111010,被解释为 -6。
左移 (<<)
<< 运算符将位向左移动,并在右侧填充 0。这与乘以 2 的幂相同。
示例
int a = 3; // 00000011
int result = a << 2;
printf("Result: %d
", result); // 12 (3 * 2^2)
右移 (>>)
右移运算符 >> 将位向右移动。这相当于除以 2 的幂。对于有符号整数,符号位是否保留取决于系统。
示例
int a = 12; // 00001100
int result = a >> 2;
printf("Result: %d
", result); // 3 (12 / 2^2)
实际应用示例:标志和权限
位运算符通常用于将多个选项存储在单个整数中,即使用标志。
示例
#define READ 1 // 0001
#define WRITE 2 // 0010
#define EXEC 4 // 0100
int permissions = READ | WRITE; // 用户可以读写
if (permissions & READ) {
printf("Read allowed
");
}
if (permissions & WRITE) {
printf("Write allowed
");
}
if (permissions & EXEC) {
printf("Execute allowed
");
}
在本例中,用户同时拥有READ和WRITE权限,但没有EXEC权限。
总结
- 位运算符作用于整数的各个位
&:与 (AND) - 两个位都必须为 1|:或 (OR) - 任一位可以为 1^: 异或 (XOR) - 只有一位为 1~: 非 (NOT) - 翻转所有位<<: 左移 - 乘以 2 的幂>>: 右移 - 除以 2 的幂
提示:位运算对于优化、底层硬件访问、标志位和掩码非常有用。

