我见过两种位掩码实现:
flags |= 1 << MASK_VALUE
并清除掩码flags &= ~(1 << MASK_VALUE)
。这是最常用的方法。flags |= MASK_VALUE
和清除掩码flags &= ~(MASK_VALUE)
#define MASK_VALUE 4
int flags = 0;
flags |= 1 << MASK_VALUE;
printf("flags |= 1 << MASK_VALUE: %d\n", flags);
flags &= ~(1 << MASK_VALUE);
printf("flags &= ~(1 << MASK_VALUE): %d\n", flags);
flags |= MASK_VALUE;
printf("flags |= MASK_VALUE: %d\n", flags);
flags &= ~(MASK_VALUE);
printf("flags &= ~(MASK_VALUE): %d\n", flags);
输出
flags |= 1 << MASK_VALUE: 16
flags &= ~(1 << MASK_VALUE): 0
flags |= MASK_VALUE: 4
flags &= ~(MASK_VALUE): 0
有什么理由使用按位移位运算符吗?第一种方法比第二种方法更好吗?
在第一种情况下,
MASK_VALUE
被错误命名,它不是一个掩码,而是一个位数。
例如,如果您想屏蔽第 4 位,您可以使用 value
1<<4
,即 16。
所以你可能有:
#define BIT_NUM 4
#define BIT_MASK (1 << BIT_NUM)
flags |= BIT_MASK;
printf("flags |= MASK_VALUE: %d\n", flags);
flags &= ~(BIT_MASK);
因此,移位被用作计算编译时间常数的方法,使用自记录代码,这比仅使用文字值16(或更可能是位掩码0x10u)更不容易出错并且更容易维护.
当您创建更复杂的蒙版时,它就会发挥作用:
#define BIT_FIELD_A (0x3u << 8) // b8:b9 field
#define BIT_B (0x1u << 4) // b4 field flag
#define MASK (BIT_FIELD_A | BIT_B) // 0x0310 (bits 4,8 and 9)