1、位运算基础
位运算是处理二进制数据的基本操作。
运算 | 符号 | 示例 | 作用 |
---|---|---|---|
按位与(AND) | & | a & b | 清除不需要的位 |
按位或(OR) | ` | ` | `a |
按位异或(XOR) | ^ | a ^ b | 翻转位 |
按位取反(NOT) | ~ | ~a | 取反所有位 |
左移(Left Shift) | << | a << n | 左移 n 位(乘 2^n ) |
右移(Right Shift) | >> | a >> n | 右移 n 位(除 2^n ) |
2、位掩码简介
位掩码(Bit Masking) 是使用 掩码(Mask) 与数据进行按位操作,以提取、修改或检查特定位的值。
掩码通常是一个特定的二进制模式,用于操作数据中的特定位。
#include <stdio.h> #define MASK 0x0F // 00001111,掩码定义 int main() { int value = 0x3A; // 00111010 int result = value & MASK; // 只保留低 4 位 printf("Result: %X\n", result); // 输出: A (1010) return 0; }
3、常见的位掩码操作
1)检查某个位是否为 1
使用 AND (&
) 操作符,num & mask
只保留 mask
所在位,其它位清零。如果结果 ≠ 0
,则该位为 1
。
#include <stdio.h> int main() { int num = 0b10101100; // 172 (二进制: 10101100) int mask = 0b00000100; // 4,对应二进制的第三位(从右往左,从0开始) if (num & mask) { printf("第 3 位是 1\n"); } else { printf("第 3 位是 0\n"); } return 0; }
2)设置某个位为 1
使用 OR (|
) 操作符,OR 操作将 mask
指定位设置为 1
,其余位保持不变。
#include <stdio.h> int main() { int num = 0b10100000; // 初始值 160 (二进制: 10100000) int mask = 0b00000100; // 掩码 4 (二进制: 00000100) - 对应设置第 3 位 num = num | mask; // 使用按位或运算符设置第 3 位 printf("新值: %d\n", num); // 164 (二进制: 10100100) return 0; }
3)清除某个位(设为 0)
使用 AND (&
) + NOT (~
),~mask
使 mask
指定位变为 0
,其他位保持 1
。AND 操作清除该位,其他位不变。
#include <stdio.h> int main() { int num = 0b10101100; // 172 int mask = 0b00000100; // 4,对应第三位 // 清除 num 的第 3 位 num = num & ~mask; printf("新值: %d\n", num); // 输出 168 (10101000) return 0; }
4)翻转某个位
使用 XOR (^
),XOR 操作:1 ^ 1 = 0
,0 ^ 1 = 1
。只改变 mask
指定的位,其余位不变。
#include <stdio.h> int main() { int num = 0b10101100; // 172 int mask = 0b00000100; // 4,对应第三位 // 使用异或操作翻转 num 的第三位 num = num ^ mask; // 输出翻转后的结果 printf("新值: %d\n", num); // 168 (10101000) return 0; }
4、其他应用
1)提取特定位
#include <stdio.h> int main() { int num = 0b11011010; // 218 (十进制) int mask = 0b00001111; // 用于提取低 4 位 int result = num & mask; // 按位与运算,保留低 4 位 printf("低 4 位: %d\n", result); // 10 (0b1010) printf("低 4 位 (二进制): 0b%b\n", result); // GCC 特殊扩展,非标准 C return 0; }
2)组合多个标志(Flags)
使用 OR (|
) 设置多个标志。使用|
组合多个权限标志。使用 &
检查是否具有某个权限。
#include <stdio.h> #define FLAG_READ 0b0001 // 1 #define FLAG_WRITE 0b0010 // 2 #define FLAG_EXEC 0b0100 // 4 int main() { int permissions = FLAG_READ | FLAG_WRITE; // 读 + 写权限 if (permissions & FLAG_READ) { printf("有读权限\n"); } if (permissions & FLAG_WRITE) { printf("有写权限\n"); } if (!(permissions & FLAG_EXEC)) { printf("没有执行权限\n"); } return 0; }
3)使用位掩码压缩数据
存储 RGB 颜色(8 位 R、8 位 G、8 位 B),使用 <<
左移位存储颜色分量。使用 & 0xFF
提取颜色值。
#include <stdio.h> int main() { unsigned int color = 0; // 设置 R、G、B 值 color |= (0x12 << 16); // 红色分量 (0x12) color |= (0x34 << 8); // 绿色分量 (0x34) color |= (0x56); // 蓝色分量 (0x56) printf("颜色编码: 0x%X\n", color); // 颜色编码: 0x123456 // 解析 RGB 颜色 int red = (color >> 16) & 0xFF; int green = (color >> 8) & 0xFF; int blue = color & 0xFF; printf("R: %X, G: %X, B: %X\n", red, green, blue); // R: 12, G: 34, B: 56 return 0; }