11 位运算与标志位操作
四种常用操作
假设 flags 是无符号整数,mask 标出要操作的位(掩码中为 1 的位)。
| 操作 | 代码 | 含义 |
|---|---|---|
| 置位 | `flags | = mask;` |
| 清位 | flags &= ~mask; | 指定位清为 0,其他位不变 |
| 翻转 | flags ^= mask; | 指定位 0 ↔ 1,其他位不变 |
| 判断 | flags & mask | 结果非零表示至少有一个掩码位为 1 |
位从右往左编号,最低位是 bit0。1u << n 表示生成只有 bit n 为 1 的掩码(n 须在 unsigned int 的有效位宽内)。
代码示例
#include <stdint.h>
uint8_t flags = 0;
flags |= (1u << 0); // 00000001:置 bit0
flags |= (1u << 1); // 00000011:置 bit1
flags &= ~(1u << 0); // 00000010:清 bit0
flags ^= (1u << 2); // 00000110:翻转 bit2
if (flags & (1u << 1)) {
// bit1 已置位
}
记忆: |= 置 1,&= ~ 清 0,^= 翻转,& 检查。
蓝牙/TWS 开发注意
- 多状态可以共用一个
flags,每一位代表一个独立状态;设置某一位时尽量避免flags = mask覆盖其他状态。 if (flags & mask)判断的是至少一位被设置;要判断掩码中全部位都已设置,用(flags & mask) == mask。- 软件状态变量与硬件寄存器不同:某些寄存器有写 1 清零(W1C)、只读或读写副作用,不能不加分析地使用
|=、&= ~等读—改—写操作。 - 多线程或中断同时修改同一标志变量时,普通的
|=等并不自动保证原子性;需根据平台采用临界区、原子操作或其他同步机制。