C 使用掩蔽的原因

C 使用掩蔽的原因,c,C,我使用的是我们以前的程序员制作的API。然而,我有点困惑,为什么他们会在这个为什么 使用带掩码的十六进制代码的原因是什么。那么,IPEV_错误屏蔽或IPEV_启动的原因是什么。为什么不使用十六进制值呢 gcc 4.4.1 c89 非常感谢您的建议,掩码可以帮助您从整数中提取所需的位,并丢弃不感兴趣的位 值0x9000在二进制中如下所示: #define IPEV_MASK 0x9000 #define IPEV_ERROR_MASK (IPEV_MASK |

我使用的是我们以前的程序员制作的API。然而,我有点困惑,为什么他们会在这个为什么

使用带掩码的十六进制代码的原因是什么。那么,IPEV_错误屏蔽或IPEV_启动的原因是什么。为什么不使用十六进制值呢

gcc 4.4.1 c89

非常感谢您的建议,

掩码可以帮助您从整数中提取所需的位,并丢弃不感兴趣的位

0x9000
在二进制中如下所示:

#define IPEV_MASK               0x9000
#define IPEV_ERROR_MASK     (IPEV_MASK | 0x0800)
#define IPEV_OPEN               (IPEV_MASK | 0x01)
#define IPEV_START              (IPEV_MASK | 0x02)
#define IPEV_MEDIA_FAIL     (IPEV_ERROR_MASK | IPEV_START)
所以这个掩码的目的是使用位12和15,丢弃其余的


IPEV\u ERROR\u MASK
IPEV\u MASK
中设置的位加上
0000 1000 0000
中设置的位的组合。因此,位11可能被保留用于指示是否发生了错误,并且将其与
IPEV\u MEDIA\u FAIL
中的
IPEV\u START
相结合是有意义的

掩码可帮助您从整数中提取所需的位,并丢弃不感兴趣的位

0x9000
在二进制中如下所示:

#define IPEV_MASK               0x9000
#define IPEV_ERROR_MASK     (IPEV_MASK | 0x0800)
#define IPEV_OPEN               (IPEV_MASK | 0x01)
#define IPEV_START              (IPEV_MASK | 0x02)
#define IPEV_MEDIA_FAIL     (IPEV_ERROR_MASK | IPEV_START)
所以这个掩码的目的是使用位12和15,丢弃其余的


IPEV\u ERROR\u MASK
IPEV\u MASK
中设置的位加上
0000 1000 0000
中设置的位的组合。因此,位11可能被保留用于指示是否发生了错误,并且将其与
IPEV\u MEDIA\u FAIL
中的
IPEV\u START
相结合是有意义的

它看起来像一种分类(或分组)方法。似乎所有的
“IPEV”
值都包含0x9000。随后的值当然可以定义为简单的十六进制值,但给出的方法在某种程度上是自我记录的,有助于避免在添加新值时出错

一种可能的用途是,一段代码可以检查值的IPEV_掩码部分,以查看“代码”是否属于该组

1001 0000 0000 0000

它看起来像一个分类(或分组)方法。似乎所有的
“IPEV”
值都包含0x9000。随后的值当然可以定义为简单的十六进制值,但给出的方法在某种程度上是自我记录的,有助于避免在添加新值时出错

一种可能的用途是,一段代码可以检查值的IPEV_掩码部分,以查看“代码”是否属于该组

1001 0000 0000 0000

我不确定你不清楚哪一部分,所以我会解释一切

首先,它们显然是位标志。位标志是一种在单个数字中存储大量布尔值的方法。例如,一个典型的32位整数可以存储32个布尔值。这有两个优点:内存非常紧凑,并且能够轻松地一次传递多个值。当然,缺点是要访问单个值,必须使用位运算符。因此,在处理代码中的布尔值时,通常不使用这种方法,而是在存储值或传递值时经常使用这种方法。还请注意,虽然您可以在物理上将每个可用的布尔值组合在一起,但通常只使用此技巧将相关值(如对象或其他对象的状态标志)组合在一起

现在,使用位标志有几种传统。首先,您总是使用每个位的描述性名称定义常量。否则很快就会变得很尴尬。(嗯……那么第17位是什么意思……)

另一方面,您总是使用
|
操作符将几个标志连接在一起,即使理论上可以使用
+
操作符。这同样有两个原因:一个原因是
|
+
快,但更重要的是,如果您意外地将同一个标记包含两次,则
|
操作符将提供正确的答案,而
+
将把一切都搞糟

这是一个真正的危险,因为在位标志的世界中,通常不仅可以看到每个位的常数,还可以看到常见组合的常数。使用
|
运算符,您可以将这些位连接起来,并确保结果将包含所需的位,而无需担心是否已将同一位设置了两次

因此,我们来举你的例子:

if (( someCode & IPEV_MASK ) == IPEV_MASK )
  // do something
显然,我们在某处有某种“IPEV”位掩码字段,这些是其位的命名常量。第一个常数是
IPEV\u MASK
,它设置位号15和12。然后是常数
IPEV_ERROR_MASK
,它包括IPEV_MASK,并且另外设置位11。等等等等

他们使用这些
|
操作来定义常量(而不是简单地编写十六进制文字)的原因是为了可读性。编译器无论如何都会将它们优化为固定值,在运行时不会进行任何位计算。但这种写作风格让你一眼就能明白哪个常数包括哪些其他常数。当然,如果您要修改其中一个,这些更改将在适当的地方自动反映出来


这是否更清楚?如果你还有什么问题,尽管问吧

我不太确定你不清楚哪一部分,所以我会解释一切

首先,它们显然是位标志。位标志是一种在单个数字中存储大量布尔值的方法。例如,一个典型的32位整数可以存储32个布尔值。这有两个优点:内存非常紧凑,并且能够轻松地一次传递多个值。当然,缺点是要访问单个值,必须使用位运算符。因此,在处理代码中的布尔值时,通常不使用这种方法,而是在存储值或传递值时经常使用这种方法。还要注意,当您