最近由于工作需要展望性地研究了一下64位编程。无非就是一些int,long和pointer间转换时的注意事项。如果就兴趣的话可以去搜索一下ILP32和LP64数据模型的相关知识。我略有小得的却是间接地对基本类型间的相互转换加深了认识。这里我想说一下符号扩展的问题。符号扩展不只是在64位编程时应该注意的问题,在32位编程时同样需要注意。请先看下面的例子:
#include <stdio.h>
int main(void)
{
char c = 1<<7;
short s;
s = c;
printf("%d/n",s);
return 0;
}
由于c是有符号char类型,值是-128,s是有符号short类型,把c赋值给s后,程序输出-128似乎是理所当然的。
那么我们把c改成无符号数,程序变成如下:
#include <stdio.h>
int main(void)
{
unsigned char c = 1<<7;
short s;
s = c;
printf("%d/n",s);
return 0;
}
c是无符号char类型,值是128,s是有符号short类型,把c赋值给s后,程序输出128似乎是也理所当然的。
当我们让c是有符号的,s是无符号的时候,程序变成如下:
#include <stdio.h>
int main(void)
{
char c = 1<<7;
unsigned short s;
s = c;
printf("%d/n",s);
return 0;
}
此时程序输出65408,这是为什么呢?原因就在于符号扩展。
让我们来对比一下这3个程序中的c与s的16进制值:
程序1 程序2 程序3
c 0x80 0x80 0x80
s 0xff80 0x0080 0xff80
当负的有符号char转换成有符号short时,符号位要进行扩展,即扩展位是全1而不是全0。
那么 对于程序3,为什么有符号char转换成无符号short也进行了符号扩展呢?其实这里也是有规则的:
当有符号char转换成无符号short时,有符号char首先转换成有符号short,再转换成无符号short。
这样问题才算清晰了,无符号0xff80的值即是65408。
上述规则对于char到long,short到long的转换都是适用的。