Wie funktionieren Flags in C?

Lesezeit: 3 Minuten

Benutzer-Avatar von Justin Meiners
Justin Meiners

Kürzlich bin ich auf mehrere Beispiele für „Flags“ in C und C++ gestoßen, und ich verstehe nicht ganz, wie sie funktionieren. Nachdem ich mir den Quellcode angesehen hatte, fiel mir auf, dass Flag-Werte oft hexadezimal definiert werden, wie zum Beispiel die folgenden:

FLAG1 = 0x00000001,
FLAG2 = 0x00000010,

Mein Instinkt legt nahe, dass diese Werte kombiniert werden. Funktionieren Flags, indem sie alle Flag-Werte in einem int kombinieren? Wenn ich beides so genutzt hätte FLAG1 | FLAG2 wäre das Ergebnis 0x00000011?

Muss ich Aufzählungen mit Bit-Offsets erstellen oder kann ich aufsteigende Ganzzahlen verwenden wie:

FLAG1 = 1;
FLAG2 = 2;

Sie müssen die Bits versetzen, sonst gibt es keine Möglichkeit, die einzelnen Flags zu extrahieren. Wenn Sie Flags hätten, die 1, 2, 3 und 4 entsprechen, und einen kombinierten Wert von 5, wie könnten Sie dann feststellen, ob es 2 & 3 oder 1 & 4 ist?

Sie können es beispielsweise auch so machen:

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
};

Dann kombinieren Sie Flaggen wie folgt:

int flags = FIRST | THIRD | FOURTH;

Und Sie extrahieren sie so:

if (flags & THIRD) { ...

Benutzeravatar von Mark Byers
Mark Byers

Ihre erste Methode besteht darin, die Bits nicht auf die effizienteste Weise zu verwenden. Im ersten Beispiel verwenden Sie die hexadezimale Notation und sie entspricht:

TEXTUREFLAGS_POINTSAMPLE = 1,
TEXTUREFLAGS_TRILINEAR = 16,

Bei der zweiten Methode scheint es, dass Sie jedes Mal nur um eins erhöhen. Dies funktioniert nicht, wenn Sie Flags kombinieren, da der kombinierte Wert mit einem anderen Flag identisch sein könnte (z. B. 1 | 2 == 3).

Sie sollten stattdessen diese Werte verwenden:

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

Dies sind Zweierpotenzen, die bitweise oder auf beliebige Weise kombiniert werden können, ohne dass es zu Kollisionen kommt.

  • Ok, aber es wird nicht funktionieren, wenn ich nur eins mache, um 20 zu mögen, oder? Ich muss immer noch die Hexadezimalzahl versetzen, damit sie sich nicht gegenseitig überschreiben, oder? Oder verstehe ich nicht, wie es funktioniert?

    – Justin Meiners

    4. September 2010 um 19:30 Uhr

  • @user425756, wenn Sie keine Zweierpotenzen verwenden, können Sie den Unterschied zwischen der 1 und der gesetzten 2 oder der gesetzten 3 nicht erkennen.

    – Paul Tomblin

    4. September 2010 um 19:33

  • Ja, das habe ich mir gedacht.

    – Justin Meiners

    4. September 2010 um 19:39 Uhr

Flags wie diese sind binäre Werte, sodass Sie 1, 2, 4, 8, 16, 32, 64, 128 in einem einzelnen Byte oder weitere Potenzen von 2 bis 2^31 in einem int kombinieren können. Da es sich um binäre Werte handelt, können Sie sie mit „oder“ verbinden. Wenn Sie also „oder“ zusammen 1,2,4 verwenden, erhalten Sie beispielsweise 7. Und Sie können das gewünschte Bit mithilfe von „and“ extrahieren. Wenn Sie also ein int mit einigen Flags haben, die miteinander verbunden sind, und sehen möchten, ob das „4“-Bit gesetzt ist, können Sie sagen if (flag & 4) und es wird wahr sein, wenn das „4“-Bit gesetzt ist.

  • Vielen Dank, das macht mehr Sinn.

    – Justin Meiners

    4. September 2010 um 19:33

Stellen Sie sich die Flags als ein Array von 32 Bits (boolesche Werte) vor.

Um eines dieser Bits auf Sie zu schalten ODER es mit 1 << BitIndex (wobei BitIndex nullbasiert ist, also 0 - 31) um eines auszuschalten, UND es mit ~(1 << BitIndex) Um zu prüfen, ob es ein- oder ausgeschaltet ist du UND es mit (1 << BitIndex)

Sobald Sie den Unterschied zwischen digitalem ODER/UND und logischem ODER/UND überwunden haben, wird alles klicken. Dann werden Sie die hexadezimale Schreibweise zu schätzen wissen!

1453170cookie-checkWie funktionieren Flags in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy