当前位置: 首页 > news >正文

【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;

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


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

http://www.xdnf.cn/news/731953.html

相关文章:

  • 安全帽目标检测
  • 计算机模拟分子合成有哪些应用软件?
  • VMware使用时出现的问题,此文章会不断更新分享使用过程中会出现的问题
  • 级联的if else
  • EDW2025|数据治理的神话破除——从误区到现实
  • CentOS-stream-9 Zabbix的安装与配置
  • 移动安全Android——解决APP抓包证书无效问题
  • comfyui 工作流中 视频长度和哪些参数有关? 生成15秒的视频,再加上RTX4060 8G显卡,尝试一下
  • Linux:Shell脚本基础
  • 【PyTroch学习-001】从一个简单示例开始:手写数字识别
  • [paddle]paddle2onnx无法转换Paddle3.0.0的json格式paddle inference模型
  • wireshark分析国标rtp ps流
  • 睿抗机器人开发者大赛CAIP-编程技能赛-历年真题 解题报告汇总 | 珂学家
  • 电子电路:共射极放大器工作原理及应用详解
  • 数据采集是什么?一文讲清数据采集系统的模式!
  • Linux常用命令大全
  • MySQL 8.0 OCP 英文题库解析(十一)
  • nic_monitor-全面监控以太网、IB、RoCE网络流量的工具
  • mongodb nosql数据库笔记
  • 系统架构中的组织驱动:康威定律在系统设计中的应用
  • Bean对象循环依赖
  • 尚硅谷redis7 90-92 redis集群分片之集群扩容
  • 智慧工厂整体解决方案
  • 基于地理特征金字塔的层次化AI定位方案:从人脑推理到卫星图谱的跨尺度匹配
  • 晨控CK-UR08与欧姆龙PLC配置Ethernet/IP通讯连接操作手册
  • React从基础入门到高级实战:React 高级主题 - 性能优化:深入探索与实践指南
  • MOT challenge使用方法及数据集说明
  • 01 redis 的环境搭建
  • dockers搭建mysql环境
  • GraalVM加持下的Quarkus极速启动