0

次のコードが何をするのか混乱しています.1行目でフラグを設定し、2行目でフラグをクリアし、3行目でフラグを切り替えます。

#include <stdio.h>
#define SCC_150_A 0x01
#define SCC_150_B 0x02
#define SCC_150_C 0x04
unsigned int flags = 0;

main () {
  flags |= SCC_150_A;  // Line 1
  flags &= ~SCC_150_B; // Line 2
  flags ^= SCC_150_C;  // Line 3
  printf("Result: %d\n",flags); // Line 4
}

私が理解していないのは、4 行目の出力がどうなるかということです。0x01 0x02およびのフラグを設定/クリア/トグルすると、どのような影響があり0x04ますか?

4

2 に答える 2

2

まず、説明しやすいように 2 進数を使用します。結局は16進数でも同じです。unsigned charまた、変数を短くして、書き留める値を短くしたことにも注意してください(8 ビット対 32 ビット)。最終結果は似ていますが、先頭の数字がないだけです。

値から始めましょう。

0x01 = 0000 0001
0x02 = 0000 0010
0x04 = 0000 0100

したがって、定数/マクロを置き換えた後、最初の行は基本的に次のようになります。

flags |= 0000 0001

これは、ビットごとの or 演算を実行します。1入力値のいずれかが1その位置にある場合、結果のビットは です。の初期値が であるためflags0これは代入または追加と同じように機能します (通常はそうではないことに注意してください)。

flags: 0000 0000
op:    0000 0001
----------------
or:    0000 0001

結果はflagsに設定されてい0000 0001ます。

flags &= ~0000 0010

ここには 2 つの演算があります。最初に~、ビットごとの補数演算子があります。これが本質的に行うことは、値のすべてのビットを反転することです。したがって、 (16進数)に0000 0010なります。次に、両方の入力値が特定の位置にある場合にのみ結果ビットが設定されるビットごとの and 演算子を使用しています。ご覧のとおり、これにより、基本的に右から 2 番目のビットが他のビットに触れることなく設定されます。1111 11010xfd110

flags: 0000 0001
op:    1111 1101
----------------
and:   0000 0001

このため、この操作の結果は0000 0001( 0x0116 進数) になります。

flags ^= 0000 0100

最後の操作はビットごとの排他的論理和 (xor) で1、入力ビットが一致しない (つまり、異なる) 場合にのみビットを設定します。これにより、オペランドに設定されたビットを切り替えるという単純な動作が発生します。

flags: 0000 0001
op:    0000 0100
----------------
xor:   0000 0101

この場合、結果は0000 0101( 0x0516 進数) になります。

最後の操作を明確にするために、ここでは xor が最も理解しにくいと思うので、元に戻しましょう。

flags: 0000 0101
op:    0000 0100
----------------
xor:   0000 0001

ご覧のとおり、右から 3 番目のビットは両方の入力で等しいので、結果は0ではなくになり1ます。

于 2013-08-15T10:41:53.647 に答える