Подтвердить что ты не робот

Эта рекурсивная функция меня озадачивает, что происходит?

Я играл с рекурсией и выполнял эту простую функцию. Я предполагал, что он выведет 9-0 в stdout, но он печатает 0-9. Я не вижу, как это происходит вообще.

int main()
{
        rec(10);
        return 0;
}

int rec(int n){
        if(n > 0)
                printf("%d\n", rec(n -1));
        return n;
}
4b9b3361

Ответ 1

Как говорит Майкл Барр в комментариях, если вы хотите посмотреть, что происходит, скомпилируйте с включенными символами отладки, например:

gcc -o test -g test.c

Затем запустите с помощью gdb.

gdb test

Затем, чтобы начать все, введите

start

Что происходит при первом вызове основной функции. Тип

step

чтобы перейти к следующей строке в коде, и с этого момента просто нажмите Enter, чтобы повторить последнюю команду. Если вы счастливы, введите continue, чтобы остановить переход. Вы увидите значения и оцениваемые строки на каждом этапе, которые подтвердят приведенные выше ответы.

Надеюсь, что предоставит некоторую полезную информацию.

Ответ 2

Функция rec в строке printf оценивается до самого printf. Таким образом, сначала печатается самый глубокий экземпляр функции rec.

Ответ 3

Подумайте об этом так.

rec(10)
rec(9)
rec(8)
rec(7)
rec(6)
rec(5)
rec(4)
rec(3)
rec(2)
rec(1)
rec(0)

Начать разматывание

printf("%d\n", 0);
printf("%d\n", 1);
printf("%d\n", 2);
printf("%d\n", 3);
printf("%d\n", 4);
printf("%d\n", 5);
printf("%d\n", 6);
printf("%d\n", 7);
printf("%d\n", 8);
printf("%d\n", 9);

Ответ 4

Перепишите свой код следующим образом:

int rec(int n){
        if(n > 0)
        {
                int retval = rec(n -1);
                printf("%d\n", retval);
        }
        return n;
}

Означает ли это, почему 0 печатается сначала до 9?

Ответ 5

Поскольку вы создаете 9 ambients 9 > 8 > 7 > 6 > 5 > 4> 3 > 2 > 1 > 0, теперь эти амбиции обрабатываются одинаково, это будет a(b(c(d(e(f(g())))))), переходя от самого глубокого к первому.

Помните, что когда вы делаете это printf("%d",n(m));, вы на самом деле ничего не печатаете, вы говорите "распечатайте результат n (m)", а затем, когда он пытается разрешить n (m), вы вызываете другую печать и еще раз сказать "разрешить n (m-1)".

Теперь, когда вы достигнете n (0), он вернет 0, который будет напечатан последним вызовом printf, поэтому он печатает 0, затем 1.. 9.

Ответ 6

int main()
{
        rec(10);
        return 0;
}

int rec(int n){
        if(n > 0)
                printf("%d\n", rec(n -1));
        return n;
}

В общем, рассмотрим часть кода. Мы говорим, что существует прямая связь между итерационными и рекурсивными решениями, так что любое решение можно записать итеративно и наоборот. Однако в некоторых случаях легче выразить алгоритм рекурсивно (например, Башня Ханоя). В случае с кодом выше эквивалент будет конструкцией цикла цикла.

Это может быть реализовано как функция следующим образом:

void _for(int i, int n)
{
    if( i >= n ) return; // TERMINAL<br />
    // some expression (ie. printf("%d\n",i);)<br />
    _for(i+1,n) // RECURSION<br />
}

Примечание. Это можно расширить с помощью указателей функций.