下面的代码(可用作控制台应用程序):

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

i的结果是0。我以为会有2个(和我的一些同事一样)。可能编译器创建了某种结构,导致i为零。

我期望2的原因是,在我的思路中,右边的语句会先求值,使I加1。然后加上i,因为i已经是1了,所以是1加1。所以1 + 1 = 2。很明显,事实并非如此。

你能解释编译器做什么或者在运行时发生了什么吗?为什么结果是零?

某种免责声明:我非常清楚您不会(而且可能不应该)使用此代码。我知道我永远不会。尽管如此,我觉得了解它为什么会以这样的方式工作以及究竟发生了什么是很有趣的。


当前回答

++后缀在对i加1之前求值,+=只求i一次。

因此,0 + 0 = 0,因为i是在加1之前计算和使用的,因为使用了++的后缀格式。要先增加i,请使用前缀形式(++i)。

(另外,只是注意:你应该只得到1,因为0 + (0 + 1)= 1)

参考资料:http://msdn.microsoft.com/en-us/library/sa7629ew.aspx (+=) http://msdn.microsoft.com/en-us/library/36x43w8w.aspx (+ +)

其他回答

关于这一点,我一直记得一个很好的助记法:

如果++位于表达式之后,则返回之前的值。下面的代码

int a = 1;
int b = a++;

是1,因为a在被a后面的++加起来之前是1,人们称之为后缀符号。还有一种前缀表示法,情况正好相反:如果++位于前面,表达式将返回操作之后的值:

int a = 1;
int b = ++a;

这里B是2。

对于你的代码,这意味着

int i = 0;
i += (i++);

i++返回0(如上所述),因此0 + 0 = 0。

i += (++i); // Here 'i' would become two

Scott Meyers在“有效的c++编程”中描述了这两种符号之间的区别。在内部,i++ (postfix)记住i的值,并调用前缀符号(++i)并返回旧值i。这就是为什么你应该总是在for循环中使用++i(尽管我认为所有现代编译器都在for循环中将i++转换为++i)。

上面的答案有很多很好的推理,我只是做了一个小测试,想和你分享

int i = 0;
i+ = i++;

这里result i显示0 result。 现在考虑以下情况:

案例1:

i = i++ + i; //Answer 1

之前我认为上面的代码类似于这个,所以第一眼看答案是1,而这个I的真正答案是1。

案例2:

i = i + i++; //Answer 0 this resembles the question code.

这里的增量操作符没有出现在执行路径中,不像前面的情况,i++有机会在加法之前执行。

我希望这对你有所帮助。谢谢

要非常小心:阅读C常见问题:你试图做的事情(同一个变量的赋值和++混合)不仅没有指定,而且也是未定义的(这意味着编译器在求值时可能会做任何事情!),不仅给出“合理”的结果)。

请阅读第三部分。整个章节都很值得一读!特别是3.9,这解释了未指明的含义。3.3节简要介绍了使用“i++”之类的工具可以做什么,不能做什么。

根据编译器内部的不同,您可能会得到0、2、1,甚至其他任何值!因为它是没有定义的,所以他们这样做是可以的。

这只是从左到右、自底向上的抽象语法树的计算。从概念上讲,表达式的树是从上到下遍历的,但是当递归从树的底部弹出时,计算就展开了。

// source code
i += i++;

// abstract syntax tree

     +=
    /  \
   i    ++ (post)
         \
         i

计算从考虑根节点+=开始。这是这个表达式的主要组成部分。必须计算+=的左操作数,以确定存储变量的位置,并获得前值为零。接下来,右边必须求值。

右边是一个后递增的++操作符。它有一个操作数i,它既作为值的来源,也作为值的存储位置进行计算。运算符对i求值,找到0,然后将1存储到该位置。它根据返回先验值的语义返回先验值0。

现在控制回到+=运算符。现在它有了完成操作的所有信息。它知道存储结果的位置(i的存储位置)以及先前的值,并且它有要添加到先前值的值,即0。所以i最后是0。

像Java一样,c#通过固定求值顺序,清除了C语言中一个非常愚蠢的方面。从左到右,自底向上:程序员可能期望的最明显的顺序。

简单地说,

i++,将在“+=”运算符完成后给“I”加1。

你想要的是++i,这样它就会在“+=”运算符执行之前给“i”加1。