最近我在C和C ++中遇到了几个“标志”的例子,我不太明白它们是如何工作的。在查看了一些源代码后,我注意到通常标志值以十六进制定义,如下所示:
FLAG1 = 0x00000001,
FLAG2 = 0x00000010,
我的直觉表明这些价值观正在被合并。通过将所有标志值组合到一个int中,标志是否有效?如果我使用了FLAG1 | FLAG2
之类的0x00000011
,那么结果会是FLAG1 = 1;
FLAG2 = 2;
?
我是否需要创建具有位偏移的枚举,或者我可以使用升序整数,如:
{{1}}
答案 0 :(得分:28)
您需要偏移这些位,否则无法提取单个标志。如果您的标志对应于1,2,3和& 4,组合值5,你怎么知道它是2& 3或1& 4?
您也可以这样做,例如:
enum {
FIRST = 1 << 0, // same as 1
SECOND = 1 << 1, // same as 2, binary 10
THIRD = 1 << 2, // same as 4, binary 100
FOURTH = 1 << 3 // same as 8, binary 1000
};
然后你组合这样的标志:
int flags = FIRST | THIRD | FOURTH;
你就像这样提取它们:
if (flags & THIRD) { ...
答案 1 :(得分:8)
您的第一种方法是不以最有效的方式使用这些位。在第一个示例中,您使用的是十六进制表示法,它等同于:
TEXTUREFLAGS_POINTSAMPLE = 1,
TEXTUREFLAGS_TRILINEAR = 16,
在第二种方法中,您似乎每次只增加一个。组合标志时这不起作用,因为组合值可能与另一个标志相同(例如,1 | 2 == 3)。
您应该使用这些值:
0x00000001 // == 1
0x00000002 // == 2
0x00000004 // == 4
0x00000008 // == 8
0x00000010 // == 16
0x00000020 // == 32
0x00000040 // == 64
etc...
这些是2的幂,它们可以使用按位或以任何方式组合而不会发生冲突。
答案 2 :(得分:5)
这样的标志是二进制值,因此您可以在单个字节中组合1,2,4,8,16,32,64,128,或者在int中组合2到2 ^ 31的其他幂。因为它们是二进制值,所以你可以“或”它们在一起,所以如果你“或”在一起1,2,4你最终会得到7,例如。你可以使用“和”来提取你想要的位 - 所以如果你有一个带有一些标志的int或者在一起,你想看看是否设置了“4”位,你可以说if (flag & 4)
和如果设置了“4”位,则为真。
答案 3 :(得分:3)
将标志视为32位数组(布尔值)
要打开其中一个位,或者将其与1&lt;&lt; BitIndex(其中BitIndex从零开始,所以0 - 31) 用〜(1&lt;&lt;&lt; BitIndex)关掉你了 通过(1&lt;&lt;&lt; BitIndex)
检查它是否打开或关闭一旦你克服了数字OR / AND与逻辑OR / AND之间的差异,它就会全部点击。 然后你会欣赏十六进制表示法!