Comment puis-je supprimer un indicateur en C?


Réponses:


339

Réponse courte

Vous souhaitez effectuer une opération ET au niveau du bit sur la valeur actuelle avec une opération NON au niveau du bit de l' indicateur que vous souhaitez annuler . Un NOT au niveau du bit inverse chaque bit (c'est-à-dire 0 => 1, 1 => 0).

flags = flags & ~MASK;ou flags &= ~MASK;.

Longue réponse

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

Lorsque vous effectuez un ET au niveau du bit avec PAS au niveau du bit de la valeur que vous souhaitez annuler.

value = value & ~ENABLE_SHOOT // 00000001

vous faites réellement:

      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: Je suis content que cela ait aidé. Au départ, j'ai eu du mal à comprendre les opérations au niveau du bit jusqu'à ce que quelqu'un prenne 10 minutes pour l'expliquer sur papier.
Dennis

1
@Dennis Je pensais que XOR travaillerait pour supprimer un indicateur déjà défini. notification.sound ^= Notification.DEFAULT_SOUND;
likejudo

3
Comment activer Walk? Depuis X | 0 == X
Unikorn

Comme le souligne @Unikorn, une valeur d'indicateur de zéro ne fonctionne pas correctement, que ce soit si vous essayez de OUI ou si vous essayez de OUI.
RenniePet

Pour activer la marche, il vous suffit de désactiver la course (ce qui laissera le bit 1 à 0). Ne considérez pas les indicateurs ENABLE_ * comme des nombres décimaux, mais comme des nombres binaires, activés ou désactivés. Cependant, vous ne pouvez toujours pas activer ou désactiver explicitement la marche.
Jacob Degeling

82
my.emask &= ~(ENABLE_SHOOT);

pour effacer quelques drapeaux:

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

13

Il est important de noter que si la variable manipulée est plus grande qu'un int, la valeur utilisée dans l'expression 'and not' doit l'être également. En fait, on peut parfois s'en tirer en utilisant des types plus petits, mais il y a suffisamment de cas étranges pour qu'il soit probablement préférable d'utiliser des suffixes de type pour s'assurer que les constantes sont suffisamment grandes.


5
+1 pour attraper le cas d'angle non évident. Une façon de l'éviter est d'utiliser à la place flags -= flags & MY_FLAG;(ou ^=si vous préférez).
R .. GitHub STOP AIDER ICE

1
@R .. J'aurais utilisé '^ =' sauf que cela fera basculer les bits et que parfois vous ne savez peut-être pas lesquels des nombreux indicateurs sont définis. Si je veux m'assurer que les deux bits les plus à droite sont zéro, par exemple my.emask: '0 1 0 1' entrée: '0 0 1 1' avec: '^ =' '0 1 1 0' avec: '& ~ '' 0 1 0 0 '
Hector
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.