Простая рекурсивная функция, не дающая ожидаемого результата - PullRequest
0 голосов
/ 27 апреля 2019

Извините, если я сделал это неправильно, я действительно новичок в C и раньше не использовал переполнение стека.Я пытаюсь отследить эту простую рекурсивную функцию вручную, но получаю другой ответ из скомпилированного кода.

Мой мыслительный процесс был

print 2 |n = 2-1 = 1 |1> = 0 |обратный отсчет (1)

печать 1 |n = 1-1 = 0 |0> = 0 |обратный отсчет (0)

печать 0 |n = 0-1 = -1 |-1 не> = 0 |

печать -1 |КОНЕЦ

void countdown(int n)
{
    printf ("n = %d\t", n);
    n--;
    if (n >= 0)
    {
        countdown(n);
    }
    printf ("n = %d\t", n);
}

int main ( )
{
    countdown(2);
    return 0;
}

Я ожидал получить: n = 2 n = 1 n = 0 n = -1

, но скомпилированный код дает мне: n = 2 n = 1 n = 0n = -1 n = 0 n = 1

Я не совсем уверен, откуда появляются дополнительные 0 и 1 после -1

Ответы [ 3 ]

1 голос
/ 27 апреля 2019

Ваш код выполняет следующие действия (исключая if):

countdown(n):
     print(n)
       countdown(n-1)
     print(n-1)

Для n = 2:

countdown(2):
     print(2)
       countdown(1)
     print(1)

-> next recursion step
     print(2)
       print(1)
         countdown(0)
       print(0)
     print(1)

-> next recursion step
     print(2)
       print(1)
         print(0)
         print(-1)
       print(0)
     print(1)
0 голосов
/ 27 апреля 2019

Здесь вы вызываете countdown () рекурсивно и вызывается трижды.
Фактически каждый рекурсивный вызов помещает countdown () в стек.

SF1(Bottom of stack) ---> SF2 ---> SF3 (Top of stack). 

Теперь будет выполнен кадр вверху.
Во время возврата из функции будет выведен конкретный кадр стека.
Теперь указатель кадра стека указывает на SF2, а затемSF1.

Учитывая вашу программу, ниже приведен поток.
Операция Push:
SF1 будет сначала помещен в стек

n = 2 printed.  
Again n updated to 1

SF2 нажата:

n = 1 got printed.  
Again n updated to 0

SF3 нажата:

n = 0 got printed.  
Again n updated to -1.  
But n <= 0, So if check fails.  

Операция всплытия:
Теперь SF3 выскочил из стека первым.

n = -1 printed  

Затем SF2 лопнул

prints n = 0.

Наконец SF1

n = 1 printed
0 голосов
/ 27 апреля 2019

Ваш код не имеет проблем.Просто удалите 2-й printf код.

void countdown(int n)
{
    printf("n = %d\t", n);
    n--;
    if (n >= 0)
        countdown(n);
}

int main()
{
    countdown(2);
    return 0;
}

Результат:

n = 2 n = 1 n = 0

Это стэк вызова, когда я захватил на 2nd printf.

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(0). Now, n is -1. 
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(0)
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(1)
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

Если вы выполняете отладку еще один, вы можете увидеть callstack, как показано ниже:

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(1) after executed countdown(0).
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(1)
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

И, если вы выполните отладку еще один, вы можете увидеть callstack, как показано ниже:

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(2) after executed countdown(1).
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

И, наконец, Программа будет закрыта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...