我对 C# 编译器如何处理前后递增和递减有点困惑。
当我编写以下代码时:
int x = 4;
x = x++ + ++x;
x
之后将具有值 10。我认为这是因为预增量设置x
为5
,这使得它5+5
评估为10
。然后后增量将更新x
为6
,但不会使用此值,因为那时10
将分配给x
。
但是当我编码时:
int x = 4;
x = x-- - --x;
然后x
将在2
之后。谁能解释为什么会这样?
我对 C# 编译器如何处理前后递增和递减有点困惑。
当我编写以下代码时:
int x = 4;
x = x++ + ++x;
x
之后将具有值 10。我认为这是因为预增量设置x
为5
,这使得它5+5
评估为10
。然后后增量将更新x
为6
,但不会使用此值,因为那时10
将分配给x
。
但是当我编码时:
int x = 4;
x = x-- - --x;
然后x
将在2
之后。谁能解释为什么会这样?
x--
will be 4, but will be 3 at the moment of --x
, so it will end being 2, then you'll have
x = 4 - 2
btw, your first case will be x = 4 + 6
Here is a small example that will print out the values for each part, maybe this way you'll understand it better:
static void Main(string[] args)
{
int x = 4;
Console.WriteLine("x++: {0}", x++); //after this statement x = 5
Console.WriteLine("++x: {0}", ++x);
int y = 4;
Console.WriteLine("y--: {0}", y--); //after this statement y = 3
Console.WriteLine("--y: {0}", --y);
Console.ReadKey();
}
this prints out
x++: 4
++x: 6
y--: 4
--y: 2
让我们看一下从该语句生成的 IL
IL_0002: ldloc.0
将 x 的值加载到堆栈中。堆栈 => (4)
IL_0003: dup
复制堆栈上最顶层的项目。堆栈 => (4, 4)
IL_0004: ldc.i4.1
将 1 压入堆栈。堆栈 => (1, 4, 4)
IL_0005: sub
减去两个最高值并将结果压入堆栈。堆栈 => (3, 4)
IL_0006: stloc.0
将堆栈的最高值存储回 x。堆栈 => (4)
IL_0007: ldloc.0
将 x 的值加载回堆栈。堆栈 => (3, 4)
IL_0008: ldc.i4.1
将值 1 加载到堆栈中。堆栈 => (1, 3, 4)
IL_0009: sub
减去两者。堆栈 => (2, 4)
IL_000A: dup
复制顶部值 => (2, 2, 4)
IL_000B: stloc.0
将最高值存储回 x。堆栈 => (2, 4)
IL_000C: sub
减去两个最高值。堆栈 => (2)
IL_000D: stloc.0
将此值存储回 x 中。x == 2
从您的评论中:
我认为后增量和前增量是在评估完整代码行之后/之前执行的 - 但它们是在评估表达式中每个项目之后/之前执行的。
你的误解是非常普遍的。请注意,在某些语言(如 C)中,未指定副作用何时可见,因此您的陈述在 C 中为真是合法的,但不是必需的。
在 C# 中不是这种情况;在 C#中,表达式左侧代码的副作用总是观察到在右侧代码执行之前发生(来自单个线程;在多线程场景中,所有赌注都没有。)
有关增量运算符在 C# 中的作用的更详细说明,请参见:
我写的关于这个经常被误解的话题的文章有很多额外的链接。
最有趣的是,您将使用 C++.Net 编译器得到完全不同的答案。
int x = 4;
x = x++ + ++x; // x = 11
x = 4;
x = x-- - --x; // x = -1
当然,结果的差异是由不同的语义决定的——这似乎很正常。但是,尽管了解两个 .net 编译器对于这些基本事物的行为方式不同这一事实也让我感到困惑。
在这个例子中,
int x = 4;
x = x++ + ++x;
你可以打破它:
x = 4++; which is = 5
x = 4 + ++5; which is 4 + 6
x = 10
相似地,
int x = 4;
x = x-- - --x;
这里,
x = 4--; which is = 3
x = 4 - --3; which is 4 - 2
x = 2
简单地说,您可以说,替换 x 的当前值,但是对于每个 ++ 或 -- 从 x 中添加/减去一个值。
我认为对 ++++++ 案例的解释是错误的:
命令............ x 的值
..................不明确的
诠释 x=4 ....4
x++................5(第一个和为 4)
++x.............6(第二个和为 6)
x=summand1+summand2 ..4+6=10
类似于 -- -- -- 案例的解释是
命令............ x 的值
..................不明确的
诠释 x=4 ....4
x--................3(减数为 4)
--x.............2(减数为 2)
x=减法-减数..4-2=10