C-这段C程序为什么是这样的执行结果呢?

C-这段C程序为什么是这样的执行结果呢?

归属感 发布于 2017-02-03 字数 188 浏览 1214 回复 7
int main(void)

{
if (0xFFF0 < (short)0xFFFF)
{
printf("OK!n");
}
else
{
printf("NG!n");
}

return 0;
}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

偏爱自由 2017-11-07 7 楼

是否,16进制格式,被解释为unsigned?这个猜测是错误的,真实答案是:

C99标准说:8或16进制常量,从int开始,按照类型表示范围递增的顺序,选择最合适的类型;
那么这里就是int了,因此0xFFF0是65520,而(short)0xFFFF是-1,再经过整型提升之后,就是上述结果了。

参见C99标准6.4.4.1节第5项(语义部分的第二节)

灵芸 2017-08-12 6 楼

据我所知,0xFFF0 = 0x0000FFF0 是个正的32位整数。如果需要无符号数,要写成0xFFF0U。如果需要表示16位short,需要写成0xFFF0S(这个不太确定,我只知道可以加L)。右边的short会隐含转化为int,于是NG掉了
16进制数表示法:1. 不能直接表示负数,需要强制转换 2. 不加修饰符的话默认32位 至于出来是有符号还是无符号,参考前两条。

晚风撩人 2017-05-07 5 楼

这是由于C/C++的隐式类型转换(Implicit conversions)所导致的。可参考http://en.cppreference.com/w/cpp/language/implicit_cast。针对整数的原则是integer promotion,即对小于整数的数转换到整数(int or unsigned int),无符号转换成有符号。
在表达式if (0xFFF0 < (short)0xFFFF)中,这两个数都转换成有符号整数,分别是-16,-1.

灵芸 2017-05-03 4 楼

前面都有些道理,16进制的数默认表示无符号整数,这没有什么错,那0xFFF0就是65520,0xFFFF就是65535,强制转换为short,大家也知道是-1,这点应该没什么争议。按我们的理解就结束了。如果要按计算机的理解,就难一点,如果看VC翻译的汇编代码,如上所说,可能是优化的,也不是很理解。再按计算机原始的思维,计算机内存里面存的是二进制而且存的是显示的数的补码,那0xFFF0在内存中以补码形式存放也应该是0xFFF0,至于0xFFFF和(short)0xFFFF,在内存中存放的形式也应该还是0xFFFF,计算机不会有什么正负的概念之分,区分这两个数的大小,也只能够做减法,至于大小,计算机也只能看标志位。我认为我们只需要理解抽象化的就行了,至于具体化到内存,则必须看真正的内存状态(高手可以看一下物理内存),或许基于不同的硬件而有所不同,但是前面的抽象化理解,是各编译器和人都能接受的答案。

偏爱自由 2017-03-11 3 楼

前面有些童鞋回答是正确的,但也有些是错误的,我来整理下。

16进制的数默认表示无符号整数,即unsigned int,所以 0xFFF0 表示unsigned int
是 0xFFFFFFF0,整数的扩充是前面的位是最高有效位的拷贝,所以 0x0000FFF0 是不对的。

其次,根据运算符的操作数的类型转换规则,一个运算的操作数类型必须相同,向能表示更多的值的类型转换,有符号转为无符号,这两条规则, (short)0xFFFF 扩充最高有效位会先转为 0xFFFFFFFF,再进行比较运算。

所以,得出 0xFFFFFFF0 < 0xFFFFFFFF。现在这两个数都是无符号数。

想挽留 2017-03-10 2 楼

magic说得对,16进制格式默认为unsigned。
(short)0xFFFF 后变成-1,因为short是带符号的双字节类型,0xFFFF是-1的补码。

int main(void)
{
if (0xFFF0 < 0xFFFF)
{
printf("OK!n");
}
else
{
printf("NG!n");
}

return 0;
}

这样写后会运行printf("OK!n");

晚风撩人 2017-02-26 1 楼

本人觉得还有点要补充,出来这种结果应该在32位以上的系统。
0xfff0 相当于 0x0000fff0,很显然是个正数,而(short)0xffff
因为被截断成16位,按照补码规则就是-1,很显然程序执行会跳到else。