是否有一些明确的顺序在下面的表达式中调用函数,或者它是否因编译器而异;
以下规则是否适用于此 - 在C中,未指定评估大多数运算符的函数和操作数的参数的顺序。在此wiki page
中找到了上述规则a = (f1(10, 20) * f2(30, 40)) + f3()
答案 0 :(得分:8)
该规则确实适用。可以按任何顺序评估f1
,f2
和f3
。
为了扩大一些混乱(因为人们不断发布错误的答案),运算符优先级不会影响评估事物的顺序。举个例子:
f1() * f2() + f3()
现在,我们知道是的,f1()
和f2()
的结果相乘,然后添加到f3()
的结果中,但我们不知道评估顺序。解析树看起来像这样:
+
/ \
* f3()
/ \
f1() f2()
但我们不知道是否会先评估+
的左侧或右侧。它可能是两种方式。与*
相同:我们不知道它的左侧或右侧是否会被首先评估。
编译器可以调用f3()
,然后存储结果,然后调用f2()
,存储该结果,然后调用f1()
,然后使用存储的结果执行实际计算
或者,它可以调用f1()
,存储结果,然后调用f2()
,然后使用这两个值相乘(然后存储该结果),然后调用f3()
并完成计算。
在每种情况下(或评估顺序的任何其他排列),功能都以不同的顺序进行评估,但仍然可以得到相同的答案。
总结:运算符优先级确定解析树,不评估顺序。未指定评估解析树的顺序。
答案 1 :(得分:4)
编译器可以按任何顺序调用这些函数(也就是说,唯一的保证是在乘法之前调用f1和f2,并且在添加之前调用所有三个函数,并且所有三个函数都只在值之后调用他们的论据是众所周知的。)
使用这样的文字参数,编译器可能会尽早调用它们(比如上面的行和行),甚至可以使它们内联。
最重要的是,不要将运算符优先级与功能评估的顺序混淆。
所有你知道的是,函数将在其参数的值已知之后但在使用其返回值之前调用。
答案 2 :(得分:2)
可以按任何顺序评估这些功能。没有指定的规则。首先评估f1
,然后评估f2
,然后评估f3
或f3
,然后评估f2
,然后评估f1
或f2
然后首先评估f1
,然后评估f3
甚至f1
,然后评估f3
,然后评估f2
(此处共有六种组合!)。
有一点需要注意:运算符优先级与评估顺序无关。
但请记住,对这些函数的评估顺序是对表达式
的算术运算a = (f1(10, 20) * f2(30, 40)) + f3()
将根据运算符优先级规则获取宫殿,即f1*f2
首先发生(当时f1
并且必须评估f2
),然后添加结果到f3
(必须评估所有f1
,f2
和f2
。