2010-08-19 13 views
25

Tengo una declaración enum que utiliza marcas de bit y no puedo averiguar exactamente cómo usar esto.Cómo usar enumeraciones con indicadores de bit

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

supongo para almacenar múltiples colores en una colorType debería OR los bits juntos?

ColorType pinkColor = kWhite | kRed; 

Pero supongamos que me gustaría comprobar si contiene pinkColorkRed, ¿cómo voy a hacer esto?

¿Alguien me puede dar un ejemplo usando el ejemplo proporcionado ColorType?

Respuesta

32

Sí, el uso de bits OR (|) para establecer múltiples banderas:

ColorType pinkColor = kWhite | kRed; 

A continuación, utilice AND bit a bit (&) para probar si se establece un indicador:

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

El resultado de & tiene cualquier bit establecido solo si el mismo bit está establecido en ambos operandos. Como el único bit en kRed es el bit 1, el resultado será 0 si el otro operando no tiene este bit configurado también.

Si usted necesita para obtener ya sea una bandera particular, se establece como un BOOL en lugar de sólo probarlo en una condición if inmediato, comparar el resultado de la operación AND con el bit probado:

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

Nota: Este significa que si 'pinkColor' es' kRed', '(pinkColor & kRed)' se evaluará a 'kRed', * not * 1 o' YES'! Esto puede ser una trampa al asignar a un tipo pequeño como 'BOOL': si el valor es 1 << (número de bits en un 'BOOL') o superior, estará fuera de rango. Una solución común es comparar el resultado con el bit probado: 'BOOL isPink = ((pinkColor & kRed) == kRed);' Una alternativa es convertir el resultado al tipo 'bool' de C99:' isPink = (bool) (pinkColor & kRed); 'Y una forma (que no es de extrañar) que no supone que 1 está dentro del rango usaría'?: ':' isPink = (pinkColor & kRed)? SÍ: NO; ' –

+0

@PeterHosey Lecturas adicionales pertinentes para cualquier persona interesada en su comentario: http://www.bignerdranch.com/blog/bools-sharp-corners/. Por cierto, si alguien está confundido (como yo) acerca de por qué en la tierra fundir a un C99 'bool' en lugar de' BOOL' soluciona el problema, la respuesta es que los lanzamientos a 'bool' son mágicos, como se explica en http: //stackoverflow.com/questions/16934876/magic-of-casting-value-to-bool. La versión corta es: 'bool' es un alias de' _Bool' y el estándar C99 dice * "Cuando cualquier valor escalar se convierte a _Bool, el resultado es 0 si el valor se compara con a 0; de lo contrario, el resultado es 1 . "* –

Cuestiones relacionadas