C# 的运算符操作顺序
我正在将 C++ 实用程序移植到 C#。当我在 C++ 中运行以下语句时,我得到了正确的操作。然而,当我在 C# 中运行相同的语句时...
有谁知道为什么执行 'begin++' ?疯狂的是,如果我运行 (i % 2) == 0 且 i=0,则立即窗口返回 true。
I am porting a C++ utility to C#. When I run the following statement in C++, I get the correct operation. When I run the same statement in C#, however...
Does anyone know why 'begin++' is executed? The crazy thing is that if I run (i % 2) == 0 with i=0, the Immediate Window returns true.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
运算符优先级与这个问题无关。导致此行为的是评估顺序。
在 C# 中,
i++
在i % 2
之前计算,因为它位于左侧。因此,i % 2
为 false,并且 if 的右侧被评估。首先,您使用优先级来获取语法树:
在每个节点上,您从左到右评估子节点。这意味着
i++
在i % 2
之前计算。Eric Lippert 在 SO 和他的博客上有很多关于此的帖子:
就我个人而言,我会避免这样的代码。将其拆分为多个表达式,甚至使用简单的
if
语句而不是会更好吗? :
在 C++ 中,访问中间没有序列点的变量是未定义的行为。我认为
=
不是序列点,所以我猜你的表达式在 C++ 中未定义,只是碰巧起作用了。Operator precedence is irrelevant in this question. It's evaluation order that causes this behavior.
In C#
i++
is evaluated beforei % 2
since it's on the left side. Thusi % 2
is false and the right side of the if gets evaluated.First you use precedence to get the syntax tree:
On each node you evaluate the children from left to right. This implies that
i++
is evaluated beforei % 2
.Eric Lippert has plenty of posts on this, both here on SO, and on his blog:
Personally I'd avoid such code. It's much nicer to split it into multiple expressions, or even use a plain
if
statement instead of? :
In C++ accessing a variable that was written to without a sequence point in between is undefined behavior. I think
=
is no sequence point, so I guess your expression is undefined in C++ and just happened to work.我不知道,但你为什么不直接表明你的意图呢?
I don't know, but why don't you just make your intentions clear?
您确定
begin
吗?结束
是正确的吗?如果我没记错的话,最后你会错过一个元素。以下是我在 C++ 中的编写方式:
但如果你仔细想想,循环内的条件实际上是不必要的,因为它会随着每次迭代而翻转。在循环内简单地进行两个复制操作会更有效:
我将循环条件更改回
<
并添加了if
以防出现奇数个元素。Are you sure that
begin < end
is correct? You will miss one element at the end, if I'm not mistaken.Here is how I would write it in C++:
But if you think about it, the conditional inside the loop really isn't necessary, because it flip-flops with every iteration. It would be more efficient to simply have two copy operations inside the loop:
I changed the loop condition back to
<
and added anif
in case there is an odd number of elements.