这个问题被问了很多。请注意,每次有人问这个问题时,都会有很多人发布错误的答案。很多人对这些运算符的工作方式有错误的想法,包括编写编程书籍并因此向他人传授谎言的人。仔细阅读此处的其他答案。
有关 C# 行为的正确分析,请参阅:
i++ 和 ++i 有什么区别?
对于 C++,任何行为都是正确的行为,在您观察到副作用的情况下。C++ 没有定义增量的副作用何时可见。任何两个编译器都可以做不同的事情。
一个好的规则是不要依赖任何语言中副作用发生的顺序,但在 C++ 中当然不要依赖它,因为它不可靠。
查看您的具体情况:
int x, y;
x = 1;
y = x + x++;
您报告 x 和 y 都是 2。这在 C# 中是正确的。在 C# 中,正确的行为是:
- 将 y 评估为变量
- 将 x 评估为一个值——它是 1
- 将 x++ 评估为一个值。这会将 x 作为变量进行计算,然后取其原始值 1,然后将该值递增 2,然后将 2 分配给 x,然后得到原始值 1。
- 计算 1 + 1,即 2
- 将 2 分配给 y。
所以 x 和 y 在 C# 中都是 2。
C++ 可以做同样的事情,但允许以从右到左的顺序计算加法。也就是说,允许这样做:
- 将 x++ 评估为一个值。这会将 x 作为变量进行计算,然后取其原始值 1,然后将该值递增 2,然后将 2 分配给 x,然后得到原始值 1。
- 将 x 评估为一个值——它是 2
- 计算 1 + 2,即 3
- 将 y 评估为变量
- 将 3 分配给 y。
C++ 也允许这样做:
- 将 x++ 评估为一个值。这会将 x 作为一个变量进行计算,然后取其原始值 1,然后将该值递增 2 ...此处缺少步骤 ...然后产生原始值,即 1。
- 将 x 评估为一个值——它是 1
- 计算 1 + 1,即 2
- 将 2 分配给 x - 之前缺少的步骤。
- 将 y 评估为变量
- 将 2 分配给 y。
因此,在 C++ 中,您可以将 y 设为 3 或 2,这取决于编译器编写者的心血来潮。在 C# 中,你总是得到 y 是 2。在 C++ 中,增量的赋值可以在任何时候发生,只要它确实发生了。在 C# 中,增量的赋值必须发生在计算增量值之后且在使用原始值之前。(当从执行线程观察时;如果你试图从另一个或多个线程观察这些东西,所有的赌注都没有了。)
在您的第二个示例中:
y = x++ + x;
在 C# 中,所需的行为是:
- 将 y 评估为变量
- 将 x++ 评估为一个值。这会将 x 作为变量进行计算,然后取其原始值 1,然后将该值递增 2,然后将 2 分配给 x,然后得到原始值 1。
- 将 x 评估为一个值——它是 2
- 计算 1 + 2,即 3
- 将 3 分配给 y。
所以 C# 中的正确答案是 y 是 3,x 是 2。
同样,C++ 可以按任何顺序执行这些步骤。允许 C++ 执行以下操作:
- 将 x 评估为一个值——它是 1
- 将 x++ 评估为一个值。这会将 x 作为变量进行计算,然后取其原始值 1,然后将该值递增 2,然后将 2 分配给 x,然后得到原始值 1。
- 计算 1 + 1,即 2
- 将 y 评估为变量
- 将 2 分配给 y。
同样,在 C++ 中,正确的答案是 y 是 2 或 3,这取决于编译器编写者的心血来潮。在 C# 中,正确答案是 y 是 3。