什么是位屏蔽?

我是C编程的新手,遇到过位屏蔽。位掩码的一般概念和功能是什么?

例子是非常赞赏的。

459131 次浏览

掩码定义了你想要保留哪些位,以及你想要清除哪些位。

屏蔽是对一个值应用掩码的行为。这可以通过以下方式实现:

  • 按位和,以提取值中的位的子集
  • 按位ORing,以便设置值中的位的子集
  • 按位XORing,以便切换值中的一个位子集

下面是一个提取值中比特子集的例子:

Mask:   00001111b
Value:  01010101b

对值应用掩码意味着我们希望清除第一个(高)位,并保留最后一个(低)位。因此,我们提取了较低的4位。结果是:

Mask:   00001111b
Value:  01010101b
Result: 00000101b

屏蔽是使用AND实现的,所以在C中我们得到:

uint8_t stuff(...) {
uint8_t mask = 0x0f;   // 00001111b
uint8_t value = 0x55;  // 01010101b
return mask & value;
}

下面是一个相当常见的用例:从较大的单词中提取单个字节。我们将单词中的高阶位定义为第一个字节。为此我们使用了两个操作符:&>>(右移)。这是我们如何从一个32位整数中提取四个字节的方法:

void more_stuff(uint32_t value) {             // Example value: 0x01020304
uint32_t byte1 = (value >> 24);           // 0x01020304 >> 24 is 0x01 so
// no masking is necessary
uint32_t byte2 = (value >> 16) & 0xff;    // 0x01020304 >> 16 is 0x0102 so
// we must mask to get 0x02
uint32_t byte3 = (value >> 8)  & 0xff;    // 0x01020304 >> 8 is 0x010203 so
// we must mask to get 0x03
uint32_t byte4 = value & 0xff;            // here we only mask, no shifting
// is necessary
...
}

注意,你可以切换上面操作符的顺序,你可以先做掩码,然后是移位。结果是一样的,但现在你必须使用不同的蒙版:

uint32_t byte3 = (value & 0xff00) >> 8;

屏蔽表示保留、更改或删除所需的部分信息。让我们来看看一个图像掩蔽操作;就像这个掩蔽操作是去除皮肤以外的任何东西:

Enter image description here

在本例中,我们正在执行操作。还有其他屏蔽操作符-XOR


位掩码表示对位施加掩码。下面是一个使用 -的位掩蔽

     1 1 1 0 1 1 0 1     input
(&)  0 0 1 1 1 1 0 0      mask
------------------------------
0 0 1 0 1 1 0 0    output

因此,只保留中间的4位(因为这些位在掩码中是1)。

让我们用XOR -来看看这个

     1 1 1 0 1 1 0 1     input
(^)  0 0 1 1 1 1 0 0      mask
------------------------------
1 1 0 1 0 0 0 1    output

现在,中间的4位被翻转(1变成00变成1)。


因此,使用位掩码,我们可以访问单个位(例子)。有时,这种技术也可以用于提高性能。以这个为例-

bool isOdd(int i) {
return i%2;
}

这个函数判断一个整数是奇数还是偶数。我们可以使用位掩码-以更有效的方式实现相同的结果

bool isOdd(int i) {
return i&1;
}

简短的解释:如果二进制数的最低有效位1,则它为奇数;对于0,它将是偶数。因此,通过对1执行,我们删除了除最低有效位之外的所有其他位,即:

     55  ->  0 0 1 1 0 1 1 1     input
(&)   1  ->  0 0 0 0 0 0 0 1      mask
---------------------------------------
1  <-  0 0 0 0 0 0 0 1    output