Cでフラグを削除するにはどうすればよいですか?


148

いくつかのフラグを保持する変数があり、それらの1つを削除したいと思います。しかし、それを削除する方法がわかりません。

これがフラグの設定方法です。

my.emask |= ENABLE_SHOOT;

6
SOの質問「Cで1つのビットをどのように設定、クリア、トグルするへの回答が役立つ場合があります。
撮影

回答:


339

短い答え

設定を解除するフラグのビットごとのNOT演算を使用して、現在の値に対してビットごとのAND演算を実行したい。ビットごとのNOTは、すべてのビットを反転します(つまり、0 => 1、1 => 0)。

flags = flags & ~MASK;またはflags &= ~MASK;

長い答え

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

設定を解除する値のビットごとの否定をビットごとのANDで実行する場合。

value = value & ~ENABLE_SHOOT // 00000001

あなたは実際にやっています:

      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:お役に立てて嬉しいです。最初は誰かが紙でそれを説明するのに10分かかるまで、ビット単位の操作を理解するのに苦労しました。
デニス

1
@Dennis私はXORがすでに設定されているフラグを削除するように機能すると思っていました。notification.sound ^= Notification.DEFAULT_SOUND;
likejudo 2014

3
ウォークを有効にするにはどうすればよいですか?X以来| 0 == X
Unikorn 2014

@Unikornが指摘しているように、フラグ値のゼロは、ORをオンにしようとしたり、ANDをオフにしようとしたりしても、正しく機能しません。
RenniePet

ウォークを有効にするには、実行を無効にする必要があります(ビット1を0に設定したままにします)。ENABLE_ *フラグは10進数ではなく、オンまたはオフの2進数と考えてください。ただし、ウォークを明示的に有効または無効することはできません。
Jacob Degeling 2017


13

操作される変数がintより大きい場合、 'and not'式で使用される値も同じである必要があることに注意することが重要です。実際、小さい型を使用することで回避できる場合もありますが、定数が十分な大きさであることを確認するために型の接尾辞を使用することがおそらく最善の奇妙なケースがあります。


5
非自明なコーナーケースをキャッチするための+1。これを回避する1つの方法は、代わりにflags -= flags & MY_FLAG;(または必要に^=応じて)を使用することです。
R .. GitHub ICEのヘルプ停止

1
@R ..ビットをトグルし、多くのフラグのどれが設定されているかわからない場合を除いて、「^ =」を使用したでしょう。右端の2つのビットがゼロであることを確認したい場合、例えばmy.emask: '0 1 0 1' input: '0 0 1 1' with: '^ =' '0 1 1 0' with: '&〜 '' 0 1 0 0 '
Hector
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.