位操作是C语言中高效处理数据的重要技术,在Linux系统编程、驱动开发和嵌入式领域尤为常用。下面介绍一些实用的位操作技巧。
设置位
#define SET_BIT(var, pos) ((var) |= (1 << (pos)))
清除位
#define CLEAR_BIT(var, pos) ((var) &= ~(1 << (pos)))
切换位状态
#define TOGGLE_BIT(var, pos) ((var) ^= (1 << (pos)))
检查位是否设置
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
unsigned int x = 10;
x = x << 1; // 相当于 x * 2
x = x >> 1; // 相当于 x / 2
void swap(int *a, int *b) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
if (x & 1) {
// 奇数
} else {
// 偶数
}
int abs(int x) {
const int mask = x >> (sizeof(int) * CHAR_BIT - 1);
return (x + mask) ^ mask;
}
int is_power_of_two(unsigned int x) {
return x && !(x & (x - 1));
}
Linux内核中广泛使用位操作,特别是在设备驱动和内存管理中:
位图操作
#include <linux/bitmap.h>
unsigned long bitmap[10];
set_bit(5, bitmap); // 设置第5位
clear_bit(5, bitmap); // 清除第5位
test_bit(5, bitmap); // 测试第5位
原子位操作
#include <linux/bitops.h>
unsigned long flags;
set_bit(0, &flags); // 非原子操作
test_and_set_bit(0, &flags); // 原子操作
位域定义
struct {
unsigned int flag1:1;
unsigned int flag2:1;
unsigned int count:6;
} status;
使用位运算代替模运算
// 代替 x % 8
x & 0x7;
快速计算log2
int log2(unsigned int x) {
int r = 0;
while (x >>= 1) r++;
return r;
}
位反转
unsigned int reverse_bits(unsigned int x) {
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8);
x = ((x >> 16) | (x << 16));
return x;
}
掌握这些位操作技巧可以显著提高Linux C程序的效率和性能,特别是在系统级编程和资源受限的环境中。