表达式
(func1() * func2()) + func3()
首先会对func1()* func2()进行求值,因为它有括号,或者可以按任何顺序调用函数,如
首先是func3()然后是(func1()* func2())
答案 0 :(得分:13)
可以按任何顺序调用这些函数。
答案 1 :(得分:8)
运算符的优先级与操作数的评估顺序无关。
C或C ++标准不确定调用函数的顺序。
子表达式的评估顺序,包括
, +, -, =, * , /
),但以下情况除外:
&&
和||
),?:
)和,
)未指定
例如
int Hello()
{
return printf("Hello"); /* printf() returns the number of
characters successfully printed by it
*/
}
int World()
{
return printf("World !");
}
int main()
{
int a = Hello() + World(); //might print Hello World! or World! Hello
/** ^
|
Functions can be called in either order
**/
return 0;
}
答案 2 :(得分:6)
您无法对调用这些函数的顺序做出任何假设。编译器以任何顺序调用这些函数,将结果分配给临时函数,然后使用这些临时值来计算表达式的结果,这是完全有效的。
答案 3 :(得分:4)
可以按任何顺序进行这些调用。您想了解 C++ sequence points C++ sequence points。
答案 4 :(得分:2)
很自然地认为在此psudocode A+B
之前评估C
:
(A+b)*C
但事实并非如此。标准表示所有表达式的评估顺序是“未指定”,除非标准另有规定:
除非另有说明,否则顺序为 评估个人的操作 运算符和子表达式 个人表达和秩序 发生副作用的是 未指定的
然后,标准继续将带括号的表达式标识为“主要表达式”,但未指定主要表达式的评估顺序。 (5.1 / 5)。
在Standardese中,“未指定”并不意味着“未定义”。相反,它意味着“实施定义,但不需要文档。”因此,您甚至可能无法说出特定编译器的评估顺序。
这是一个简单的程序来说明行为:
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo(const string& name) : name_(name) {++i_; cout << "'" << name << "'(" << i_ << ")\n"; };
operator unsigned() const { return i_; }
Foo operator+(const Foo& rhs) const { string new_name = name_; new_name += "+"; new_name += rhs.name_; return Foo(new_name); }
private:
string name_;
static unsigned i_;
};
unsigned Foo::i_ = 0;
int main()
{
(Foo("A") + Foo("B")) + Foo("C");
}
在Win7上运行在Debug / x64上的MSVC10上,输出恰好是:
'C'(1)
'B'(2)
'A'(3)
'A+B'(4)
'A+B+C'(5)
答案 5 :(得分:1)
C / C ++中的括号强制操作顺序。 func1() * func2()
将添加到func3()
,但编译器可以选择在将结果传递给乘法/加法运算之前以任何顺序调用函数。