【发布时间】:2018-09-27 18:51:44
【问题描述】:
当我意识到 OCaml 将整数除法和乘法存储到相同的优先级时,我正在涉足 OCaml,因此 3*4/5 与 3/5*4 不同。不知何故,我错误地记得在 C/C++ 中情况并非如此,除法的优先级高于乘法,但每篇文档都说,就像 OCaml C 和 C++ 一样,为 @ 分配相同的优先级987654323@ 和*。
我写了一个简单的程序:
int main(int argc, char** argv){
printf("%f %f",3*5/4, 3/5*4);
}
当我使用 gcc 8.1.1 编译它时,它打印了 0.0000 0.0000,尽管它强化了我的错误信念,但与记录在案的行为背道而驰。怀疑一些奇怪的编译器问题,我试图简单地打印一个格式化为浮点数的整数:
int main(int argc, char** argv){
printf("%f",20);
}
结果再次得到 0.00000。这真的让我的大脑很乱。现在是凌晨 2 点,我没有得到答案就无法入睡。
P.S.:我已经用 C 语言编程了很多年,要么我在这里做一些非常愚蠢的事情,要么编译器真的把事情搞砸了。
编辑:正如 cmets 中指出的那样,这是一个愚蠢的错误。在 C/C++ 中,/ 的行为类似于正确除法,如果至少其中一个操作数是浮点数,但当两个操作数都是整数时,它变成整数除法。 printf() 也无法执行任何转换,因为它不知道变量的实际类型。我至少赢得了一张反对票,但这将永久提醒我糟糕的默认语义和松散的打字会在哪里咬人。
【问题讨论】:
-
对
int值的操作产生int值,而不是float。尝试打印20.或3.*5/4。 -
warning: format '%f' expects argument of type 'double', but argument 2 has type 'int' [-Wformat=] -
这里没有“隐式转换”。您正在将可变参数 (
...) 参数传递给printf。您有责任确保参数类型与格式说明符正确匹配。如果你需要演员 - 自己做。printf将无法理解这里需要演员表。printf本质上将可变参数视为二进制数据。 -
太尴尬了,但是用 Python 编程一段时间让我完全忘记了
/将执行整数除法,所以3/5*4的计算结果为 0,但是3*5/4呢? -
@WeatherVane 是的,但没有
5/4,因为乘法和除法具有相同的优先级,并且从左到右关联。所以它实际上是15/4,诚然,它给出了与3*(5/4)相同的答案
标签: c