运算符的优先级?

3

看看这个简单的类:

class A {
    int *val;
public:
    A() { val = new int; *val = 0; }
    int get() { return ++(*val); }
};

为什么当我运行这段代码时,它会打印出 21
int main() {
    A a, b = a;
    cout << a.get() << b.get();
    return 0;
}

但是如果我像这样运行它,它会打印出12,这正是我所期望的:
int main() {
    A a, b = a;
    cout << a.get();
    cout << b.get();
    return 0;
}

我在这里漏掉了什么?运算符优先级?顺便说一下,这是一个C++测试问题,而不是生产代码。

编辑: 这是否意味着当我有 cout << (Expr1) << (Expr2) 时,Expr1Expr2 在输出Expr1之前就已经被计算了?


4
这与结合律有关,而不是优先级。只有一个运算符,所以不存在优先级的问题。 - user207421
3
这不涉及结合律。这关乎子表达式的计算顺序。 - T.C.
1
@EJP 不,它不是。通常情况下是未指定的。 - T.C.
1
https://dev59.com/nOo6XIcBkEYKwwoYTSsu - T.C.
4
C++11(草案N3337)dcl.fct.default:函数参数的求值顺序是未指定的。 - legends2k
显示剩余2条评论
2个回答

8

运算符优先级不决定中间结果的计算顺序,即它不决定整个表达式中子表达式的计算顺序。

表达式语句

cout << a.get() << b.get();

可以被编译器执行的代码

int tmp_a = a.get();
int tmp_b = b.get();
cout << tmp_a;
cout << tmp_b;

或作为
int tmp_b = b.get();
int tmp_a = a.get();
cout << tmp_a;
cout << tmp_b;

在这种情况下,运算符 << 的优先级和结合性保证了在输出之前会先将 tmp_a 发送到输出。但它并不保证在发送前会先计算 tmp_a

2
这行代码:
cout << a.get() << b.get();

未指定先评估 a.get() 还是 b.get()

由于 ab 共享相同的 val 指针,这些操作的顺序会影响输出结果。

(编辑)

这是否意味着当我有 cout << (Expr1) << (Expr2) 时,Expr1 和 Expr2 在输出 Expr1 之前被评估?

这也没有指定。


谢谢!无论如何,那是C++认证初级程序员的练习题之一,根据他们的说法,正确答案是21,即使该输出应该是未定义的。 - Darien Pardinas
2
@DarienPardinas 哇!有人应该和他们聊聊,不是吗?你能分享一个链接吗? - Drew Dormann
第6章问题7。您需要注册(免费)才能亲眼看到它。 - Darien Pardinas
@DarienPardinas,他们的库存照片使用不同的高斯模糊。这是第一个警示信号。 - Drew Dormann
@DrewDormann 你的意思是什么?这个认证不值得一看吗? - Darien Pardinas
显示剩余3条评论

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