【问题标题】:Operator Precedence.. () and ++运算符优先级.. () 和 ++
【发布时间】:2011-06-21 08:11:11
【问题描述】:

敬礼..

我有一个不寻常的问题。 Here in this table 在 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)

【问题讨论】:

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


【解决方案1】:

像往常一样,这是未定义的行为。在+ 处没有sequence point,所以没有定义++ 在什么时候更新a。这不是优先级问题。

【讨论】:

  • @C77431 - 按照这个顺序,你是从 MSDN 粘贴的,没有 operator++ (:operator++ 改变变量的值,任何变量的改变都应该用序列点分隔,是一切都定义明确,你在这里没有序列点。
【解决方案2】:

这里有两个误解。

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

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

【讨论】:

  • 表格说:“函数调用和表达式分组”所以我认为它们确实意味着括号的两种使用。诚然,它是一个 JScript 表,因此它的相关性值得怀疑。
  • 你说得对,我在表格中忽略了这一点。在这种情况下,表格是错误的:-)。括号在用于表达式分组时不是运算符,并且给它们分配优先级是没有意义的(在 JScript 或其他任何地方)。括号是否优先于运算符的问题不会出现,因为括号的语法没有歧义 - 而这个问题确实出现在所有运算符中,包括函数调用运算符 (),因此这些运算符需要分配的优先级。 (此外,运算符“做某事”;括号只是语法。)
  • 当问题是关于 c++ 的时候,我们为什么要讨论 JScript 运算符优先级?为什么不使用正确的优先级表呢? msdn.microsoft.com/en-us/library/126fe14k%28v=vs.10.0%29.aspx
  • 有趣——他们不考虑将括号分组为该表中的运算符。当然这不是 JScript 和 C++ 的区别,只是 JScript 表是错的,C++ 表是对的 :-)
【解决方案3】:

这个x=a++ + (a-b);是未定义的行为,不管是++a还是a++

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


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

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

更好?

【讨论】:

  • 首先评估的不仅仅是未定义;在严格阅读标准的情况下,整个程序的行为是完全未定义的。
  • 我认为第一个例子很好。编辑几乎让它变得更复杂:P
【解决方案4】:

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

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

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

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

      我只给你一个链接:

      Sequence Points

      Prasoon Saurav 在 StackOverflow.com 上解释

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

          它没有任何优先级问题。

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

          【讨论】:

            猜你喜欢
            • 2020-03-05
            • 1970-01-01
            • 2021-03-29
            • 2013-07-31
            • 1970-01-01
            • 2023-03-07
            • 2011-07-07
            相关资源
            最近更新 更多