先看一段代码:
http://codepad.org/GZXrvsUE
1 #include"stdio.h" 2 int main() 3 { 4 char a=0xff; 5 if(a==0xff) 6 { 7 printf("char a is 0xff\n"); 8 } 9 else 10 { 11 printf("char a is not 0xff\n"); 12 } 13 return 0; 14 }
结果输出是char a is not 0xff,很意外吧,因为a是带符号的,if比较的时候a被扩展成了四个字节的int(32位处理器下的做法)
要是再加一句就更明了了。
printf("int a is %x",a); //结果是 int a is 0xffffffff
再次印证了姚新颜大哥在《c/c++深层探索》里写的那样,为了简便,K&R C中的变量只保留了整型和浮点型两种类型,其它的都是转化使用的。
的确,char a在内存里存的是0xff不差,但在if中拿来比较的时候被当作int来比较了,而a又默认被声明为了有符号数(即使char也如此,被当作整数处理的),于是为了保证数据的正确性,就把它扩展成0xffffffff了(若用一个字节存储整数,-1表示为0xff,若用四个字节存储,-1就是0xffffffff了)。或许是这样,比较的时候,先把内存里的数拿到寄存器里处理一下,做了符号扩展,再给CPU判断。
另外,用vs将上述代码当作c++编译结果也是如此,codepad直接提示编译通不过http://codepad.org/JXiiUo2c
再看下一段代码
1 //调试环境VS2008 2 #include "stdafx.h" 3 4 #include "stdio.h" 5 int _tmain(int argc, _TCHAR* argv[]) 6 { 7 __int8 vara=0xff; 8 int varb; 9 int varc; 10 int vard; 11 int vare; 12 int varf; 13 int varg; 14 varb=(__int8)vara; 15 varc=(int)vara; 16 vare=*((__int8 *)&vara); 17 varf=*((int *)&vara); 18 varg=vara&0xff; 19 vara=getchar(); 20 return 0; 21 }