【问题标题】:Explaining post-increment in C# [duplicate]在 C# 中解释后增量 [重复]
【发布时间】:2012-04-09 11:04:21
【问题描述】:

我有一些代码

static void Main(string[] args)
{
    int j = 0;
    for (int i = 0; i < 10; i++) 
        j = j++;
    Console.WriteLine(j);
}

为什么答案是 0?

【问题讨论】:

  • 这样的代码必须来自学术界。荒谬。
  • 我以为答案是 10
  • 不,因为j的值被带入中间结果,变量j自增,THEN是分配给j的中间结果。
  • @NikolaMarkovinović - 您应该将其发布为答案。迄今为止最好的答案,顺便说一句。
  • 我想这都是很有可能的,但我更希望得到OP的理由,以更好地解决误解

标签: c# post-increment


【解决方案1】:

顾名思义,后自增是在值被使用后递增

y = x++;

根据C# Language Specification,这相当于

temp = x;
x = x + 1;
y = temp;

应用于您的原始问题,这意味着在这些操作之后j 保持不变。

temp = j;
j = j + 1;
j = temp;

你也可以使用 pre-increment,它会做相反的事情

x = x + 1;
y = x;

y = ++x;

请参阅 MSDN 上的 Postfix increment and decrement operators

【讨论】:

  • 你能用 one 变量说明问题吗?
  • 这种行为并不完全符合后增量的定义。在 C 或 C++ 等其他语言中,此表达式是未定义的。它仅在 C# 中定义,因为评估顺序已明确定义。
  • 我使用问题中指定的原始问题添加了一个示例,正如@Oded 所建议的那样。
  • @EricLippert:你是对的。我澄清了我的声明。
【解决方案2】:

这是因为++ increment works 的方式。 The order of operations is explained in this MSDN article 这可以在这里看到(如果我读错了这个规范,请有人纠正我:)):

int j = 2;
//Since these are value objects, these are two totally different objects now
int intermediateValue = j;
j = 2 + 1
//j is 3 at this point
j = intermediateValue;
//However j = 2 in the end

由于是值对象,此时的两个对象(jintermediateValue)是不同的。旧的 j 增加了,但是因为您使用了相同的变量名,所以它丢失了。我建议您也阅读一下value objects versus reference objects 的区别。

如果您为变量使用了单独的名称,那么您将能够更好地查看此细分。

int j = 0;
int y = j++;
Console.WriteLine(j);
Console.WriteLine(y);
//Output is 
// 1
// 0

如果这是一个具有类似运算符的引用对象,那么这很可能会按预期工作。特别指出如何只创建指向同一引用的新指针。

public class ReferenceTest
{
    public int j;
}

ReferenceTest test = new ReferenceTest();
test.j = 0;
ReferenceTest test2 = test;
//test2 and test both point to the same memory location
//thus everything within them is really one and the same
test2.j++;
Console.WriteLine(test.j);
//Output: 1

回到原点,不过:)

如果您执行以下操作,那么您将获得预期的结果。

j = ++j;

这是因为先递增,后赋值。

但是,++ 可以单独使用。所以,我会把它改写为

j++;

因为它只是翻译成

j = j + 1;

【讨论】:

  • 操作顺序不正确。赋值发生在使用存储值递增之后。见msdn.microsoft.com/en-us/library/aa691363
  • 在这种情况下,值类型和引用类型没有区别。
  • @fgb Hrmm,我想我从来没有深入研究过操作的顺序。我会更新我的答案
  • @CodeInChaos 你是对的,但是我认为通过正确理解值与引用对象可以解决部分混淆
  • @fgb 请随意查看并验证我是否正确编写了订单:)
猜你喜欢
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 2014-01-09
  • 2017-04-30
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多