C/C++ 数学运算符优先级

7
所以我知道C++有一个运算符优先级,而且
int x = ++i + i++;

由于 pre++ 和 post++ 处于同一级别,因此无法确定哪个会先计算,因此

是未定义的。但我想知道的是,如果

在 pre++ 或 post++ 之前出现,那么它是否有定义?
int i = 1/2/3;

is undefined。我询问的原因是因为有多种解释方法:(1/2)/3或者1/(2/3)。 我的猜测是这是一种未定义的行为,但我想要确认一下。


3
不,它不是未定义的。它是(一除以二)再除以三。换句话说,这是一个普通的数学表达式。 - Robert Harvey
我认为你对第一个问题的思考有点模糊,而这种思维方式渗透到了你对第二个问题的思考中。第一个问题实际上归结为函数参数求值顺序未定义。也就是说,如果你把它看作是 operator+(++i,i++),那么它就很明显了。 - Chris A.
1
C++(以及大多数其他编程语言)采用从数学借鉴的优先顺序。您不需要以多种方式查看表达式,数学运算具有层次结构。但是,您可以使用(合理放置的)括号更改操作的顺序。 - Thomas Anthony
5
int x = ++i + i++ 的未定义性与操作符优先级无关。 - Benjamin Lindley
2
请注意,未定义行为与运算符优先级无关。它与执行顺序有关,以及在序列点之间是否可以多次修改 i。恰好,前置递增和后置递增的优先级级别不同。 - Steve Jessop
5个回答

17

如果你查看C++的运算符优先级和结合性,你会发现除法运算符是从左到右结合的,这意味着它将被计算为(1/2)/3,因为:

在同一单元格中的运算符(可能有多行运算符列在一个单元格中)按照给定方向的相同优先级进行计算。例如,表达式a=b=c被解析为a=(b=c),而不是(a=b)=c,因为它是从右到左结合的。


6
在你的例子中,编译器可以自由地按任意顺序评估“1”、“2”和“3”,然后从左到右应用除法。
i++ + i++ 的例子也是如此。它可以按任意顺序评估 i++,这就是问题所在。
并不是函数的优先级未定义,而是其参数的评估顺序未定义。

5

第一个代码片段是未定义行为,因为变量i在序列点之间被多次修改。

第二个代码片段是定义良好的行为,并等同于:

int i = (1 / 2) / 3;

作为运算符,/ 具有从左到右的结合性。

你能进一步解释为什么第一个代码片段是未定义行为吗?如果你使用 i = 4,它会输出10。抱歉,我是个新手。 - akaHuman

2

这是一个定义,从左到右阅读:

#include <iostream>

using namespace std;

int main (int argc, char *argv[]) {
    int i = 16/2/2/2;
    cout<<i<<endl;
    return 0;
}

输出"2"而不是1或16。


0
它可能会说未定义,因为您选择了整数int,该类型只包括整数。 尝试使用包含分数的double或float。

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