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