C ++表达式中的运算符优先级

时间:2018-04-10 17:24:56

标签: c++ operators expression

计划1:

#include <iostream>
using namespace std;
int a = 5;
int fun1() {
    a = 17;
    return 3;
} 

int main() {
// Even though C languages are left associative, 
// this line of code evaluates fun1() first: 
    a = a + fun1();
//  a = 17+3
    printf("%d",a);
    a = fun1()+a;
    printf("\n%d",a);
    return 0;
}

输出

20

20

计划2:

int a = 10;
int fun(){
    a= 15;
    return 30;
}
int main(void) {
// whereas in this example, fun() is evaluated last:
    int x = a + 10 + fun();
//      x = 10 + 10 + 30
    a= 10;
    int y = fun() + 10 + a;
    printf(" x = %d \n y = %d \n",x,y);
    return 0;
}

输出

x = 50

y = 55

为什么程序1首先评估fun1()而在程序2中,fun()最后在表达式结束时进行评估?

根据我的理解,基于C语言是关联的,为什么程序1表现得很奇怪?

4 个答案:

答案 0 :(得分:3)

历史上,未指定函数调用的参数评估顺序。这意味着对于电话

foo(bar(), baz());

如果它需要调用bar()而不是baz(),或者反过来需要调用编译器。请记住,调用运算符是泛型函数调用的另一种情况,即baz() + bar()在语义上与operator+(baz(), bar())相同。

出于实际目的,编译器用于评估从倒数到第一个的参数,因为这是将参数推送到堆栈以用于许多函数调用ABI的顺序。

答案 1 :(得分:2)

你混合了两个概念(虽然它经常发生),让我们看一下表达式:

a = b + c + d * e;

运算符优先级和关联性意味着该表达式等于

a = ( ( b + c ) + ( d * e ) );

但并不意味着,d * e必须在b + c之前进行评估,因为*具有更高的优先级。详情请见order of evaluation

  

除了下面提到的,C ++中没有从左到右或从右到左评估的概念。这不应与运算符的从左到右和从右到左的关联性混淆:表达式f1()+ f2()+ f3()被解析为(f1()+ f2())+ f3( )由于operator +的左右关联性,但是f3的函数调用可以在运行时的第一个,最后一个或f1()或f2()之间进行评估

重点是我的。

答案 2 :(得分:0)

有三个独立的概念经常混淆:

评估顺序,用于确定评估操作数的顺序。

标准中通常没有指定。

优先顺序,它决定首先评估两个运算符中的哪一个。

例如,在a + b * c中,在加法之前评估乘法 操作数的评估顺序不受优先级的影响。

关联性,它决定首先评估哪个运算符具有相同的优先级

例如,<<是左关联的; a << b << c被评估为(a << b) << c,而赋值是右关联的; a = b = ca = (b = c) 操作数的评估顺序也不受关联性的影响。

答案 3 :(得分:-2)

此类型的评估顺序未按标准指定。由编译器来完成他正在进行的优化。