现在我要做一些不该做的事情……我将尝试简化 Eric Lippert 在这里写的内容 What is the difference between i++ and ++i? 我希望我没有写错什么 :-)
现在…… 前缀递增和后缀递增运算符是做什么的?简化并忽略它们之间的所有副本(并记住它们不是多线程环境中的原子运算符):
它们都是表达式(如i + 1
),返回结果(如i + 1
),但具有副作用(不像i + 1
)。副作用是它们递增变量i
。重要问题是“所有的事情发生的顺序是什么?”答案非常简单:
- 前置自增
++i
:将i
加1并返回i
的新值
- 后置自增
i++
:将i
加1并返回i
的旧值
现在...重要的是,增量i
总是先发生。然后返回一个值(旧值或新值)。
让我们举个例子(Lippert的例子相当复杂。我会举一个不太完整但足以检查我之前说的顺序是否正确的不同、更简单的例子)(技术上我会举两个例子)
例子1:
unchecked
{
int i = Int32.MaxValue;
Console.WriteLine("Hello! I'm trying to do my work here {0}", i++);
Console.WriteLine("Work done {1}", i);
}
例子2:
checked
{
int i = Int32.MaxValue;
Console.WriteLine("Hello! I'm trying to do my work here {0}", i++);
Console.WriteLine("Work done {1}", i);
}
checked
表示如果溢出会抛出异常 (OverflowException
)。 unchecked
表示相同的操作不会抛出异常。 Int32.MaxValue + 1
肯定会溢出。使用 checked
会抛出异常,而使用 unchecked
i
将变为 -1。
让我们尝试运行第一段代码。结果:
Hello! I'm trying to do my work here 2147483647
Work done -1
好的... i
已经被增加了,但是 Console.WriteLine
接收到了旧值 (Int32.MaxValue == 2147483647
)。从这个例子中我们无法确定后缀自增运算符和调用 Console.WriteLine
的顺序。
让我们尝试运行第二段代码。结果:
System.OverflowException: Arithmetic operation resulted in an overflow.
好的...很明显首先执行了后增量,导致异常,然后显然Console.WriteLine
没有被执行(因为程序结束了)。
所以我们知道我说的顺序是正确的。
现在。你应该从这个例子中学到什么?和我多年前学到的一样。在C和C#中,前缀和后缀增量适用于混淆代码比赛。它们不适用于许多其他事情(但请注意,C++是不同的!)。从那个教训中,我学到了只有两个地方可以自由使用后增量,而没有一个地方可以自由使用前增量。
“安全”的后增量
for (int i = 0
并且
i++
“安全”的前缀递增
(nothing)