【C】位运算

C 语言位运算(Bitwise Operations)

位运算直接对整数的二进制位(bit)进行操作,常用于底层开发、硬件编程、数据压缩、加密算法等场景。C 语言提供了 6 种位运算符:


1. 基本位运算符

运算符名称描述示例(假设 A = 60, B = 13
&按位与两位均为 1 时结果为 1A & B = 120011 1100 & 0000 1101 = 0000 1100
|按位或任意一位为 1 时结果为 1`A
^按位异或两位不同时结果为 1A ^ B = 490011 1100 ^ 0000 1101 = 0011 0001
~按位取反所有位取反(0→1, 1→0)~A = -61~0011 1100 = 1100 0011,补码表示)
<<左移左移指定位数,低位补 0A << 2 = 2400011 1100 → 1111 0000
>>右移右移指定位数,高位补符号位(算术右移)或 0(逻辑右移,取决于编译器)A >> 2 = 150011 1100 → 0000 1111

2. 常见用途

(1) 掩码操作(Masking)

  • 检查某位是否为 1
    if (value & (1 << n)) {  // 检查第 n 位(从 0 开始)
        // 第 n 位是 1
    }
    
  • 设置某位为 1
    value |= (1 << n);  // 第 n 位置 1
    
  • 清除某位为 0
    value &= ~(1 << n); // 第 n 位清 0
    
  • 切换某位(0↔1)
    value ^= (1 << n);  // 第 n 位取反
    

(2) 快速乘除 2 的幂

  • 左移代替乘法
    int x = 5;
    int y = x << 3; // y = x * 2³ = 40
    
  • 右移代替除法
    int x = 20;
    int y = x >> 2; // y = x / 2² = 5
    

    注意:右移负数的结果依赖编译器实现(算术/逻辑右移)。

(3) 交换变量(不使用临时变量)

a ^= b;  // a = a ^ b
b ^= a;  // b = b ^ (a ^ b) = a
a ^= b;  // a = (a ^ b) ^ a = b

(4) 判断奇偶性

if (x & 1) {  // 等价于 x % 2 != 0
    // 奇数
}

(5) 取绝对值(32 位整数)

int abs(int x) {
    int mask = x >> 31;  // 正数为 0,负数为 -1(全 1)
    return (x ^ mask) - mask;  // 负数取反加 1
}

3. 注意事项

  1. 符号位问题

    • 右移 (>>) 有符号数时,高位补符号位(算术右移)。
    • 无符号数右移时,高位补 0(逻辑右移)。
  2. 位移超出位数

    • 如果位移位数超过类型的宽度(如 int 左移 32 位),行为未定义(UB)。
  3. 运算符优先级

    • 位运算符优先级低于算术运算符,建议用括号明确逻辑:
      if (x & 0xFF == 0)   // 错误!等价于 x & (0xFF == 0)
      if ((x & 0xFF) == 0) // 正确
      
  4. 可读性

    • 复杂的位操作应添加注释,或使用宏/函数封装:
      #define BIT(n) (1 << n)
      #define IS_SET(x, n) ((x) & BIT(n))
      

4. 实战示例

示例 1:提取 RGB 颜色分量

uint32_t color = 0xFF3366; // RGB(0xFF, 0x33, 0x66)
uint8_t r = (color >> 16) & 0xFF; // R = 0xFF
uint8_t g = (color >> 8)  & 0xFF; // G = 0x33
uint8_t b = color & 0xFF;         // B = 0x66

示例 2:IP 地址转换

uint32_t ip = (192 << 24) | (168 << 16) | (1 << 8) | 10; // 192.168.1.10

示例 3:位图(Bitmap)

uint8_t bitmap[16]; // 128 位位图
// 设置第 n 位
void set_bit(int n) {
    bitmap[n / 8] |= (1 << (n % 8));
}
// 清除第 n 位
void clear_bit(int n) {
    bitmap[n / 8] &= ~(1 << (n % 8));
}

5. 扩展:位域(Bit Fields)

C 语言支持在结构体中定义位域,直接控制成员的位数:

struct {
    unsigned int is_active : 1;  // 1 位
    unsigned int mode      : 3;  // 3 位
    unsigned int padding   : 4;  // 4 位填充
} flags;

注意:位域的具体内存布局依赖编译器实现,跨平台时需谨慎。


掌握位运算可以显著提升代码在底层和高性能场景的效率,但需注意可读性和平台兼容性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值