#include<stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
printf("%.2x ", start[i]);
printf("\n");
}
int main()
{
short sx = -12345;
unsigned short usx = sx;
int x = sx;
unsigned ux = usx;
printf("sx = %d:\t", sx);
show_bytes((byte_pointer)&sx, sizeof(short));
printf("usx = %u:\t", usx);
show_bytes((byte_pointer)&usx, sizeof(unsigned short));
printf("x = %d :\t ", x);
show_bytes((byte_pointer)&x, sizeof(int));
printf("ux = %u:\t", ux);
show_bytes((byte_pointer)&ux, sizeof(unsigned));
return 0;
}
分析:
补码转化为无符号数时,-12345和53191的16位无符号表示(二进制)是完全一样的。当发生强制转化时,不改变位,只改变数值,也就是unsigned short usx = sx; usx的数值是53191而不是-12345.
(补充,把无符号转换为补码时,也是位模式不变。所以有T2U32(-1)=UMax32)
sx的补码表示和usx的无符号表示在16位字长时的十六进制表示是一样的,在32位字长的时候是不同的。
-12345的十六进制表示是0xFFFFCFC7, 53191的十六进制表示是0x0000CFC7。前者是符号扩展,在前面加了16位最高有效位1,表示成十六进制就是0xFFFF。后者是零扩展,在前面加16位的0,十六进制就是0x0000.