1

礼炮..

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

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

    return 0;
}

答案是:

x=6

这仅发生在 prefex ++ 中,并且可以按照我对post-increment 的预期工作。

有什么理由吗?问候..

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

    return 0;
}

x=4

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

4

8 回答 8

8

像往常一样,这是未定义的行为。没有序列点+所以没有定义在什么点++更新a。这不是优先问题。

于 2011-02-04T12:29:29.607 回答
5

这里有两个误解。

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

第二:运算符优先级是指运算符在解析其他歧义语法时所采取的优先顺序;它不是指副作用的时间顺序。因此,prefix ++ 总是在计算表达式之前增加值,posfix ++ 总是在计算表达式之后增加值,与句法运算符的优先级无关。

于 2011-02-04T12:36:25.757 回答
4

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

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


编辑: - 我看到你不明白这里的问题,我会添加更多信息:

operator++(后缀或前缀,随便),改变变量的值,所以这使得这个操作符更特别,that operator+,operator-等。所以,随着++aa++改变 的值a,你需要在这之后有一个序列点,然后再a使用. operator+不是序列点,所以就像您调用了operator+( ++a, (a-b) );. 该标准没有说明参数的评估顺序,所以这给我们带来了未定义的行为

更好的?

于 2011-02-04T12:29:42.540 回答
2

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

优先表是从语法派生的,它们不能替代它。

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

于 2011-02-04T12:31:36.230 回答
2

我只会给你一个链接:

序列点

Prasoon Saurav 在 StackOverflow.com 上解释

于 2011-02-04T13:39:28.177 回答
2

这是调用未定义的行为。avia pre-increment 或 post-increment 的修改与其在括号表达式中的使用之间没有序列点。这实际上与运算符优先级无关。考虑一个更简单的例子:

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

的值应该b是多少?+允许编译器以任何顺序计算左手边和右手边,因为通常你会得到相同的答案,除非你修改表达式中的一个变量并再次引用它而没有干预序列点。正如我所说,这是未定义的行为,一个编译器可能会给出 4,另一个编译器可能会给出 3,第三个可能会使您的计算机着火。

于 2011-02-04T12:35:01.070 回答
0

我的理解是,当您在公式中使用 a++ 之类的东西时,“a”值的副本将用于数学运算,因为“++”仅在其他操作之后才有效,因此公式永远不会更新。但我可能错了。

因此,如果您有 x=++a + b,其中 a = 1 和 b = 2,您会得到类似 x = 1 + 2 的东西,而对于 x = a++ + b,您会得到 x = 2 + 2,在值上替代。

于 2011-02-04T14:15:13.050 回答
0

它没有任何优先级问题。

如果你能解决这个问题,那么只要我们有=操作员,它就会从“右到左”解决。表示将解决右侧表达式并将 ans 分配给 variable x。在解决右侧表达式时,我们有+使用“从左到右”方法解决的运算符。所以++a会先解决,然后根据规则括号解决。所以++a会生成4并且(a-b)会给出2所以最后的加法会给出结果6

于 2016-02-03T08:13:50.890 回答