类型转换

int main (int argc, char **argv)
{
    unsigned int a = 0xFFFFFFF7;
    unsigned char i = (unsigned char)a;
    char* b = (char*)&a;
    printf("i = %08x
b = %08x
",i,*b);
    return 0;
} /* ----- End of main() ----- */
输出
i = 000000f7
b = fffffff7

uint变量赋值给uchar变量时会发生字节截断(3位及高于3位的部分将被程序自动丢弃),因此i输出最低位字节。

而 char* b = (char*)&a 中&a可以认为是个指向 unsigned int类型数据的指针,(char *)&a则把&a强制转换成 char *类型的指针,并且这个时候发生了截断!截断后,指针b只指向oxf7这个数据(在X86系列的机器中,数据的存储是“小端存储”,低地址单元存放低位数据)。

又由于指针b是 char *型的,属于有符号数,所以有符号数0xf7在printf()的作用下输出fffffff7 (这个过程中其实发生了参数类型提升default argument)。

详见:弱类型?C语言参数提升带来的一个陷阱

1 void main()
  2 {
  3     unsigned int a = 0xAAAAAAA7;
  4     unsigned char i = (unsigned char)a;
  5     char* b = (char*)&a;
  6     unsigned char* c = (unsigned char*)&a;
  7 
  8     printf("%08x, %08x, %08x,%08x
", a, i, *b, *c);
  9 }
输出的结果是:
aaaaaaa7, 000000a7, ffffffa7,000000a7

按照书中的理论,这里*b和*c明显是无法解释的。经过查阅相关的资料,我认为可以这样解释,其实程序的5行和6行也是进行截断。b或者c是指向a的内存,但是只是指向a的低字节内存。也就是0xA7。b是char*类型,所以把0xA7解释为负数,所以*b输出结果为0xffffffa7,等于-89。而c,为unsigned char*类型,*c的输出为167。

参考:

程序员面试宝典中的一个错误 char * b=(char *)&a

《程序员面试宝典》中的一个错误

原文地址:https://www.cnblogs.com/zhanbiqiang/p/4009014.html