Jak mogę usunąć flagę w C?


Odpowiedzi:


339

Krótka odpowiedź

Chcesz wykonać operację Bitwise AND na bieżącej wartości z operacją Bitwise NOT flagi, którą chcesz cofnąć . Bitowe NIE odwraca każdego bitu (tj. 0 => 1, 1 => 0).

flags = flags & ~MASK;lub flags &= ~MASK;.

Długa odpowiedź

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

Kiedy wykonujesz Bitwise AND z Bitwise NOT wartości, którą chcesz cofnąć.

value = value & ~ENABLE_SHOOT // 00000001

faktycznie robisz:

      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: Cieszę się, że pomogło. Początkowo miałem problemy ze zrozumieniem operacji bitowych, dopóki komuś nie zajęło 10 minut, aby wyjaśnić to na papierze.
Dennis,

1
@Dennis Myślałem, że XOR będzie działać, aby usunąć już ustawioną flagę. notification.sound ^= Notification.DEFAULT_SOUND;
likejudo

3
Jak włączyć Walk? Ponieważ X | 0 == X
Unikorn

Jak wskazuje @Unikorn, wartość flagi równa zero nie działa poprawnie, albo jeśli spróbujesz włączyć ją LUB, albo jeśli spróbujesz ją wyłączyć.
RenniePet

Aby włączyć chodzenie, wystarczy wyłączyć bieg (co pozostawi bit 1 ustawiony na 0). Nie myśl o flagach ENABLE_ * jako o liczbach dziesiętnych, ale jako o liczbach binarnych, włączonych lub wyłączonych. Nadal nie możesz jednak jawnie włączyć ani wyłączyć chodzenia.
Jacob Degeling

82
my.emask &= ~(ENABLE_SHOOT);

aby wyczyścić kilka flag:

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

13

Należy zauważyć, że jeśli przetwarzana zmienna jest większa niż liczba int, wartość użyta w wyrażeniu „and not” również musi być. Właściwie czasami można uciec od używania mniejszych typów, ale jest wystarczająco dużo dziwnych przypadków, że prawdopodobnie najlepiej jest użyć sufiksów typów, aby upewnić się, że stałe są wystarczająco duże.


5
+1 za złapanie nieoczywistego narożnika. Jednym ze sposobów uniknięcia tego jest użycie flags -= flags & MY_FLAG;(lub ^=jeśli wolisz).
R .. GitHub STOP HELPING ICE

1
@R .. Użyłbym '^ =' z wyjątkiem tego, że będzie to przełączać bity i czasami możesz nie wiedzieć, która z wielu flag jest ustawiona. Jeśli chcę się upewnić, że dwa najbardziej prawe bity są równe zero, np. Moja.maska: '0 1 0 1' input: '0 0 1 1' with: '^ =' '0 1 1 0' with: '& ~ '0 1 0 0'
Hector
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.