我正在做一个非常简单的计算机科学作业,围绕着C中的按位运算符,但我遇到了一个问题,我不知道为什么会发生这种情况。这是我正在运行的代码。
#include <stdio.h>
int main(int argc, char *argv[]){
int bitPattern1 = 0x10011001;
int bitPattern2 = 0x01100110;
int bitPattern3 = 0xFFFFFFFF;
int bitPattern4 = 0x00000000;
/* pair 1 */
printf("bitPattern1 & bitPattern2 = %x\n", bitPattern1 & bitPattern2);
printf("bitPattern1 && bitPattern2 = %x\n", bitPattern1 && bitPattern2);
/* pair 2 */
printf("bitPattern1 | bitPattern2 = %x\n", bitPattern1 | bitPattern2);
printf("bitPattern1 || bitPattern2 = %x\n", bitPattern1 || bitPattern2);
/* pair 3 */
printf("bitPattern1 & bitPattern3 = %x\n", bitPattern1 & bitPattern3);
printf("bitPattern1 && bitPattern3 = %x\n", bitPattern1 && bitPattern3);
/* pair 4 */
printf("bitPattern1 | bitPattern3 = %x\n", bitPattern1 | bitPattern3);
printf("bitPattern1 || bitPattern3 = %x\n", bitPattern1 || bitPattern3);
/* pair 5 */
printf("bitPattern2 & bitPattern4 = %x\n", bitPattern2 & bitPattern4);
printf("bitPattern2 && bitPattern4 = %x\n", bitPattern2 && bitPattern4);
/* pair 6 */
printf("bitPattern2 | bitPattern4 = %x\n", bitPattern2 | bitPattern4);
printf("bitPattern2 || bitPattern4 = %x\n", bitPattern2 || bitPattern4);
return 0;
}
问题发生在第4对的第一部分,它返回以下结果:
bitPattern1 | bitPattern3 = ffffffff
bitPattern1 || bitPattern3 = 1
为什么按位运算符返回“f”s我查找了文档,虽然OR运算符返回1或0但似乎该示例应该返回“11111111”。这与十六进制数字有关吗?我一直无法在谷歌上找到任何东西。
答案 0 :(得分:2)
首先,OR的输入是FFFFFFFF
的十六进制表示法,这意味着在二进制(按位)术语中它是11111111111111111111111111111111
。即它比你引用的要多得多1
(确切地说是32位)。
其次,有问题的按位OR应该确实以二进制表示法返回1111111...1
。而这正是它的回报。但是当您以 hex 表示法打印结果时,您会得到FFFFFFFF
。您使用x
中的printf
格式说明符明确请求了十六进制表示法。
不幸的是,printf
没有用于生成二进制表示法的格式说明符。但是,将十六进制转换为二进制是一项微不足道的任务,因为它是用四个二进制数字直接替换每个十六进制数字。 F
代表1111
,正如您所看到的那样,按位词,您的OR确实会产生11111111111111111111111111111111
,就像它应该的那样。
答案 1 :(得分:1)
按位运算符对参数中的所有位进行操作,在执行操作时将每个位与其对应位匹配。由于您已分配bitPattern3 = 0xFFFFFFFF
所有32位都已打开,因此对其进行按位或(|
)将使所有位都切换为打开。
逻辑OR(||
)会将参数视为true / false,并对它们执行简单的OR运算,返回true / false值
答案 2 :(得分:1)
OR
和AND
运算符有两种形式,逻辑(|| and &&
)和算术(| and &
)。
逻辑OR
和AND
将返回bool
结果。这些是你的“英语式”连词。
算术OR
和AND
在位级上工作,在每个相应的位上进行连接。
在前一种逻辑比较(|| and &&
)的情况下,您通常会比较布尔值。例如:
bool shouldUpdate = (hasNetworkConnection && isNewerVersionAvailable);
bool isDifferentLocation = (location.X != this.X || location.Y != this.Y);
对于后一种算术比较的情况,这些通常使用enum
的{{1}}值完成,如下所示:
Flags
在这种情况下,[Flags]
enum AccessModeFlags
{
None = 0x0,
Read = 0x1,
Write = 0x2,
ReadWrite = Read | Write
}
为ReadWrite
,因为它是0x3
和OR
的按位0000 0001
,从而产生0000 0010
。< / p>
答案 3 :(得分:0)
这与您的问题相关,但行:
int bitPattern1 = 0x10011001;
int bitPattern3 = 0xFFFFFFFF;
导致实现定义的行为或引发实现定义的信号,因为值0x10011001和0xFFFFFFFF超出“int”的范围,假设您使用的是32位整数。
重要的是要理解当你编写这些行时,你并没有在变量中明确地存储该位模式。您将VALUE 4294967295存储在变量中,编译器可以选择它用于存储该值的位模式。它可以做任何它喜欢的事情,只要你访问它的价值就可以得到你所放的东西 - 尽管为了简单起见,这几天的计算机几乎都使用了两个补码表示。
在这种情况下,int的最大值为2147483647,因此您的分配超出范围。但是GCC已经决定通过猜测你想要分配导致二进制补码表示FFFFFFFF的任何值来处理这个问题。其他编译器可以在此时中止该程序并仍然符合C标准。
此外,您将“int”传递给%x,如果int为负,则会导致未定义的行为。 “%x”需要“unsigned int”。
您可以通过将所有“int”更改为“unsigned int”来避免这些问题。