C语言位运算完全指南
为什么需要位运算
位运算是 C 语言的精髓之一,直接操作内存中的二进制位,在底层编程、嵌入式系统、性能优化等场景中广泛应用。掌握位运算可以写出更高效、更节省内存的代码。
基本位运算符
C 语言提供 6 种基本位运算符:
按位与:a & b // 两位都为 1 时结果为 1 按位或:a | b // 至少有一位为 1 时结果为 1 按位异或:a ^ b // 两位相异时结果为 1 按位取反:~a // 所有位取反 左移:a << n // 左移 n 位,低位补 0 右移:a >> n // 右移 n 位,无符号高位补 0,有符号高位补符号位
位掩码技巧
位掩码是使用位运算处理单个位的常用技巧:
// 提取第 n 位(从 0 开始) int get_bit(int x, int n) { return (x >> n) & 1; } // 设置第 n 位为 1 int set_bit(int x, int n) { return x | (1 << n); } // 清除第 n 位(设为 0) int clear_bit(int x, int n) { return x & ~(1 << n); } // 切换第 n 位 int toggle_bit(int x, int n) { return x ^ (1 << n); }
异或的妙用
异或运算有几个独特性质,可以用于一些巧妙操作:
// 性质 1:a ^ a = 0,a ^ 0 = a // 性质 2:满足交换律和结合律 // 性质 3:不使用临时变量交换两个数 void swap(int *a, int *b) { *a = *a ^ *b; *b = *a ^ *b; // 等价于 (*a^*b)^*b = *a *a = *a ^ *b; // 等价于 (*a^*b)^*a = *b } // 找出数组中唯一出现一次的数,其他数都出现两次 int find_single(int *arr, int n) { int result = 0; for (int i = 0; i < n; i++) { result ^= arr[i]; } return result; }
位域
位域允许在结构体中直接定义位级别的成员:
struct Flags { unsigned int enable : 1; // 占 1 位 unsigned int mode : 2; // 占 2 位 unsigned int status : 4; // 占 4 位 unsigned int : 1; // 保留位 }; struct Flags f; f.enable = 1; f.mode = 3; // 最大值为 3(2 位能表示的最大值)
实际应用场景
位运算在实际开发中非常常见:
1. 权限控制:使用掩码判断用户权限标志位
2. 状态标志:用单个整数的不同位表示多种状态
3. 数据压缩:将多个小数据打包到一个字节中
4. 算法优化:快速乘除法(x << 1 相当于 x * 2)
5. 硬件交互:操作寄存器、嵌入式开发