2010-10-22 16 views
30

Apple a veces usa el operador Bitwise-Shift en sus enumeración de definiciones. Por ejemplo, en el archivo CGDirectDisplay.h que forma parte del núcleo de gráficos:¿Por qué usar el operador Bitwise-Shift para valores en una definición de C enum?

enum { 
    kCGDisplayBeginConfigurationFlag = (1 << 0), 
    kCGDisplayMovedFlag   = (1 << 1), 
    kCGDisplaySetMainFlag   = (1 << 2), 
    kCGDisplaySetModeFlag   = (1 << 3), 
    kCGDisplayAddFlag   = (1 << 4), 
    kCGDisplayRemoveFlag   = (1 << 5), 
    kCGDisplayEnabledFlag   = (1 << 8), 
    kCGDisplayDisabledFlag  = (1 << 9), 
    kCGDisplayMirrorFlag   = (1 << 10), 
    kCGDisplayUnMirrorFlag  = (1 << 11), 
    kCGDisplayDesktopShapeChangedFlag = (1 << 12) 
}; 
typedef uint32_t CGDisplayChangeSummaryFlags; 

Por qué no usar simplemente incrementando int 's como en una 'normal' enumeración?

+1

Pregunta relacionada: http://stackoverflow.com/questions/2159138/c-bitwise-operator-in-enum-custom-authorization-in-mvc – Oded

+1

Hace que sea fácil ver que la enumeración son todos indicadores con solo un solo bit establecido. –

+3

En realidad, la verdadera razón, como señaló Loki, es la legibilidad. Puede usar 1, 2, 4, 8, 16 y así sucesivamente (potencias de 2) pero corre el riesgo de cometer errores, mientras que 1 << 0, 1 << 1, 1 << 2, 1 << 3 es más fácil para ingresar y leer y dejar que el compilador realice el cálculo del valor real. Si desea programar de modo inteligente, necesita saber qué puede hacer el compilador por usted y aprovechar sus capacidades. – Telemat

Respuesta

46

De esta manera puede agregar varias banderas juntas para crear un "conjunto" de banderas y luego puede usar & para averiguar si una bandera dada se encuentra en dicho conjunto.

No podría hacer eso si simplemente usa números incrementales.

Ejemplo:

int flags = kCGDisplayMovedFlag | kCGDisplaySetMainFlag; // 6 
if(flags & kCGDisplayMovedFlag) {} // true 
if(flags & kCGDisplaySetModeFlag) {} // not true 
+0

Bueno, eso explica algunas cosas para algunos códigos C++ que estoy ayudando a desenredar. ¡Gracias! – CodeMouse92

2

Esto permitirá una variable para combinar fácilmente varias banderas:

unit32_t multFlag = kCGDisplayRemoveFlag | kCGDisplayMirrorFlag | kCGDisplaySetMainFlag' 
4

Si usted tiene FLAGA = 1, FlagB = 2 y FlagC = 3, FLAGA o FlagB daría el mismo valor que FlagC. El operador de desplazamiento se utiliza para garantizar que cada combinación de banderas sea única.

63

Tal vez escribir los valores en hexadecimal (o binario) ayuda :-)

enum { 
    kCGDisplayBeginConfigurationFlag = (1 << 0), /* 0b0000000000000001 */ 
    kCGDisplayMovedFlag    = (1 << 1), /* 0b0000000000000010 */ 
    kCGDisplaySetMainFlag    = (1 << 2), /* 0b0000000000000100 */ 
    kCGDisplaySetModeFlag    = (1 << 3), /* 0b0000000000001000 */ 
    kCGDisplayAddFlag     = (1 << 4), /* 0b0000000000010000 */ 
    kCGDisplayRemoveFlag    = (1 << 5), /* 0b0000000000100000 */ 
    kCGDisplayEnabledFlag    = (1 << 8), /* 0b0000000100000000 */ 
    kCGDisplayDisabledFlag   = (1 << 9), /* 0b0000001000000000 */ 
    kCGDisplayMirrorFlag    = (1 << 10),/* 0b0000010000000000 */ 
    kCGDisplayUnMirrorFlag   = (1 << 11),/* 0b0000100000000000 */ 
    kCGDisplayDesktopShapeChangedFlag = (1 << 12) /* 0b0001000000000000 */ 
}; 

Ahora puede añadirlos (o "o" ellos) y obtener diferentes valores

kCGDisplayAddFlag | kCGDisplayDisabledFlag /* 0b0000001000010000 */ 
+1

¡Muchas gracias, eso hace que las cosas sean SUPER claras! :) –

+3

TAN claro, puede considerar establecer esto como la respuesta aceptada. – deed02392

+0

¿Cuáles serían las limitaciones con esto? ¿Habría un máximo de, digamos, 16 valores que puedes poner en esta enumeración antes de que te quedes sin posibilidades? – mylogon

0

.. porque 1<<7 parece más conciso y fácil de leer que 01000000. ¿No es así?

+2

bien para mí ... no – paulm

+0

Esto no responde a la pregunta – artman

-5

usando #define es más comprensible. pero enum podría agrupar estos valores para jugar.

+0

Esto no responde la pregunta en absoluto. – Oliver

Cuestiones relacionadas