c/c++语言里面的带符号整数扩展

 

 

 

先看一段代码:

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

http://codepad.org/Q4athPaJ

 

再次印证了姚新颜大哥在《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 }
View Code

程序很简单,目的是想要将变量的值0xff送到各个比他长的变量里面去,现在为止,只用varf达到了目的

其实将vara声明改成unsigned就能正确输出的:

unsigned __int8 vara=0xff;

varb=(unsigned __int8)vara;//
varc=(int)vara;
vare=*((unsigned __int8 *)&vara);

虽然改成unsigned __int8 vara=0xff; 存储的内容根本没有改变。。。。但扩展时情况就不一样了

说不清楚 建议读姚新颜大哥的《C语言标准与实现》

 

又改了一下程序 测试

 1 #include "algorithm"
 2 #include "set"
 3 #include "string"
 4 #include"iostream"
 5 #include "map"
 6 using namespace std;
 7 
 8 //#include "stdafx.h"
 9 //#include "wchar.h"
10 #define  _TCHAR char
11 #include "stdio.h"
12 int main(int argc, _TCHAR* argv[])
13 {
14     //unsigned char vara=0xff;
15     char vara=0xff;
16     int varb;
17     int varc;
18     int vard;
19     int vare;
20     int varf;
21     int varg;
22     int varh;
23     int vari;
24     unsigned int varj;
25     varb=(__int8)vara;
26     varc=(int)vara;
27     vare=*((__int8 *)&vara);
28     varf=*((int *)&vara);
29     varg=vara&0xff;
30     varh=(unsigned int)vara;
31 
32     vari=*(unsigned *)&vara;    
33     varj=(unsigned int)vara;
34     printf("vara is: %8x\n",vara);
35     printf("varb is: %8x\n",varb);
36     printf("varc is: %8x\n",varc);
37     printf("vard is: %8x\n",vard);
38     printf("vare is: %8x\n",vare);
39     printf("varf is: %8x\n",varf);
40     printf("varg is: %8x\n",varg);
41     printf("varh is: %8x\n",varh);
42     printf("vari is: %8x\n",vari);
43     return 0;
44 }
45 //--------------------------------------------------
46 //Release下的运行结果
47 //E:\testproc\Mic\tecpp\Release>tecpp.exe
48 //  vara is: ffffffff
49 //  varb is: ffffffff
50 //  varc is: ffffffff
51 //  vard is: 7204b6ff
52 //  vare is: ffffffff
53 //  varf is: 7204b6ff
54 //  varg is:       ff
55 //  varh is: ffffffff
56 //  vari is: 7204b6ff
57 //
58 //E:\testproc\Mic\tecpp\Release>
59 //  --------------------------------------------------
60 //  Debug下的运行结果
61 //E:\testproc\Mic\tecpp\Release> ..\debug\tecpp.exe
62 //  vara is: ffffffff
63 //  varb is: ffffffff
64 //  varc is: ffffffff
65 //  vard is: cccccccc
66 //  vare is: ffffffff
67 //  varf is: ccccccff
68 //  varg is:       ff
69 //  varh is: ffffffff
70 //  vari is: ccccccff
测试程序

 

最后发现这种情况还是采用按位与操作比较没麻烦(var=vara&0xff;//只取最后一个字节)

posted on 2013-06-28 11:37  zhiying678  阅读(678)  评论(0编辑  收藏  举报

导航