在vc6中运行如下代码:
#include <stdio.h>
int main()
{ unsigned int a=0xFFFFFFF7,c=0xFFFFFF67;
char *b=(char*)&a, *d=(char*)&c;
printf("b=%x, d=%x\n",*b,*d);
return 0;}
为什么输出的结果会是:b=fffffff7, d=67如果将c改为:c=0xFFFFFF87,则结果为:b=fffffff7, d=ffffff87
解释你这个问题首先要明白几个概念
1.printf的%x参数的含义:unsigned int;无符号十六进制表示(无前导0x)也就是说它要求后面给的是一个unsigned int型,而unsigned int的处理方式就是将实际的32bit输出,那么如果后面给的不是unsigned int怎么办?那就隐式的类型转换。
2.C语言如何进行隐式类型转换?就是将“较低”类型提升为“较高”类型,相应的较高类型转换为较低类型要显示的强制类型转换。 char *b=(char*)&a就是强制类型转换。较低类型和较高类型其实就是指占用的存储空间。而现在许多pc里unsigned int 和int 都是32bit的(大家可以使用sizeof来看),这样int 转换为 unsigned int 其实存储方面没有变化,但值就不对了。因为C语言里int是使用补码来记录的,也就是说负数转换为unsigned int时,就成了其补码了。关于补码是什么参看http://baike.baidu.com/view/377340.html?wtp=tt
3.强制类型转换的问题。程序中char *b=(char*)&a, *d=(char*)&c;两个强制类型转换表示 *b *d 分别是a和c的最后的8bit了,换句话说就算 a=0x000000F7,c=0x00000067;结果也一样。char默认是有符号的,所以根据以上三点,再看 printf("b=%x, d=%x\n",*b,*d);这句,*b = (char*)&a // 意味着 *b=0xF7 ,由于char有符号,也就是-9,但是char是8bit,转换为unsigned int 就是-9的补码fffffff7*d = (char*)&c //意味着 *d=0x67, 由于char有符号,也就是103,但是char是8bit,转换为unsigned int 就是103的补码103但当*d=0x87时,由于char有符号,也就是-121,但是char是8bit,转换为unsigned int 就是-121的补码0xFFFFFF87
下面把你原来函数改了一下,更清楚一点:
#include <stdio.h>
int main()
{ unsigned int a=0xFF000FF7,c=0x0000FF67;
char *b=(char*)&a, *d=(char*)&c;
printf("*b= :sizeof %u, int %d, unsigned int %u, hex %x\n",sizeof(*b),*b,*b,*b);
printf("*d= :sizeof %u, int %d, unsigned int %u, hex %x\n",sizeof(*d),*d,*d,*d);
system("pause"); return 0;}
执行结果:*b= :sizeof 1, int -9, unsigned int 4294967287, hex fffffff7*d= :sizeof 1, int 103, unsigned int 103, hex 67