Як працює рекурсивна функція stack overflow російською

Тут 2 функції. main - основна функція програми, fact - функція обчислення факторіала. Факторіал обчислюється циклічним викликом функції fact. У перший раз fact викликається з main, потім поки аргумент функції не стане 1, вона викликає сама себе зі зменшенням аргументу на 1. В кратце якось так. До речі алгоритм не має перевірок аргументів і не зможе обробити аргументи менше 1. - atom-22 23 Серпня '15 о 13:39

окей, а якщо передати fact (2), то вийде що функція не рабоать? т.к n-1 = 1 - user186578 23 Серпня '15 о 13:43

@ User186578: чому ж не буде? буде. - Nick Volynkin ♦ 23 Серпня '15 о 13:44

На майбутнє: коли ставите запитання, пояснюйте докладніше, що вам вже зрозуміло, а що - ще немає, що ви очікували отримати і що отримали натомість. Рекомендую прочитати: Як задавати питання. як створити короткий, завершений і достовірний приклад. - Nick Volynkin ♦ 25 Серпня '15 о 5:15

Факторіал натурального числа N - це добуток всіх чисел від 1 до N включно.

Факторіал 1 дорівнює 1. У всіх інших випадках факторіал (N) дорівнює Факторіалом (N-1) * N.

У цьому прикладі fact (int n) - це рекурсивна функція, вона викликає сама себе.

Наприклад, програма вважає факторіал числа 4.

Як це працює по рекурсивним викликам:

Може бути стане більш зрозумілим, якщо переписати її зовсім коротко

fact () циклічно викликає саму себе, кожен раз з аргументом на 1 менше, ніж її викликали до тих пір, поки її не викличуть з аргументом, рівним 1. В цьому випадку вона поверне 1. В інших випадках вона повертає твір n на результат, який повертає fact (n - 1).

Все це майже дослівно відповідає визначенню факторіала.

А в разі рекурсивної функції масив r [] неявно організовується у вигляді стека активацій функції fact.

Оскільки для обчислення fact (n) досить знати значення fact (n - 1). то очевидно ефективним алгоритмом буде проста ітерація, де на кожному кроці циклу ми будемо множити вже обчислений факторіал на лічильник кроків циклу. Заодно перевіримо допустимість вхідного параметра (факторіал визначено для цілих невід'ємних чисел) і переповнення (тобто вміщається чи черговий проміжний результат в змінну типу int).

У разі помилок повертаємо завідомо неправильний результат: при переповненні нуль, а для негативного аргументу число менше нуля (сам невірний аргумент).

відповідь дан 23 Серпня '15 о 13:43

РЕАЛІЗАЦІЯ БЕЗ рекурсією:

РЕАЛІЗАЦІЯ З рекурсією:

Якщо придивитися, то помітно повторення коду в обох реалізаціях: num * (factorialRecurses (num - 1)); відповідає

Функція викликає функцію всередині себе до тих пір, поки не доходить до нуля. Якщо подивитися в дебаггера, стає зрозуміло, що стек викликів функції в цей момент заповнюється. Тут досить згадати організацію стека. Функція А -> викликає Функцію B -> викликає Функцію C -> викликає Функцію D і т.д. тільки в разі рекурсії виходить, що одна і та ж функція викликає себе багаторазово. Після чого, дійшовши до крайньої точки - нуля, стек поступово зменшується тому повертає результати викликів функції до моменту його повного "руйнування".

відповідь дан 19 Жовтня о 15:21

Схожі статті