我扫描int变量的字节表示并得到一些意想不到的结果。
如果我这样做
int a = 127;
cout << (unsigned int) *((char *)&a);
我按预期得到127。如果我做
int a = 256;
cout << (unsigned int) *((char *)&a + 1);
我按预期得到1。但是如果我做的话
int a = 128;
cout << (unsigned int) *((char *)&a);
我有 4294967168 ,这是......非常喜欢。
问题是:在查看int变量的第一个字节时,有没有办法获得128,该值是128?
答案 0 :(得分:5)
出于同样的原因,(unsigned int)(char)128
是4294967168:char
默认情况下会在最常用的系统上签名。 128无法符合有符号的8位数量,因此当您将其转换为char
时,您将获得-128(十六进制为0x80)。
然后,当你将-128转换为unsigned int
时,得到2 32 - 128,即4294967168。
如果您想获得+128,请使用unsigned char
代替char
。
答案 1 :(得分:0)
char
已在此处签名,因此在您的第二个示例*((char *)&a + 1) = ((char)256 +1) = (0+1) = 1
中,编码为0b00000000000000000000000000000001
,因此将其作为无符号整数变为1。
在您的第三个示例*((char *)&a) = (char)128 = (char)-127
中,编码为0b10000000000000000000000000000000
,即2 <&lt; 31,即4294967168
答案 2 :(得分:0)
正如评论所指出的,看起来这里发生的事情是你遇到了twos complement的奇怪现象。在最后一次转换中,由于您没有使用unsigned char
,因此该字节的最高位用于指示正值或负值。然后,你只有7位代表你的价值,给你一个0-127的正数范围(-128-127整体)。
如果你超出这个范围,那么它会换行,你得到-128,当它被转换回unsigned int
时会产生异常大的值。
答案 3 :(得分:0)
int a = 128;
cout << (unsigned int) *((unsigned char *)&a);
此外,您的所有代码都依赖于在小端机器上运行。
以下是你应该如何做这些事情:
int a = 127;
cout << (unsigned)(unsigned char)(0xFF & a);
int a = 256;
cout << (unsigned)(unsigned char)(0xFF & (a>>8));
int a = 128;
cout << (unsigned)(unsigned char)(0xFF & a);