14

最近、C および C++ の「フラグ」の例をいくつか目にしましたが、それらがどのように機能するのかよくわかりません。いくつかのソース コードを見た後、次のようにフラグ値が 16 進数で定義されていることが多いことに気付きました。

FLAG1 = 0x00000001,
FLAG2 = 0x00000010,

私の直感は、これらの価値が組み合わされていることを示唆しています。フラグは、すべてのフラグ値を 1 つの int に結合することによって機能しますか? これらの両方を使用した場合FLAG1 | FLAG2、結果はどうなります0x00000011か?

ビットオフセットを使用して列挙型を作成する必要がありますか、それとも昇順の整数を使用できますか?

FLAG1 = 1;
FLAG2 = 2;
4

4 に答える 4

36

ビットをオフセットする必要があります。そうしないと、個々のフラグを抽出する方法がありません。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) { ...
于 2010-09-04T19:29:25.863 に答える
10

最初の方法は、最も効率的な方法でビットを使用していません。最初の例では、16 進表記を使用しており、次と同等です。

TEXTUREFLAGS_POINTSAMPLE = 1,
TEXTUREFLAGS_TRILINEAR = 16,

2 番目の方法では、毎回 1 ずつ増加しているように見えます。結合された値が別のフラグと同じになる可能性があるため (たとえば、1 | 2 == 3)、フラグを結合する場合、これは機能しません。

代わりに次の値を使用する必要があります。

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

これらは 2 のべき乗であり、bitwise-or を使用して任意の方法で衝突を起こさずに組み合わせることができます。

于 2010-09-04T19:28:21.830 に答える
5

このようなフラグはバイナリ値であるため、1、2、4、8、16、32、64、128 を 1 バイトに、または 2 の累乗を最大 2^31 まで int に組み合わせることができます。これらはバイナリ値であるため、それらを一緒に「or」することができます。たとえば、1、2、4 を「or」すると、最終的に 7 になります。そして、「and」を使用して必要なビットを抽出することができます。したがって、いくつかのフラグを or'ed にした int があり、「4」ビットが設定されているかどうかを確認したい場合は、次のように言えますif (flag & 4)。 「4」ビットが設定されます。

于 2010-09-04T19:32:05.467 に答える
4

フラグは 32 ビットの配列 (ブール値) と考えてください。

これらのビットの 1 つをオンにするには、1 << BitIndex (BitIndex は 0 から始まるため、0 ~ 31) で OR します。1 つをオフにするには、~(1 << BitIndex) で AND します。あなたはそれを(1 << BitIndex)でANDします

デジタル OR/AND と論理 OR/AND の違いを理解したら、すべてがうまくいきます。それなら、16 進表記に感謝します。

于 2010-09-04T19:47:10.007 に答える