Paso 1: antecedentes
Por ejemplo, podríamos declarar un entero de 8 bits como una bandera para mostrar algunas instrucciones o no o no:
unsigned char DISPLAY_INSTRUCTIONS = 1;
Utilizando un valor de 8 bits nos permitiría tener 28 valores posibles, o 256 banderas únicas. Cada bandera sería tomar un byte de los recursos, ya sea en disco o en base de la RAM. También podríamos utilizar otros valores estándar para la bandera como uint16_t, un valor de 16 bits almacenar banderas únicas hasta 65.535, probablemente mucho más de lo que podríamos necesitar o utilice. Pero ¿qué pasa si sólo teníamos, dice, 6 banderas que necesitábamos para seguir? En el esquema anterior se requeriría de seis bytes, un byte para cada bandera, pero usando bits podríamos almacenamos todas las seis banderas (y algunos) dentro de un solo byte.
Si usted está familiarizado con números binarios, podría tomar un momento y lea mi instructable sobre bases de número, que incluye el binario o encontrar una serie de tutoriales en línea. Supondré que ya tienes un paso conocimiento de números binarios cómo se ponen juntos. Así, usted puede preguntar ¿cómo uno utiliza los bits individuales dentro de un número entero como una bandera para el uso en software de código? Por lo general, esto se hace asignando un poco a "1" o "0" y basado en su ubicación dentro de los enteros, se puede utilizar para una afirmación o una negación del valor especificado. Por ejemplo, tomar un 8-bit número, digamos, cero y lo mira.
0000 0000
OK, nada emocionante aquí. Ahora en la posición de la 1, que sea 1:
0000 0000
Podemos hacer lo mismo para la ubicación de los dos:
0000 0010
o en lugar de cuatro:
0000 0100
o tal vez el 32 y 8 Ubicación:0010 1000
¿Qué números de hacer estos tirones de bit? No nos importa. Nos estamos sólo preocupados por los bits individuales dentro de la cantidad en este caso. Para asignar fácilmente valores de indicador a bits, es común utilizar el idioma siguiente:
#define FLAG1 0x01 // 0000 0001
#define FLAG2 0x02 // #define FLAG1 0x01 // 0000 0001
#define FLAG2 0x02 // 0000 0010
#define FLAG3 0x04 // 0000 0100
#define FLAG4 0x08 // 0000 1000
#define FLAG5 0x10 // 0001 0000
#define FLAG6 0x20 // 0010 0000
#define FLAG7 0x40 // 0100 0000
#define FLAG8 0x80 // 1000 0000
#define FLAG3 0x04 // unsigned char myFlags = 0x00; myFlags |= FLAG5;
#define FLAG4 0x08 // 0000 1000
#define FLAG5 0x10 // 0001 0000
#define FLAG6 0x20 // 0010 0000
#define FLAG7 0x40 // 0100 0000
#define FLAG8 0x80 // 1000 0000
Allí hemos definido nuestras banderas. Tomar nota del patrón en el número hexadecimal y su representación binaria. Por lo tanto, si es FLAG5, entonces la bandera entero habría poco 5 conjunto (utilizando un índice basado en 1, contrario a la más común basado en 0, pero no es importante para nosotros ahora mismo). Crear la variable bandera y configurar FLAG5 tiene este aspecto:
myFlags &= ~FLAG3;
Nos o las banderas por lo que cualquier banderas existentes se mantienen conservan. Si usted y las banderas, usted tendrá que escribir sobre cualquier banderas existentes con la máscara de bits el ANDing que. Esto es útil cuando desea borrar una bandera:
#define FLAG28 0x00400000
Conjuntos anteriores FLAG3 a cero. Aviso que son ANDing con el complemento de la bandera.
Pero qué pasa si usted tiene:
#define FLAG_1 0x01
#define FLAG_2 0x02
#define FLAG_3 0x04
#define FLAG_4 0x08
...
uint32_t _flags;
// set a flag
_flags |= FLAG_2;
// clear a flag
_flags &= ~FLAG_3;
// test bit flag
if (_flags & FLAG_4)
do_something();
¿y se intenta establecer con nuestro entero de 8 bits? Tendrás un rebosadero con tamaños de enteros no coinciden y sale un error, probablemente en tiempo de ejecución y tiempo de compilación no porque el compilador será generalmente promover o de lo contrario convertir implícitamente su bandera constante en el tipo que está siendo operado en. Esto no es siempre el caso, pero a menudo es. Esto puede crear duro atrapar insectos y la peor clase: errores de tiempo de ejecución. Son malos porque pueden ser más difíciles de rastrear, más difícil de replicar e introducido a los usuarios, que no quieres hacer en la medida de lo posible.
¿Además, lo que si es necesario una nueva bandera, decir, FLAG9 pero con el valor 0x0080 por cualquier motivo? Tienes 1) extender su bandera tipo para acomodar el tamaño más grande y 2) Inserte la bandera en sus declaraciones de bandera y numerar todas las banderas detrás de él. Eso simplemente no es factible y definitivamente no.
¿Qué hacer acerca de estos problemas? ¿Cómo garantizar seguridad de tipos y extensibilidad a nuestras banderas? Dar vuelta la página y descúbrelo!