2017-04-21 74 views
59

这是一个简单的控制台应用程序代码,它返回一个我完全不理解的结果。有趣的访谈练习结果:返回,递增和参考行为

试想想它是否输出0,1或2控制台:

using System; 

namespace ConsoleApplication 
{ 
    class Program 
    { 
     static void Main() 
     { 
      int i = 0; 
      i += Increment(ref i); 

      Console.WriteLine(i); 
      Console.ReadLine(); 
     } 

     static private int Increment(ref int i) 
     { 
      return i++; 
     } 
    } 
} 

答案是0

我不明白的是为什么后递增i++,从Increment方法,它在ref上执行(不在传入变量的副本上)会增加变量,但稍后会被忽略。

我的意思是在这个视频:

有人能解释一下这个例子,为什么在调试期间我看到值增加1,但随后又回到0?

+0

当执行'返回i ++'时,i(它是0)的值在它递增前返回。当增量可能发生时,该值将被丢弃,因为它已经返回。试着做'return ++ i;'来代替。 – shahkalpesh

+0

是的,但是你正在更新参考....它不应该回落到0.并且它被执行,因为调试器中的值被更新为1 – Sidewinder94

+0

这是因为后增量运算符。 尝试阅读Eric Lippert的这个优秀答案,以了解后增量如何工作: http://stackoverflow.com/questions/3346450/what-is-the-difference-between-i-and-i/3346729#3346729 – Boney

回答

101

i += Increment(ref i);相当于

i = i + Increment(ref i); 

的赋值的右手侧的表达式从左至右评价,所以下一步是

i = 0 + Increment(ref i); 

return i++返回的当前值i(即0),然后增量i

i = 0 + 0; 

在赋值之前i的值为1(在Increment方法中增加),但赋值再次使其为0。

+3

......你比我快一点;) – DarkSquirrel42

+0

谢谢Jakub,了解细节,现在它为什么是1,再次变成0。 – Aremyst

+0

所以如果这条线是'i = Increment(ref i)+ i',结果会不一样?我不会说谎,这是第一次'从左到右'的规则对我的心理模型产生了影响......布尔短路之外我猜 – user1935361

17

我认为这里的“神奇”之处只是 操作优先 操作顺序

i += Increment(ref i) 

相同

i = i + Increment(ref i) 

的+操作执行从左到右

所以首先我们把...当时是0 ...

然后我们加上Increment(ref i)...的结果也是0 ... 0 + 0 = 0 ...但是等到...在我们得到结果之前我实际上是递增的...

在我们的+操作的左操作数已经被评估之后发生增量...所以它不会改变一个事物... 0 + 0仍然是0 ...因此在+操作之后i被赋值为0执行

+3

与优先级无关,所有与从左到右的评估有关。 –

+0

仔细阅读...运算符优先权!=操作优先顺序...从左到右依次排列... – DarkSquirrel42

+4

我仔细阅读。你写得不好。使用正确的术语 - 操作顺序,而不是优先顺序。优先级决定如何从不明确的输入构建AST。操作/评估顺序决定了AST如何评估结果。使用短语'操作优先'既不意味着。 –

0

正如你所提到的 - postincrement“i ++”。声明 - “返回i ++;”将在返回原始值后在内存中设置'i'的值。

尝试使用“return ++ i;”可能你会得到它。

+1

我不认为这是正确的。语句'返回i ++;'递增'i',然后返回'i'的前一个值,它是0.我从Eric Lippert的答案中获取这些信息:http://stackoverflow.com /问题/ 3346450 /什么,是最差之间-I型和I/3346729#3346729 –