我很困惑下面的代码是做什么的,我理解第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行的输出会是什么?设置clearingtoggling标志的效果是什么?0x01
0x02
和 0x04
?
这些宏定义的常量,每个常量都需要一个位来表示。
macro hex binary
======================
SCC_150_A 0x01 001
SCC_150_B 0x02 010
SCC_150_C 0x04 100
初始化 flags
是0。
那么它有。
SCC_150_B
.因此,最终结果是1012或十进制的5。
首先,我打算用二进制数,因为用它们解释起来更容易。最后,用十六进制数也是一样的。另外,请注意,我把变量缩短为 unsigned char
以获得一个较短的值(8位与32位)。最终的结果是相似的,只是没有前导数字。
让我们从值开始。
0x01 = 0000 0001
0x02 = 0000 0010
0x04 = 0000 0100
所以在替换了constantmacro之后,第一行基本上是这样的:
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和运算符,其中一个结果位只设置为 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
.