我对以下代码的作用感到困惑,我理解第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
上的标记会产生什么影响?
答案 0 :(得分:2)
宏定义了每个都需要表示一个位的常量:
macro hex binary
======================
SCC_150_A 0x01 001
SCC_150_B 0x02 010
SCC_150_C 0x04 100
最初flags
为0。
然后它有:
SCC_150_B
。因此,最终结果为101 2 ,或十进制为5。
答案 1 :(得分:2)
首先,我将使用二进制数字,因为它更容易用它们来解释。最后,它与十六进制数相同。另请注意,我将变量缩短为unsigned char
以使写入值更短(8位对32位)。最终结果是相似的,只是没有前导数字。
让我们从值开始:
0x01 = 0000 0001
0x02 = 0000 0010
0x04 = 0000 0100
因此在替换常量/宏之后,第一行基本上就是这样:
flags |= 0000 0001
如果任何输入值在该位置为1
,则执行按位或操作,结果中的位为1
。由于flags
的初始值为0
,这就像分配或添加一样(通常不会记住这一点)。
flags: 0000 0000
op: 0000 0001
----------------
or: 0000 0001
结果是flags
设置为0000 0001
。
flags &= ~0000 0010
这里我们有两个操作,首先是~
,即按位补码运算符。这基本上做的是翻转价值的所有部分。因此,0000 0010
变为1111 1101
(十六进制为0xfd
)。然后你使用bitwise和operator,如果两个输入值在特定位置都是1
,结果位只被设置为1
。正如您所看到的,这实际上会导致右侧的第二位设置为0
而不会触及任何其他位。
flags: 0000 0001
op: 1111 1101
----------------
and: 0000 0001
因此,此操作的结果为0000 0001
(十六进制为0x01
)。
flags ^= 0000 0100
最后一个操作是按位异或(xor),只有当输入位不匹配(即它们不同)时才会将位设置为1
。这导致切换操作数中设置的位的简单行为。
flags: 0000 0001
op: 0000 0100
----------------
xor: 0000 0101
在这种情况下,结果将为0000 0101
(十六进制为0x05
)。
为了澄清上一次操作,因为我认为xor可能是最难理解的,让我们回过头来说:
flags: 0000 0101
op: 0000 0100
----------------
xor: 0000 0001
如您所见,右侧的第三位在两个输入中相等,因此结果为0
而不是1
。