代码之家  ›  专栏  ›  技术社区  ›  Justin Meiners

旗子在C中是如何工作的?

  •  10
  • Justin Meiners  · 技术社区  · 16 年前

    最近我在C和C++中遇到了几个“标志”的例子,我不太明白它们是如何工作的。在查看了一些源代码之后,我注意到通常标志值是以十六进制定义的,例如:

    FLAG1 = 0x00000001,
    FLAG2 = 0x00000010,
    

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

    我需要创建带位偏移量的枚举还是可以使用升序整数,如:

    FLAG1 = 1;
    FLAG2 = 2;
    
    4 回复  |  直到 10 年前
        1
  •  27
  •   jtbandes    16 年前

    您需要偏移位,否则无法提取单个标志。如果您有对应于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) { ...
    
        2
  •  6
  •   Mark Byers    16 年前

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

    TEXTUREFLAGS_POINTSAMPLE = 1,
    TEXTUREFLAGS_TRILINEAR = 16,
    

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

    您应该改为使用这些值:

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

    这是两种力量的力量,它们可以通过按位或任何方式组合而不产生碰撞。

        3
  •  4
  •   Paul Tomblin    16 年前

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

        4
  •  2
  •   James    16 年前

    将标志视为32位的数组(布尔值)

    使用1<<位索引(其中位索引是从零开始的,所以0-31)打开其中一个位。 用~(1<<位索引)关闭一个 检查它是否打开或关闭,以及是否使用(1<<位索引)

    一旦你克服了数字或/和逻辑或/之间的差异,它就会全部点击。 那么你会喜欢十六进制符号!