C/set清除切换中的标志
我对下面的代码的作用感到困惑,我知道第1行设置了一个标志,第2行清除了一个标志,第3行切换了一个标志C/set清除切换中的标志,c,set,toggle,flags,C,Set,Toggle,Flags,我对下面的代码的作用感到困惑,我知道第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
#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
}
#包括
#定义SCC_150_A 0x01
#定义SCC_150_B 0x02
#定义SCC_150_C 0x04
无符号整数标志=0;
主要(){
标志|=SCC_150_A;//第1行
标志&=~SCC_150_B;//第2行
flags^=SCC_150_C;//第3行
printf(“结果:%d\n”,标志);//第4行
}
我不明白的是第4行的输出是什么?设置/清除/切换
0x01
0x02
和0x04
上的标志会有什么影响?宏定义了需要表示单个位的常量:
macro hex binary
======================
SCC_150_A 0x01 001
SCC_150_B 0x02 010
SCC_150_C 0x04 100
最初标志
为0
然后它有:
因此,最终结果是1012,或十进制的5。宏定义了每个常量都需要一个位来表示:
macro hex binary
======================
SCC_150_A 0x01 001
SCC_150_B 0x02 010
SCC_150_C 0x04 100
最初标志
为0
然后它有:
因此,最终结果是1012,或十进制的5。首先,我将使用二进制数,因为用它们更容易解释。最终,十六进制数也是如此。还请注意,我将变量缩短为
unsigned char
,以便有一个较短的值进行写操作(8位vs.32位)。最终结果类似,只是没有前导数字
让我们从以下值开始:
0x01 = 0000 0001
0x02 = 0000 0010
0x04 = 0000 0100
因此,在替换常量/宏之后,第一行基本上是:
flags |= 0000 0001
这将执行按位or运算,如果任何输入值在该位置为1
,则结果中的一位为1
。由于标志
的初始值为0
,因此这将与赋值或加法一样工作(通常不会,请记住这一点)
结果是将标志设置为0000 0001
flags &= ~0000 0010
这里我们有两个操作,首先是~
,按位补码运算符。这实际上是翻转所有的值位。因此,0000 0010
变为11111101
(0xfd
十六进制)。然后使用按位and运算符,如果两个输入值在特定位置都是1
,则结果位仅设置为1
。如您所见,这将基本上导致右侧的第二位被设置为0
,而不接触任何其他位
flags: 0000 0001
op: 1111 1101
----------------
and: 0000 0001
因此,此操作的结果为0000 0001
(0x01
十六进制)
最后一个操作是按位异或(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
首先,我将使用二进制数,因为使用它们更容易解释。最终,十六进制数也是如此。还请注意,我将变量缩短为unsigned char
,以便有一个较短的值进行写操作(8位vs.32位)。最终结果类似,只是没有前导数字
让我们从以下值开始:
0x01 = 0000 0001
0x02 = 0000 0010
0x04 = 0000 0100
因此,在替换常量/宏之后,第一行基本上是:
flags |= 0000 0001
这将执行按位or运算,如果任何输入值在该位置为1
,则结果中的一位为1
。由于标志
的初始值为0
,因此这将与赋值或加法一样工作(通常不会,请记住这一点)
结果是将标志设置为0000 0001
flags &= ~0000 0010
这里我们有两个操作,首先是~
,按位补码运算符。这实际上是翻转所有的值位。因此,0000 0010
变为11111101
(0xfd
十六进制)。然后使用按位and运算符,如果两个输入值在特定位置都是1
,则结果位仅设置为1
。如您所见,这将基本上导致右侧的第二位被设置为0
,而不接触任何其他位
flags: 0000 0001
op: 1111 1101
----------------
and: 0000 0001
因此,此操作的结果为0000 0001
(0x01
十六进制)
最后一个操作是按位异或(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
我不太理解您的问题-您的问题是什么?你到底不明白什么?我不太明白你的问题-你有什么问题?你到底不明白什么?