以下假定测试机器为32位。
.
对于char类型的变量x而言,你虽然给x赋值0xFFFF,但编译器会对其进行截断,因为char类型的长度只有1字节,所以内存中实际存在的是0xFF,而不是0xFFFF,也因此与65535和65536都没有任何关系。至于为什么会打印出"-1",是因为"%d"要求char类型的0xFF被进行的是"带符号扩展"(对应的汇编指令为movsx),也就是说0xFF被扩展成值为0xFFFFFFFF的临时变量进行输出,此时"%d"就输出为"-1"了。如果你把输出改为"%08X"就能很容易看到这一点。还有,你可以把char x = 0xFFFF改为 unsigned char 就可以很好的看到这一点(此时进行的是"无符号扩展",对应的汇编指令为movzx,0xFF会被扩展为0x000000FF进行输出)。注:这里没有考虑 x--中的"--"问题。
.
以下是我的一些测试,环境为VC6 + Debug方式,编译时均会出现提示:"warning C4305: 'initializing' : truncation from 'const int ' to 'char '",这就说明编译器对其进行了截断。
.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char x=0xFFFF;
printf("%08X\n\n\n", x--);
return 0;
}
输出:
FFFFFFFF
.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char x=0xFFFF;
printf("%u\n\n\n", x--);
return 0;
}
输出:
4294967295
.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
unsigned char x=0xFFFF;
printf("%d\n\n\n", x--);
return 0;
}
输出:
255
.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
unsigned char x=0xFFFF;
printf("%08X\n\n\n", x--);
return 0;
}
输出:
000000FF
.
为了更清楚的说明这一问题我们不妨进一步做如下测试:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i = 0x33;
char x = 0xFFFF;
int j = 0x44;
printf("%d\n\n\n", x--);
return 0;
}
编译通过后,在printf函数那一行下断点,运行中断后查看内存,得:
0012FF74
44 00 00 00 FF CC CC CC
D....烫.
0012FF7C
33 00 00 00 C0 FF 12 00
3.......
0012FF84
39 12 40 00 01 00 00 00
9.@.....
我们可以看到0x44和0x33之间的并不是0xFFFF,而是0xFF。
说明:"FF"后面的3个"CC"是因为那3个字节是没有被用过的内存而内存又要按32位对齐所致。
=======================
晕了,发帖不支持段落之间的空行了?排版真难看,所以行与行之间加了个点"."。
[
本帖最后由 prankmoon 于 2009-8-31 22:39 编辑 ]