函数调用的顺序

7

针对这个表达式

(func1() * func2()) + func3()

func1() * func2()会首先被计算,因为它有括号。但是函数的调用顺序可以随意,比如先调用func3(),然后再计算(func1() * func2())。

6个回答

15
任何顺序都可以调用这些函数。

10

运算符的优先级与操作数的求值顺序无关。

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;
  } 

6

您不能假设这些函数调用的顺序。编译器完全可以以任何顺序调用这些函数,将结果分配给临时变量,然后使用这些临时值计算表达式的结果。


4

2
"C++语言定义目前未指定序列点。这绝对是一个有趣的声明。" - Johannes Schaub - litb
好的,需要找到一个更好的参考资料 :) Johannes,你有吗? - Nikolai Fetissov
2
https://dev59.com/Zm855IYBdhLWcg3wuG-W 这个怎么样? - John Dibling
谢谢John,我真的在寻找一种直接链接到标准文本的方法。只是用维基百科引用替换了链接。 - Nikolai Fetissov

2

自然而然地认为在这个伪代码中,A+BC 之前被计算:

(A+b)*C

但实际上并非如此。标准规定所有表达式的计算顺序都是“未指定的”,除非标准另有规定:

5/4 [expr]:

除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的计算顺序以及副作用发生的顺序均为未指定

标准接着将括号表达式标识为“基本表达式”,但不指定基本表达式的计算顺序(5.1 / 5)。

在标准术语中,“未指定”并不意味着“未定义”。它表示“实现定义,但不需要文档记录”。因此,您甚至可能无法确定特定编译器的计算顺序。

下面是一个简单的程序,说明了这种行为:

#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系统中的MSVC10上,使用Debug/x64模式运行时,输出结果如下:
'C'(1)
'B'(2)
'A'(3)
'A+B'(4)
'A+B+C'(5)

2

C/C++中的括号强制指定运算顺序。 func1() * func2() 将会先被加到 func3() 中,但编译器可以在将结果传递给乘法/加法运算之前以任何顺序调用函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接