C#的运营商的运营顺序

时间:2011-11-20 22:15:13

标签: c# c++ operator-precedence

我正在将C ++实用程序移植到C#。当我在C ++中运行以下语句时,我得到了正确的操作。当我在C#中运行相同的语句时,不过......

omgwtfbbq

有谁知道为什么'开始++'被执行?疯狂的是,如果我在i = 0的情况下运行(i%2)== 0,则立即窗口返回true。

3 个答案:

答案 0 :(得分:12)

运算符优先级与此问题无关。它是导致此行为的评估顺序。

在C#中i++i % 2之前进行评估,因为它位于左侧。因此,i % 2为false,if的右侧将被评估。

首先使用优先级来获取语法树:

=
  buffer[i++]
  if i % 2
    then temp[end--]
    else temp[begin++]

在每个节点上,您从左到右评估子项。这意味着在i++之前评估i % 2

Eric Lippert在这方面有很多帖子,无论是在SO还是在他的博客上:

就个人而言,我会避免这样的代码。将它分成多个表达式,甚至使用普通if语句而不是? :

更好

在C ++中访问写入的变量而其间没有序列点是未定义的行为。我认为=不是序列点,所以我猜你的表达式在C ++中是未定义的,只是碰巧工作了。

答案 1 :(得分:3)

我不知道,但为什么不明白你的意图呢?

if(i % 2 == 0) {
    buffer[i] = temp[end--];
} else {
    buffer[i] = temp[begin++];
}

i++;

答案 2 :(得分:0)

您确定begin < end是否正确?如果我没弄错的话,你最后会错过一个元素。

以下是我用C ++编写的方法:

for (; begin <= end; ++i)
{
    buffer[i] = temp[(i & 1) == 0 ? end-- : begin++];
}

但是如果你考虑一下,循环中的条件确实不是必需的,因为它会在每次迭代时触发。在循环中简单地进行两次复制操作会更有效:

while (begin < end)
{
    buffer[i++] = temp[end--];
    buffer[i++] = temp[begin++];
}
if (begin == end)
{
    buffer[i++] = temp[end--];
}

我将循环条件更改回<并添加了if,以防有奇数个元素。