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

C++ C+中的运算符优先级+;表达,c++,operators,expression,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

程序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;
}
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;
}
输出:

#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;
}
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的行为会很奇怪呢?

标准中没有规定这种类型的求值顺序。由编译器来完成他正在进行的优化

历史上,函数调用的参数求值顺序未指定。这意味着这是一个电话

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

出于实际目的,编译器用于从最后一个参数到第一个参数求值,考虑到这是许多函数调用ABI将参数推送到堆栈的顺序。

您混合了两个概念(尽管这种情况经常发生),让我们看看表达式:

a = b + c + d * e;
运算符优先级和结合性意味着此表达式等于

a = ( ( b + c ) + ( d * e ) );
但这并不意味着,例如,
d*e
必须在
b+c
之前求值,仅仅因为*具有更高的优先级。详情可在此找到

除了下面指出的,C++中没有左到右或右到左的评价概念。这不应与运算符的从左到右和从右到左的关联性混淆:由于运算符+,从左到右的关联性,表达式f1()+f2()+f3()被解析为(f1()+f2())+f3(),,但对f3的函数调用可以在运行时首先、最后或在f1()或f2()之间求值


重点是我的。

有三个不同的概念经常被混淆:

求值顺序,确定操作数求值的顺序

这在标准中通常未指定

优先级,它确定两个运算符中的哪一个先求值

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

结合性,它决定首先计算具有相同优先级的运算符


例如,
未指定评估顺序。这取决于编译器。@drescherjm我仍然不明白,两个程序中的操作数顺序是相同的。编译器可以按任意顺序对其求值。优先级与求值顺序不同,运算符优先级和求值顺序是两个几乎不相关的概念,这意味着什么?是什么让编译器先计算fun1(),即使它位于表达式的末尾?我对这两个程序使用了相同的编译器。这意味着它是什么。在这种表达式中,不能依赖求值顺序,如果需要,必须在正确的位置添加()。@drescherjm我不确定是否有人会从中受益。大多数开发人员都受过太多的训练,不能依赖于评估顺序,所以他们不太可能开始使用这种保证。@liliscent我的观点是正确的。看来我误解了措辞。将删除关于C++17的部分。谢谢