你能帮我理解为什么变量 a
在第一种情况下没有递增,而在第二种情况下却递增吗?
案例 1:
int a = 10;
a = a++;
Console.WriteLine(a); //prints 10
案例 2:
int a = 10;
int c = a++;
Console.WriteLine(a); //prints 11
我已经回答了其他类似的问题,但找不到任何细节。
更新 1:我认为程序的流程如何
案例 1:
1. 'a' is assigned 10
2. 'a' is assigned 10 before increment happens
3. 'a' is incremented by 1 (Why doesn't this step affect the final value of 'a'?)
4. 'a' is printed --> 10
案例 2:
1. 'a' is assigned 10
2. 'c' is assigned 10 before 'a' is incremented
3. 'a' is incremented by 1 (Why does the increment of 'a' work here?)
4. 'a' is printed --> 11
更新 2:感谢所有的回答,我想我已经理解了,如果我错了请纠正我。
案例 1:
1. `a` is assigned 10
2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it's a post increment operation, assigns the old value to `a`. What i thought was, compiler would assign the old value 10 first and evaluate the `++` operation later. This is where i was wrong, compiler evaluates the RHS beforehand and assigns the value based on the operator.
4. 'a' is printed --> 10
案例 2:
1. `a` is assigned 10
2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it's a post increment operation, assigns the old value to `c` but value of `a` is preserved with `11`.
4. 'a' is printed --> 11
最佳答案
对我而言,了解某些行为的最佳方式是检查生成的 IL。在你的第一种情况下是
IL_0001: ldc.i4.s 0A // stack: 10
IL_0003: stloc.0 // a = 10, stack: empty
IL_0004: ldloc.0 // stack: 10
IL_0005: dup // stack: 10, 10
IL_0006: ldc.i4.1 // stack: 10, 10, 1
IL_0007: add // stack: 10, 11
IL_0008: stloc.0 // a = 11, stack: 10
IL_0009: stloc.0 // a = 10, stack: empty
IL_000A: ldloc.0 // stack: 10
IL_000B: call System.Console.WriteLine
您可以看到原始值仍然卡在堆栈上,因此创建的 11 最后被覆盖了。
让我试着用通俗易懂的话来解释一下。
当您为变量赋值时 (a = a++
),赋值的整个右侧首先被计算以保证正确的值,就是这样。所以没有什么比你得到 10,应用程序继续并在你执行下一行时增加值。
现在,将后递增想象成某人,他首先递增一个值,但给了你他的世界,你将从表达式中取回原始值。现在你应该明白为什么 11 被覆盖了。增量在前,最后,您将获得 promise 的原始值(正如 IL 所证明的那样)。
关于c# - 分配中意外的后增量行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27996608/