采用以下代码(可用作控制台应用程序):
static void Main(string[] args) { int i = 0; i += i++; Console.WriteLine(i); Console.ReadLine(); }
结果i是 0。我预计是 2(正如我的一些同事所做的那样)。编译器可能会创建某种导致i为零的结构。
i
我期望 2 的原因是,在我的思路中,首先评估右手语句,将 i 增加 1。然后将其添加到 i。因为 i 已经是 1,所以它将 1 添加到 1。所以 1 + 1 = 2。显然这不是正在发生的事情。
你能解释一下编译器做了什么或者在运行时发生了什么吗?为什么结果为零?
某种免责声明:我绝对知道您不会(并且可能不应该)使用此代码。 我知道我永远不会。尽管如此,我发现了解它为什么以这种方式运行以及究竟发生了什么是很有趣的。
这:
int i = 0; i += i++
可以看作是你做的(以下是粗略的过度简化):
int i = 0; i = i + i; // i=0 because the ++ is a postfix operator and hasn't been executed i + 1; // Note that you are discarding the calculation result
实际发生的事情比这更复杂 - 看看 MSDN, 7.5.9 Postfix increment and decrement operator:
x++ 或 x– 形式的后缀递增或递减操作的运行时处理包括以下步骤: 如果 x 被归类为变量: x 被评估以产生变量。 x 的值被保存。 使用保存的 x 值作为其参数调用选定的运算符。 运算符返回的值存储在 x 的求值给出的位置。 x 的保存值成为操作的结果。
x++ 或 x– 形式的后缀递增或递减操作的运行时处理包括以下步骤:
如果 x 被归类为变量:
请注意,由于优先顺序,后缀++出现 在 之前 +=,但结果最终未被使用(因为使用了之前的值i)。
++
+=
对其构成的部分进行更彻底的分解i += i++需要知道两者+=都不++是原子的(即,两者都不是单个操作),即使它们看起来像。这些实现的方式涉及临时变量,i操作发生之前的副本 - 每个操作一个。(我将使用名称iAdd和分别iAssign用于 和 的临时变量++)+=。
i += i++
iAdd
iAssign
因此,更接近正在发生的事情是:
int i = 0; int iAdd = i; // Copy of the current value of i, for ++ int iAssign = i; // Copy of the current value of i, for += i = i + 1; // i++ - Happens before += due to order of precedence i = iAdd + iAssign;