标志在C中是如何工作的? 最近我在C和C++中遇到了几个“标志”,我不太明白它们是如何工作的。看过一些源代码后,我注意到标记值通常是用十六进制定义的,如下所示: FLAG1 = 0x00000001, FLAG2 = 0x00000010,

标志在C中是如何工作的? 最近我在C和C++中遇到了几个“标志”,我不太明白它们是如何工作的。看过一些源代码后,我注意到标记值通常是用十六进制定义的,如下所示: FLAG1 = 0x00000001, FLAG2 = 0x00000010,,c++,c,integer,flags,C++,C,Integer,Flags,我的直觉表明,这些价值观正在结合起来。标志是否通过将所有标志值组合成一个int来工作?如果我像FLAG1 | FLAG2那样使用这两个选项,结果会是0x00000011 我是否需要使用位偏移创建枚举,或者可以使用升序整数,如: FLAG1 = 1; FLAG2 = 2; 您的第一种方法没有以最有效的方式使用位。在第一个示例中,您使用十六进制表示法,它相当于: TEXTUREFLAGS_POINTSAMPLE = 1, TEXTUREFLAGS_TRILINEAR = 16, 在第二种方法中,

我的直觉表明,这些价值观正在结合起来。标志是否通过将所有标志值组合成一个int来工作?如果我像
FLAG1 | FLAG2
那样使用这两个选项,结果会是
0x00000011

我是否需要使用位偏移创建枚举,或者可以使用升序整数,如:

FLAG1 = 1;
FLAG2 = 2;

您的第一种方法没有以最有效的方式使用位。在第一个示例中,您使用十六进制表示法,它相当于:

TEXTUREFLAGS_POINTSAMPLE = 1,
TEXTUREFLAGS_TRILINEAR = 16,
在第二种方法中,似乎每次只增加一个。这在组合标志时不起作用,因为组合值可能与另一个标志相同(例如,1 | 2==3)

您应该改为使用以下值:

0x00000001  // == 1
0x00000002  // == 2
0x00000004  // == 4
0x00000008  // == 8
0x00000010  // == 16
0x00000020  // == 32
0x00000040  // == 64
etc...

这是两个的幂,它们可以按位或以任何方式组合而不产生冲突。

您需要偏移位,否则无法提取单个标志。如果您有对应于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
};
你可以这样提取它们:

if (flags & THIRD) { ...

像这样的标志是二进制值,所以你可以在一个字节中组合1、2、4、8、16、32、64、128,或者在一个整数中再加上2到2^31的幂。因为它们是二进制值,所以你可以将它们“或”在一起,例如,如果你将1、2、4“或”在一起,你就得到了7。你可以用“And”来提取你想要的位,因此如果你有一个带有一些标志或“ed”在一起的int,你想看看是否设置了“4”位,你可以说
if(flag&4)
,如果设置了“4”位,则为真。

将标志想象为一个32位(布尔)的数组


在你身上打开一个,或者用1打开,好吧,但如果我只做一个,像20个,它就不起作用了,是吗?我还得错开十六进制,这样它们就不会互相覆盖了,对吗?或者我不明白它是如何工作的。@user425756,如果你不使用二的幂,你就无法分辨1和2被设置的区别,或者3被设置的区别。是的,我就是这么想的。谢谢你,这更有意义。
if (flags & THIRD) { ...