2010-08-19 5 views
25

Ich habe eine Enum-Deklaration mit Bit-Flags und ich kann nicht genau herausfinden, wie man das benutzt.Wie man Enums mit Bit-Flags verwendet

enum 
{ 
    kWhite = 0, 
    kBlue = 1 << 0, 
    kRed  = 1 << 1, 
    kYellow = 1 << 2, 
    kBrown = 1 << 3, 
}; 
typedef char ColorType; 

Ich nehme in einem colorType mehreren Farben speichern ich zusammen die Bits OR sollte?

ColorType pinkColor = kWhite | kRed; 

Aber angenommen, würde ich möchte überprüfen, ob pinkColorkRed enthält, wie würde ich das tun?

Wer kümmert sich um ein Beispiel mit dem mitgelieferten ColorType Beispiel?

Antwort

32

Ja, Verwendung bitweise OR (|) mehrere Flags zu setzen:

ColorType pinkColor = kWhite | kRed; 

Verwenden Sie dann bitweise AND (&) zu testen, ob ein Flag gesetzt ist:

if (pinkColor & kRed) 
{ 
    // do something 
} 

Das Ergebnis & hat irgendein Bit gesetzt, nur wenn das gleiche Bit in beide Operanden gesetzt ist. Da das einzige Bit in kRed Bit 1 ist, wird das Ergebnis 0 sein, wenn der andere Operand dieses Bit nicht ebenfalls gesetzt hat.

Wenn Sie erhalten, ob eine bestimmte Flagge als BOOL gesetzt ist, anstatt zu testen es nur in einem if Zustand unmittelbar, vergleichen Sie das Ergebnis der bitweisen UND auf dem getesteten Bit:

BOOL hasRed = ((pinkColor & kRed) == kRed); 
+18

Hinweis: Diese bedeutet, dass, wenn 'pinkColor'' kRed' ist, '(pinkColor & kRed)' zu 'kRed', * nicht * 1 oder' YES' ausgewertet wird! Dies kann ein Fehler sein, wenn Sie einem kleinen Typ wie "BOOL" zuweisen: Wenn der Wert 1 << (Anzahl der Bits in einem "BOOL") oder größer ist, liegt er außerhalb des Bereichs. Eine übliche Lösung ist es, das Ergebnis mit dem getesteten Bit zu vergleichen: 'BOOL isPink = ((pinkColor & kRed) == kRed);' Eine Alternative ist, das Ergebnis in C99s 'Bool'-Typ zu konvertieren:' isPink = (bool) (pinkColor & kRed); 'Und ein (n zugegebenermaßen ungewöhnlicher) Weg, der nicht davon ausgeht, dass 1 im Bereich liegt, würde'?: ':' isPink = (pinkColor & kRed) verwenden? JA: NEIN; ' –

+0

@PeterHosey Relevante weitere Lektüre für alle, die an Ihrem Kommentar interessiert sind: http://www.bignerdranch.com/blog/bools-sharp-corners/. By the way, wenn jemand verwirrt ist (wie ich war) darüber, warum auf der Erde Casting zu einem C99 'bool' anstelle von' BOOL' behebt das Problem, ist die Antwort, dass Casts zu 'Bool' sind Magie, wie in http diskutiert: //stackoverflow.com/questions/16934876/magic-of-casting-value-to-bool. Die Kurzversion ist: 'bool' ist ein Alias ​​von' _Bool' und der C99-Standard sagt * "Wenn ein skalarer Wert in _Bool konvertiert wird, ist das Ergebnis 0, wenn der Wert gleich mit 0 vergleicht; andernfalls ist das Ergebnis 1 . "* –