7

我扫描了一个 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,嗯……很漂亮。

问题是:有没有办法在查看值为 128 的 int 变量的第一个字节时获得 128?

4

4 回答 4

5

出于同样的原因(unsigned int)(char)1284294967168:char在最常用的系统上默认签名。128 不适合有符号的 8 位数量,因此当您将其转换为 时char,您会得到 -128(十六进制的 0x80)。

然后,当您将 -128 转换为 时unsigned int,您会得到 2 32 - 128,即 4294967168。

如果您想获得 +128,请使用 anunsigned char而不是char.

于 2012-11-07T18:35:56.307 回答
0

正如评论所指出的,看起来这里发生的事情是你遇到了奇怪的二进制补码。在您的最后一次转换中,由于您没有使用unsigned char,因此字节的最高位用于指示正​​值或负值。然后,您只有 8 位中的 7 位来表示您的值,为您提供 0-127 的正数范围(总体为 -128-127)。

如果超出此范围,则它会回绕,并得到 -128,当它被转换回 an 时,unsigned int将导致该异常大的值。

于 2012-11-07T18:37:42.527 回答
0

char在此处签名,因此在您的第二个示例中,*((char *)&a + 1) = ((char)256 +1) = (0+1) = 1编码为0b00000000000000000000000000000001,因此变为 1 作为无符号整数。

在您的第三个示例中,*((char *)&a) = (char)128 = (char)-127编码为0b10000000000000000000000000000000,即 2<<31,即 4294967168

于 2012-11-07T18:32:55.220 回答
0
int a = 128;
cout << (unsigned int) *((unsigned char *)&a);

Also all of your code is dependent on running on a little endian machine.

Here's how you should probably be doing these things:

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);
于 2012-11-07T18:39:48.903 回答