¿Cómo puedo eliminar una bandera en C?

Respuestas:

339

Respuesta corta

Desea realizar una operación AND a nivel de bit en el valor actual con una operación NOT a nivel de bit del indicador que desea desarmar . Un bit a bit NO invierte cada bit (es decir, 0 => 1, 1 => 0).

flags = flags & ~MASK;o flags &= ~MASK;.

Respuesta larga

ENABLE_WALK  = 0    // 00000000
ENABLE_RUN   = 1    // 00000001
ENABLE_SHOOT = 2    // 00000010
ENABLE_SHOOTRUN = 3 // 00000011

value  = ENABLE_RUN     // 00000001
value |= ENABLE_SHOOT   // 00000011 or same as ENABLE_SHOOTRUN

Cuando realiza un Bitwise AND con Bitwise NOT del valor que desea desarmar.

value = value & ~ENABLE_SHOOT // 00000001

en realidad estás haciendo:

      0 0 0 0 0 0 1 1     (current value)
   &  1 1 1 1 1 1 0 1     (~ENABLE_SHOOT)
      ---------------
      0 0 0 0 0 0 0 1     (result)
Dennis
fuente
@ Aaron: Me alegro de que haya ayudado. Inicialmente tuve problemas para entender las operaciones bit a bit hasta que alguien tardó 10 minutos en explicarlo en papel.
Dennis
1
@ Dennis, pensé que XOR funcionaría para eliminar una bandera ya establecida. notification.sound ^= Notification.DEFAULT_SOUND;
likejudo
3
¿Cómo se habilita Walk? Desde X | 0 == X
Unikorn
Como señala @Unikorn, un valor de indicador de cero no funciona correctamente, ya sea si intenta activarlo O o si intenta activarlo y desactivarlo.
RenniePet
Para habilitar la caminata, solo tiene que deshabilitar la carrera (que dejará el bit 1 establecido en 0). No piense en las banderas ENABLE_ * como números decimales, sino como números binarios, ya sea activados o desactivados. Sin embargo, aún no puede habilitar o deshabilitar explícitamente la caminata.
Jacob Degeling
82
my.emask &= ~(ENABLE_SHOOT);

para borrar algunas banderas:

my.emask &= ~(ENABLE_SHOOT|SOME_OTHER|ONE_MORE);
Ned Batchelder
fuente
13

Es importante tener en cuenta que si la variable que se manipula es mayor que un int, el valor utilizado en la expresión 'y no' también debe serlo. En realidad, a veces uno puede salirse con la suya usando tipos más pequeños, pero hay suficientes casos extraños que probablemente sea mejor usar sufijos de tipo para asegurarse de que las constantes sean lo suficientemente grandes.

Super gato
fuente
55
+1 para atrapar la caja de esquina no obvia. Una forma de evitarlo es usarlo flags -= flags & MY_FLAG;(o ^=si lo prefiere).
R .. GitHub DEJA DE AYUDAR A ICE
1
@R .. Hubiera usado '^ =', excepto que alternará los bits y, a veces, es posible que no sepa cuál de los muchos indicadores está configurado. Si quiero asegurarme de que los dos bits más correctos son cero, por ejemplo, my.emask: '0 1 0 1' input: '0 0 1 1' con: '^ =' '0 1 1 0' con: '& ~ '' 0 1 0 0 '
Héctor