【问题标题】:Precedence of operators?运算符的优先级?
【发布时间】:2015-03-20 17:03:25
【问题描述】:

看看这个简单的类:

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 &lt;&lt; (Expr1) &lt;&lt; (Expr2) 时,Expr1Expr2 在打印Expr1 的输出之前被评估?

【问题讨论】:

  • 这是关于关联性,而不是优先级。只有一个运算符,因此不会出现优先级问题。
  • 这与关联性无关。这是关于子表达式的求值顺序。
  • @EJP 不,不是。它通常未指定。
  • C++11(草案 N3337)dcl.fct.defaultThe order of evaluation of function arguments is unspecified.

标签: c++ operator-precedence


【解决方案1】:

运算符优先级不规定中间结果的评估顺序。 IE。它并不规定整个表达式中子表达式的求值顺序。

表达式语句

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;

在这种情况下,运算符&lt;&lt; 的运算符优先级和关联性保证tmp_atmp_b 之前发送到输出。但它不保证tmp_atmp_b 之前被评估

【讨论】:

    【解决方案2】:

    这一行:

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

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

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

    (编辑)

    这是否意味着当我有 cout

    这也没有指定。

    【讨论】:

    • 完成!但是我仍然不清楚为什么在Expr1 之前评估Expr2。我试过 GCC 和 MSVC
    • @DarienPardinas 这是因为他们想这样做,而且他们被允许这样做。作为程序员,您不要假设首先评估哪个。如果你想要那个控制,你可以把它们放在不同的行上。祝你好运!
    • @DarienPardinas 不要将观察到的行为与指定行为或定义行为混淆。它们有时是不同的东西。如有疑问,请揭开标准文本,看看它会把你带到哪里。
    • 谢谢!无论如何,这是 C++ Certified Associate Programmer 的练习题之一,根据他们的正确答案是21,即使该输出应该是未定义的。
    • @DarienPardinas 哇!有人应该和他们聊天,不是吗?可以分享一个链接吗?
    猜你喜欢
    • 2011-07-07
    • 2021-10-25
    • 2011-06-21
    • 2013-02-24
    • 2012-08-10
    • 2020-03-05
    • 2012-12-13
    相关资源
    最近更新 更多