Come posso rimuovere un flag in C?


Risposte:


339

Risposta breve

Si desidera eseguire un'operazione AND bit a bit sul valore corrente con un'operazione Bit a bit NOT del flag che si desidera annullare . Un bit a bit NON inverte ogni bit (ovvero 0 => 1, 1 => 0).

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

Risposta lunga

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

Quando si esegue un bit a bit E con bit a bit NOT del valore che si desidera annullare.

value = value & ~ENABLE_SHOOT // 00000001

stai effettivamente facendo:

      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)

@Aaron: sono contento che abbia aiutato. Inizialmente ho avuto difficoltà a capire le operazioni bit per bit fino a quando qualcuno non ha impiegato 10 minuti per spiegarlo sulla carta.
Dennis,

1
@Dennis Pensavo che XOR avrebbe funzionato per rimuovere una bandiera già impostata. notification.sound ^= Notification.DEFAULT_SOUND;
likejudo

3
Come si abilita Walk? Poiché X | 0 == X
Unikorn,

Come sottolineato da @Unikorn, un valore di flag pari a zero non funziona correttamente, sia se si tenta di OPPURE attivarlo o se si tenta di SPEGNERE.
RenniePet,

Per abilitare la camminata, devi solo disabilitare la corsa (che lascerà il bit 1 impostato su 0). Non pensare ai flag ENABLE_ * come numeri decimali, ma come numeri binari, attivati ​​o disattivati. Tuttavia, non è ancora possibile abilitare o disabilitare esplicitamente la camminata.
Jacob Degeling,

82
my.emask &= ~(ENABLE_SHOOT);

per cancellare alcune bandiere:

my.emask &= ~(ENABLE_SHOOT|SOME_OTHER|ONE_MORE);

13

È importante notare che se la variabile manipolata è più grande di un int, anche il valore usato nell'espressione 'e non' deve essere. In realtà, a volte si può cavarsela usando tipi più piccoli, ma ci sono casi abbastanza strani che probabilmente è meglio usare suffissi di tipo per assicurarsi che le costanti siano abbastanza grandi.


5
+1 per catturare la custodia angolare invisibile. Un modo per evitarlo è invece usare flags -= flags & MY_FLAG;(o ^=se preferisci).
R .. GitHub smette di aiutare ICE il

1
@R .. Avrei usato '^ =' tranne che avrebbe attivato / disattivato i bit e talvolta potresti non sapere quali dei molti flag sono impostati. Se voglio assicurarmi che i due bit più a destra siano zero, ad esempio my.emask: '0 1 0 1' input: '0 0 1 1' con: '^ =' '0 1 1 0' con: '& ~ '' 0 1 0 0 '
Ettore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.