位掩码。为什么我们需要按位移位运算符?

问题描述 投票:0回答:1

我见过两种位掩码实现:

  1. 使用按位移位运算符设置
    flags |= 1 << MASK_VALUE
    并清除掩码
    flags &= ~(1 << MASK_VALUE)
    。这是最常用的方法。
  2. 另一种不使用按位移位运算符,仅使用逻辑运算符来设置
    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

有什么理由使用按位移位运算符吗?第一种方法比第二种方法更好吗?

c bitmask
1个回答
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)
© www.soinside.com 2019 - 2024. All rights reserved.