2013-09-25 1 views
-1

Я работаю на довольно простое отслеживание упражнения, однако я не совсем понимая, почему решение, что это такое ...простой рекурсия трассировка понимание стеки

void f(int n) { 
    if (n>0) { 
    f(n-1) 
    cout << n << " "; 
    } 
} 

int main() { 
    f(5); 
    return 0; 
} 

ответ 1 2 3 4 5 , однако мне интересно, как это происходит, поскольку каждый раз, когда функция f называется, она никогда не попадает в строку cout ... Я понимаю, что существует система стекирования, в которой просматривается последняя функция, однако до факториала где он возвращал значение для умножения на предыдущее n, я не понимаю, как это похоже. Пожалуйста, не используйте факториал снова, я это понимаю, но я не понимаю, как здесь реализуется cout. Спасибо за вашу помощь.

+0

Этот код не скомпилирован. – chris

+2

Ответ - это буквально карандаш/ручка и лист бумаги. Не должно быть сложной задачу с шестиуровневым стеклом вызовов. – WhozCraig

ответ

0

Это делает подходит к выходной строке, после рекурсивного вызова f возвращается.

Важной частью здесь является условие остановки:

if (n>0) 

Это делает рекурсивный вызов только в том случае, если n больше нуля. И поскольку рекурсивный вызов имеет аргумент n - 1, он будет ниже и ниже, пока он не станет равным нулю, и больше вызовов не будет.

Позволяет отслеживать его для вас, так как вы должны ленивого сделать это самостоятельно в отладчике (или на бумаге):

  1. Первый звонок от main сделан. n == 5 и явно больше, чем ноль, так что рекурсивный вызов сделан с 5 - 1
  2. Во втором вызове, n == 4, все еще больше нуля, чтобы вызов сделан снова с 4 - 1
  3. В третьем вызове, n == 3, еще больше ноль поэтому вызов выполняется снова 3 - 1
  4. В четвертом вызове, n == 2, еще больше, чем ноль, так вызов сделан снова 2 - 1
  5. В пятом вызове, n == 1, еще больше нуля, так при выполнении вызова снова с 1 - 1
  6. В шестом вызове n == 0, который не больше нуля, поэтому больше вызовов не производится, и функция возвращается.
  7. Возврата к n == 1 и так 1 печатаются, а затем функция возвращает
  8. Возврата к n == 2, и так 2 печатаются, а затем функция возвращает
  9. Возврата к n == 3, и так 3 печатаются, а затем функция возвращает
  10. возврат к n == 4, и так 4 печатается, а затем функция возвращает
  11. возврат к n == 5, и так 5 печатается, а затем функция возвращается к функции main

То есть, это должно было сработать, если оно скомпилировано. Теперь он даже не зайдет так далеко, поскольку у вас будут ошибки компилятора (с кодом, как показано в вашем вопросе).

+1

Другими словами, как и любой другой вызов функции, программа в конечном итоге вернется из f (n-1) и перейдет к следующей строке. Он не может просто пропускать строки. –

+0

@joachim pileborg благодарю вас за то, что он дал мне это! Я понимаю это намного лучше! – user2809437

0

Рассмотрите простой случай звонка f(1). Мы проходим тест if и делаем рекурсивный вызов f(0). Этот вызов вернется, ничего не сделав, и продолжит выполнение тела f(1). Следующее утверждение является призыв к std::cout << 1 << " ";:

// Substitute the parameter with the passed in argument n = 1 
void f(1) { 
    if (1 > 0) { 
    f(0); 
    std::cout << 1 << " "; 
    } 
} 

Теперь вы должны быть в состоянии справиться случае f(2), и вообще f(n). Всякий раз, когда вы задумываетесь о рекурсивных программах, рассматривайте базовые случаи, а затем обобщайте. Запишите код, заменив параметры функции фактическими аргументами.