C 语言 - 位运算符

C 语言位运算符

注意:这是 C 语言中一个更高级的主题。如果您是编程新手,一开始觉得棘手也不必担心——位运算符主要用于特殊情况,如系统编程、硬件控制或性能优化。

在 C 语言中,位运算符允许您直接处理构成二进制形式数字的位(即 1 和 0)。

计算机中的每个整数都以二进制形式存储,这意味着它使用位(二进制数字,即 0 或 1)来表示。位运算符允许您比较、组合、移位或翻转这些位。

注意:位运算仅适用于整数类型(如 int、char 或 long)。

提示:如果您还不熟悉二进制数,请先查阅以下页面:

位运算符列表

运算符 名称 描述
& 如果两个位都为 1,则对应位设为 1
| 如果至少有一个位为 1,则对应位设为 1
^ 异或 如果只有一个位为 1,则对应位设为 1
~ 反转所有位
<< 左移 将位向左移动(乘以 2 的幂)
>> 右移 将位向右移动(除以 2 的幂)

二进制示例

让我们从两个整数开始:

int a = 6;  // 二进制 0110
int b = 3;  // 二进制 0011

以下是不同位运算符对这些值的影响:

操作 二进制结果 十进制结果
a & b 0010 2
a | b 0111 7
a ^ b 0101 5
~a ...1001 -7 (在大多数系统上)
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,因为从右边数第三位被设置了(2² = 4)。

按位与 (&)

& 运算符比较每个位,并且仅当两个位都为 1 时才返回 1。

实例

int a = 6;   // 0110
int b = 3;   // 0011

int result = a & b;
printf("结果: %d\n", result); // 2 (0010)

亲自试一试

按位或 (|)

| 运算符如果任一位为 1,则将该位设为 1。

实例

int a = 6;   // 0110
int b = 3;   // 0011

int result = a | b;
printf("结果: %d\n", result); // 7 (0111)

亲自试一试

按位异或 (^)

^ 运算符仅当位不同时才返回 1。

实例

int a = 6;   // 0110
int b = 3;   // 0011

int result = a ^ b;
printf("结果: %d\n", result); // 5 (0101)

亲自试一试

按位非 (~)

~ 运算符反转每个位(0 变成 1,1 变成 0)。

实例

int a = 5; // 00000101

int result = ~a;
printf("结果: %d\n", result); // 在大多数系统上是 -6

亲自试一试

注意:~ 的结果取决于负数如何存储(通常是补码)。例如,5 (00000101) 变成 11111010,这被解释为 -6。

左移 (<<)

<< 运算符将位向左移动,并在右侧填充 0。这相当于乘以 2 的幂。

实例

int a = 3; // 00000011

int result = a << 2;
printf("结果: %d\n", result); // 12 (3 * 2^2)

亲自试一试

右移 (>>)

>> 运算符将位向右移动。这相当于除以 2 的幂。对于有符号整数,符号位可能会根据系统被保留。

实例

int a = 12; // 00001100

int result = a >> 2;
printf("结果: %d\n", 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\n");
}
if (permissions & WRITE) {
  printf("Write allowed\n");
}
if (permissions & EXEC) {
  printf("Execute allowed\n");
}

亲自试一试

在此例中,用户同时拥有 READ 和 WRITE 权限,但没有 EXEC 权限。

总结

  • 位运算符作用于整数的各个位上。
  • &:与 - 两个位都必须为 1。
  • |:或 - 任一位可以为 1。
  • ^:异或 - 只有一个位为 1。
  • ~:非 - 翻转所有位。
  • <<:左移 - 乘以 2 的幂。
  • >>:右移 - 除以 2 的幂。

提示:位运算对于优化、底层硬件访问、标志和掩码非常有用。