所以当我输入以下命令时
#include <stdio.h>
int main() {
int myInt;
myInt = 0xFFFFFFE2;
printf("%d\n",myInt);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是-30
.
我得到了两个补码的想法但是当我直接输入-30时我也得到了相同的数字.所以我的问题是为什么我会以十六进制形式写出我的号码?如果我使用十六进制形式,编译器如何区分我的意思是0xFFFFFFE2是-30的二进制补码还是值4294967266?
这里有一些误解,所有这些都可以通过重新审视第一原则来解决:
数字是一个数字.
当你写小数字42
时,就是数字42.
当你写十六进制文字时0x2A
,那仍然是数字42.
将这些表达式中的任何一个分配给a时int
,int
包含数字42.
数字是一个数字.
你使用哪个基地并不重要.它什么都没改变.以十六进制编写文字,然后将其分配给一个int
并不会改变发生的事情.它没有神奇地使数字被解释,处理或表示任何不同.
数字是一个数字.
你在这里做的是分配0xFFFFFFE2
,即号码4294967266 myInt
.该数字大于int
平台上[signed]的最大值,因此它会溢出.结果是未定义的,但你碰巧看到"回绕"到-30,可能是由于两个补码表示如何工作并在计算机的芯片和内存中实现.
而已.
它与十六进制无关,因此在十六进制和十进制文字之间没有"选择".如果你使用十进制文字会发生同样的事情:
myInt = 4294967266;
Run Code Online (Sandbox Code Playgroud)
此外,如果您正在寻找一种"触发"这种环绕行为的方法,请不要这样做,因为溢出具有未定义的行为.
如果你要处理的原始比特和字节组成myInt
,你可以通过它的别名char*
,unsigned char*
或者std::byte*
和周围的方式打球.