Ваша проблема в том, что вы не понимаете понятия функция активации . Каждая активация функции имеет свою собственную копию i
и собственную копию Lemmings
, и они полностью независимы от любой другой активации функции.
Что вас здесь смущает, так это то, что у вас есть пять - да пять - разные вызовы на WriteToConsole
, и у всех них есть собственная копия i
и их собственная копия lemmings
. Давайте проиллюстрируем это, дав инструменту вашей программе показ каждой активации каждой функции и значения каждой переменной в каждой точке:
public class Program
{
private static int callCount = 0;
private static int WriteToConsole(int lemmings)
{
callCount += 1;
int currentCall = callCount;
Console.WriteLine("Call number {0} has Lemmings = {1}", currentCall, lemmings);
int i = lemmings;
Console.WriteLine("Call number {0} has i = {1}", currentCall, i);
while (i > 0)
{
Console.WriteLine("Call number {0} in the loop top with i = {1}", currentCall, i);
i = WriteToConsole(i - 1);
Console.WriteLine("Call number {0} in the loop bottom with i = {1}", currentCall, i);
}
Console.WriteLine("Call number {0} is about to return {1}", currentCall, lemmings - 1);
return lemmings - 1;
}
public static void Main(string[] args)
{
WriteToConsole(3);
}
}
Теперь мы видим, что результат отражает то, что происходит:
Call number 1 has Lemmings = 3
Call number 1 has i = 3
Call number 1 in the loop top with i = 3
Call number 2 has Lemmings = 2
Call number 2 has i = 2
Call number 2 in the loop top with i = 2
Call number 3 has Lemmings = 1
Call number 3 has i = 1
Call number 3 in the loop top with i = 1
Call number 4 has Lemmings = 0
Call number 4 has i = 0
Call number 4 is about to return -1
Call number 3 in the loop bottom with i = -1
Call number 3 is about to return 0
Call number 2 in the loop bottom with i = 0
Call number 2 is about to return 1
Call number 1 in the loop bottom with i = 1
Call number 1 in the loop top with i = 1
Call number 5 has Lemmings = 0
Call number 5 has i = 0
Call number 5 is about to return -1
Call number 1 in the loop bottom with i = -1
Call number 1 is about to return 2
Очень внимательно читайте след , пока не поймете, что происходит. Вы получаете четыре выхода loop x
, потому что номер вызова 1 находится в верхней части цикла, когда i
равен 3, а после рекурсивного вызова i
равен 1. Условие цикла выполнено, поэтому вызовите 1 печатает как loop 3
, так и loop 1
.