我在Windows 7上使用Code :: Blocks 10.05。
我编写了以下程序,
#include<stdio.h>
int main()
{
float f=1.5;
printf("%f\n",(f-1)*1/2);
return 0;
}
输出 0.250000 。 我理解如下,
由于f
是浮点(f-1)
,因此返回浮点值 0.500000 ,整个表达式升级为浮点运算,因此 1/2 也被视为浮动,以获得 0.500000 ,从而得到结果。
还有以下声明,
float f=1.5;
printf("%f\n",1/2*(f-1));
将 0.000000 作为答案。
这里表达式1/2
执行整数除法。在这里,我期望首先评估(f-1)
,并将整个表达式升级为浮点运算。
我再次想到,因为波兰语符号是,
* / 1 2 - f 1
除法是第一次执行的操作,因此是结果。 我对这个假设是否正确?
最后,以下陈述无视所有逻辑,
float f=1.5;
printf("%f\n",(f-1)*(1/2));
输出 0.000000 , 但这里的波兰表示法是,
* - f 1 / 1 2
所以(f-1)
应该首先进行评估,因此整个表达式升级为浮动
点算术和输出应 0.250000 。
我哪里出错了? 这是否与运营商的评估顺序有关*? C中的表达式是不明确的吗?
答案 0 :(得分:6)
由于f是float(f-1),返回浮点值0.500000,整个表达式升级为浮点运算
不,你从哪里得到错误的信息?升级到浮点仅适用于其中任一操作数是浮点数的一个运算符。 1/2
不被视为浮点表达式 - 因此,它甚至没有被评估。由于乘法和除法具有相同的优先级并且是左关联的,
(f - 1) * 1 / 2
评估为
((f - 1) * 1) / 2)
然后,1
被提升为float
(至少),然后因为((f - 1) * 1)
也是浮点数,那么除法的另一个操作数{{1}也被提升为2
(或更高精度的FP编号,具体取决于编译器的需要)。
这里我期望首先评估(f-1)并将整个表达式升级为浮点运算。
不,正如我刚才解释的那样,这是一个不正确的期望。它是不要转换为浮点的完整表达式。它只是 运算符的另一个直接操作数,其中一个操作数是float
。因此在表达式中:
float
(f - 1) * (1 / 2)
是f - 1
。 float
是一个整数,它为零,然后整数零被提升为1 / 2
,因为float
的另一个操作数是*
。然而,float
的操作数是整数,因此根据整数运算的规则来评估除法。
答案 1 :(得分:2)
*
和/
具有相同的优先级,因此(f-1)*1/2
相当于((f-1)*1)/2
,而不是您的想法。
虽然1/2*(f-1)
相当于(1/2)*(f-1)
,其中1/2
的值为0
。
答案 2 :(得分:1)
由于paranthesis:(1/2)
你只得到一个大的零(1/2的结果)升级到浮点数。因此零结果。
答案 3 :(得分:0)
(1/2)
被视为整数,结果为零。乘以零导致结果也为零。
答案 4 :(得分:0)
表达式从左到右进行评估:
f
是float
。f - 1
中,两个操作数都提升为double
,值为0.5
。调用表达式E1
。(f - 1) * 1
相同,即E1 * 1
,两个操作数都提升为double
,表达式的值为0.5
。调用表达式E2
。(f - 1) * 1 / 2
相同,即E2 / 2
,两个操作数都会提升为double
,而且表达式的值为0.25
。