Когда n = 5, почему часть «Done!» Печатается 5 раз, даже если это после рекурсивного оператора вызова? - PullRequest
0 голосов
/ 14 апреля 2020

Я понимаю, почему часть "Я вычисляю" печатается 5 раз, так как она находится над оператором вызова. Не должен "Готово!" часть будет напечатана только один раз после печати пяти строк «Я вычисляю», а затем будет возвращена f?

int factorial( int n)
{
    cout<<"I am calculating F("<<n<<")\n ";
    if(n == 0)
        return 1 ;
    int f = n * factorial(n - 1);
    cout<<"Done! F("<<n<<") = " <<f<<'\n';
    return f;  
}

int main()
{
  int n;
  cin>>n;
  int result = factorial(n);
  cout << result;  
}

CODE OUTPUT:
5
I am calculating F(5)
 I am calculating F(4)
 I am calculating F(3)
 I am calculating F(2)
 I am calculating F(1)
 I am calculating F(0)
 Done! F(1) = 1
Done! F(2) = 2
Done! F(3) = 6
Done! F(4) = 24
Done! F(5) = 120
120



Ответы [ 3 ]

1 голос
/ 14 апреля 2020

Вы звоните в общей сложности factorial 6 раз, и только 1 из этих случаев if(n == 0) соответствует истине, и return 1 выполняется (до того, как DONE будет напечатано), остальные 5 раз - до завершения. до return f!

Именно так и ожидается.

  • main() печать 5
  • main() звонки factorial(5)
    • factorial(5) печать I am calculating F(5)
    • factorial(5) вызовы factorial(4)
      • factorial(4) печать I am calculating F(4)
      • factorial(4) вызовы factorial(3)
        • factorial(3) отпечатков I am calculating F(3)
        • factorial(3) вызовов factorial(2)
          • factorial(2) отпечатков I am calculating F(2)
          • factorial(2) вызовов factorial(1)
            • factorial(1) печать I am calculating F(1)
            • factorial(1) вызовы factorial(0)
              • factorial(0) печать I am calculating F(0)
              • С n 0 сейчас, factorial(0) возвращает 1 в factorial(1)
            • factorial(1) устанавливает f в 1 * 1 со вторым 1, возвращающимся из factorial(0) вызов
            • factorial(1) печать Done! F(1) = 1
            • factorial(1) возвращает 1 в factorial(2)
          • factorial(2) комплектов f до 2 * 1 ш При 1 возвращении с factorial(1) звонка
          • factorial(2) печати Done! F(2) = 2
          • factorial(2) возвращает 2 в factorial(3)
        • factorial(3) устанавливает f на 3 * 2 с 2, возвращающимся с factorial(2) вызова
        • factorial(3) отпечатков Done! F(3) = 6
        • factorial(3) возвращает 6 на factorial(4)
      • factorial(4) устанавливает f на 4 * 6 с 6, возвращающимся с factorial(3) вызова
      • factorial(4) печатает Done! F(4) = 24
      • factorial(4) возвращает 24 в factorial(5)
    • factorial(5) устанавливает f в 5 * 24 с 24 возвращается с factorial(4) звонка
    • factorial(5) печатает Done! F(5) = 120
    • factorial(5) возвращает 120 main()
  • main() печатает 120 с 120, возвращающимся с factorial(5) звонка
0 голосов
/ 14 апреля 2020

Я понимаю, почему часть "Я рассчитываю" напечатана 5 раз

Вы ошибаетесь. Этот текст выводится 6 раз для чисел 0 - 5 включительно.

Этот оператор

cout<<"Done! F("<<n<<") = " <<f<<'\n';

выполняется 5 раз, потому что когда n равно 0, функция завершается.

if(n == 0)
    return 1 ;

То есть при n, равном 0, оператор не получает управление.

0 голосов
/ 14 апреля 2020

Это потому, что рекурсивный вызов в вашем коде не прекращает выполнение вызывающей функции.

return только после части print it out.

Поэтому каждый вызов функции, верхнего или более высокого уровня, печатает текст непосредственно перед возвратом результата вызывающей стороне, почти так же, как при печати «Я вычисляю» каждый раз.

Попробуйте найти способ обнаружить, что текущее выполнение находится на верхнем уровне или на самых глубоких вызовах, и просто добавьте if, чтобы распечатать «Done» только в этом случае.

РЕДАКТИРОВАТЬ: или просто переместите 'print' Done '' из factorial и переместите его в main, после вызова factorial ..

...