2016-07-02 4 views
-5
#include<iostream> 
using namespace std; 

int factorial(int x) 
{ 
    if(x == 1) 
    { 
     return 1; 
    } 
    else 
    { 
     return x*factorial(x-1); 
    } 
} 

int main() 
{ 
    cout<<factorial(5)<<endl; 
} 

Я не получаю часть, когда значение достигает 1. Почему программа не выводит 1 в качестве вывода, потому что когда 1 достигнут, она возвращает 1. Рассмотрим приведенные ниже шаги.Какова логика этой рекурсивной программы для поиска факториала в C++?

5*factorial(4)=5*4*factorial(3)=5*4*3*factorial(2)=5*4*3*2*factorial(1)

Так что теперь, когда значение x становится 1 и переходит в случае, если условие становится истинным и 1 возвращается. Так почему же он не выводит 1? Разве что значение 5*4*3*2*factorial(1) хранится где-то, а возвращаемое значение просто умножается на 5*4*3*2*1 и выдает 120?

Также объясните, что происходит, когда мы передаем 0 вместо 5, как это будет выводить 1? (0! = 1)

+2

Я запутался, почему это даже вопрос? Вы можете легко запустить это в компиляторе и пройти через код, чтобы увидеть beviour – Leon

+0

«... когда мы передаем 0 вместо 5, как это будет выводить 1?» - что заставило вас думать, что в этом случае выйдет 1? На самом деле это не так. Скорее всего, это просто сбой. – AnT

+0

Если вы уже знаете, что предыдущие рекурсивные вызовы эквивалентны в последовательности '5 * 4 * 3 * 2 * factorial (1)', то какие у вас проблемы с последним шагом и понимание того, что все это '5 * 4 * 3 * 2 * 1', что составляет '120'? – AnT

ответ

3

это так же, как вы сказали:

5*factorial(4)=5*4*factorial(3)=5*4*3*factorial(2)=5*4*3*2*factorial(1) 

Так что, если она достигает 1, то это будет заменено

5*factorial(4)=5*4*factorial(3)=5*4*3*factorial(2)=5*4*3*2*1 

поэтому результат последнего шага переходит во второй последней стадии. ... где будет вычисляться 2 * 1 ... После этого третий последний шаг получает значение 2 * 1 = 2 и умножает 3 на дюйм и так далее.

Если вы вставляете меньше или равно 0 в свою функцию, вы получите бесконечную рекурсию, потому что если (0 == 1). Но если заменить этот код с

int factorial(int x) 
{ 
    if(x <= 1) 
    { 
     return 1; 
    } 
    else 
    { 
     return x*factorial(x-1); 
    } 

} 

Тогда также 0 и -чисел будет работать

+0

Почему у вас есть 'else if', а не просто опустить оператор else else? Теперь у вас есть ветка, которая никогда не вернется, хотя эта ветка никогда не будет достигнута. – martijnn2008

+1

np, мы здесь, чтобы помочь друг другу;) – martijnn2008

+0

это было потому, что я думал 0! = 0, но это неправильно ... 0! = 1! = 1;) – Thomas

1

Стек хранит в некотором смысле все ожидающие операции операции. Как только факт (2) получает 1 от вызова, он умножает его на 2 и возвращает 2. факт (3) получает, что 2, умножает его на 3 и возвращает 6. факт (4) получает, что 6, умножает его на 4 и возвращает 24. И так далее ...

Передача 0 в текущей форме программы и не означала, что программа будет сбой (скорее всего). Изменение строки if (x == 1) на if (x == 0) исправит это.

+0

Он потерпит крах из-за переполнения стека или, может быть, он снова достигнет 1 после долгого времени, если стек можно сделать достаточно большим. Если стек не переполняется и доходит до 1, он возвращает нуль. –

+0

(или, по крайней мере, того, что я ожидал бы от программы, которая корректно работает на случаях с n> = 1) –

+0

Ну, это не очевидно UB (но всякий раз, когда я упоминаю переполнение стека, я как бы подразумеваю UB простым факт, что компилятору разрешено предположить, что такое переполнение стека не произойдет) –

Смежные вопросы