哪个订单function称为
是否有一些确定的顺序,在下面的表达式中调用函数或它是否从编译器到编译器不同?
此处的规则是否适用 – 在C中,未指定大多数运算符的函数和操作数的参数的计数顺序。 在此Wiki页面中找到了上述规则
a = (f1(10, 20) * f2(30, 40)) + f3()
该规则确实适用。 可以以任何顺序评估f1
, f2
和f3
。
为了扩大一些混乱(因为人们不断发布错误的答案 ),运算符优先级不会影响事物的评估顺序。 举个例子:
f1() * f2() + f3()
现在,我们知道是的, f1()
和f2()
结果相乘,然后加到f3()
的结果中,但我们不知道评估的顺序 。 解析树看起来像这样:
+ / \ * f3() / \ f1() f2()
但是我们不知道是否会首先评估+
的左侧或右侧。 它可以是任何一种方式。 与*
相同:我们不知道它的左侧或右侧是否会先被评估。
编译器可以调用f3()
,然后存储结果,然后调用f2()
,存储该结果,然后调用f1()
,然后使用存储的结果执行实际计算。
或者,它可以调用f1()
,存储结果,然后调用f2()
,然后使用这两个值相乘(然后存储该结果),然后调用f3()
并完成计算。
在这些情况中的每一种情况下(或评估顺序的任何其他排列),以不同的顺序评估function,但是实现了相同的答案。
总结: 运算符优先级确定解析树, 而不是评估顺序 。 未指定评估解析树的顺序。
编译器可以按任何顺序调用这些函数(也就是说,唯一的保证是在乘法之前调用f1和f2,并且在添加之前调用所有三个函数,并且所有三个函数只会在它们的参数值之后调用众所周知)。
使用这样的文字参数,编译器可能会尽早调用它们(比如上面的行和行),甚至可以使它们内联。
最重要的是,不要将运算符优先级与function评估的顺序混淆。
所有你知道的是,函数将在其参数的值已知之后但在使用其返回值之前被调用。
可以按任何顺序评估这些function。 没有指定的规则。 首先评估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
) 。