运算符优先..()和++

时间:2011-02-04 12:26:29

标签: c++ operator-precedence post-increment pre-increment

敬礼..

我有一个不寻常的问题。 Here in this table在MSDN库中,我们可以看到()的优先级高于 ++(预增量)。 但是当我运行这段代码时,似乎 ++(prefex)的优先级更高:

int main()
{
    int a=3,b=2,x;
    x=++a + (a-b);
    cout<<"x= "<<x;

    return 0;
}

答案是:

  

X = 6

仅在prefex ++中发生这种情况,并且按照我预期的后增量工作。

有什么理由吗? 此致..

int main()
{
    int a=3,b=2,x;
    x=a++ + (a-b);
    cout<<"x= "<<x;

    return 0;
}
  

X = 4

(我使用Microsoft Visual C ++ 2010 express)

8 个答案:

答案 0 :(得分:8)

像往常一样,这是未定义的行为+处没有sequence point,因此未定义++更新a的位置。这不是优先问题。

答案 1 :(得分:5)

这里有两个误解。

第一种:在表中,()引用函数调用,而不是用于分组的括号。用于分组的括号不是具有特定优先级的运算符,而是用于强制执行与运算符优先级给出的解释不同的解释的方法。因此,无论运算符的优先级如何,括号中的任何内容都被视为一个单元。

第二种:运算符优先级是指运算符在解析其他模糊语法时所采用的优先顺序;它没有提到副作用的时间顺序。因此,前缀++总是在计算表达式之前增加值,posfix ++总是在计算表达式之后增加值,与语法运算符优先级无关。

答案 2 :(得分:4)

x=a++ + (a-b);是未定义的行为,无论是++a还是a++

原因是:您使用两个参数调用operator+a++(a-b),但未定义将首先评估两个参数中的哪一个。


编辑: - 由于我发现您不明白这里的问题,我会添加更多信息:

operator++(后缀或前缀,无论如何),更改变量的值,因此这使得此运算符更加特殊,operator+operator-因此,当++aa++更改a的值时,您需要在此之后有一个序列点,然后再次使用aoperator+不是序列点,因此就像你调用operator+( ++a, (a-b) );一样。该标准说明了关于参数评估的顺序,因此这给我们带来了未定义的行为

更好?

答案 3 :(得分:2)

优先顺序并不决定评估顺序。优先级指定运算符如何绑定到操作数;而不是评估运营商的顺序。

优先级表是从语法中派生出来的,它们不是它的替代品。

此外,您不应该假设JScript优先级表必然与C ++代码有任何关系。

答案 4 :(得分:2)

这是调用未定义的行为。通过预增量或后增量修改a与在括号表达式中使用它之间没有序列点。这实际上与运算符优先级无关。考虑一个更简单的例子:

int a = 1;
int b = (a=2) + a;

b的价值应该是多少?允许编译器以任何顺序评估+的左侧和右侧,因为通常您将获得两个订单的相同答案,除非您修改表达式中的一个变量并引用再次没有插入序列点。正如我所说的那样,这是一个未定义的行为,一个编译器可能会给出4个,另外三个,三分之一可能会点亮你的计算机。

答案 5 :(得分:2)

我会给你一个链接:

Sequence Points

在Prasoon Saurav的StackOverflow.com上解释

答案 6 :(得分:0)

我的理解是,当你在一个公式中使用类似++的东西时,“a”的值的副本被用于数学,因为“++”仅在其他操作之后起作用,公式永远不会更新。但我可能错了。

所以如果你有x = ++ a + b,那你a = 1且b = 2 你得到类似x = 1 + 2的东西,并且x = a + + + b,在值替换上得到x = 2 + 2。

答案 7 :(得分:0)

它没有任何优先权问题。

如果您将解决问题,那么只要我们有=运算符,它就会从“从右到左”解决。表示将解决右侧表达式,并将ans分配给变量x。在解决右侧表达式时,我们有+运算符,它使用“从左到右”的方法来求解。因此++a将首先解决,然后根据规则括号将被解决。因此++a将生成4(a-b)将生成2,因此最终添加将生成结果6