Как работает рекурсивная функция и что в какой момент она возвращает?

#include <stdio.h>

int factorial(int num);

int main()
{   
    int num;
    printf("Enter a number to print its factorial\n");
    scanf("%d",&num);
    printf("factorial is %d",factorial(num));
    return 0;
}

int factorial(int num)
{
    if (num==1)
    {
        return 1;
    }
    int factNm1,factN;
        printf("%d,num); 
//why is it even printing 2 and not 1 when i print the value of num AND HOW THE other values are getting
//stored in factNm1?
    factNm1 = factorial(num-1);
    factN = factNm1 * num;                                                   
    return factN;                                                                               
}

Результат нормальный, я откуда-то скопировал этот код, но до сих пор не могу его понять.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Очистка форматирования этой функции:

int factorial(int num)
{
    if (num == 1)
    {
        return 1;
    }

    int factNm1, factN;

    printf("%d", num); 

    factNm1 = factorial(num - 1);
    factN = factNm1 * num;  
                                                 
    return factN;                                                                             
}

Это очень просто. Если num равно 1, функция немедленно возвращает 1. Конец истории.

В противном случае поток управления продолжается. Объявлены две новые переменные int. Мы также печатаем значение num, которого не может быть 1, иначе мы бы никогда не дошли до этого вывода.

factNm1 является результатом вызова той же функции факториала, но с меньшим числом. Это означает, что, если мы не указали отрицательное число или ноль, мы сходимся к 1, что является базовым случаем для рекурсии.

Затем мы возвращаем полученное значение, умноженное на входное значение num. Таким образом, что-то вроде factorial(4) фактически является 4 * 3 * 2 * 1.

Ответ принят как подходящий

Рекурсивная функция глубоко вызывает функцию внутри себя до тех пор, пока не возникнут некоторые условия.

Пример:

function recursiveFunction(n){
  // calling itself
  return n * recursiveFunction(n-1)
}

Давайте посмотрим, как это работает?

Когда вы вызываете recursiveFunction(5)

он возвращает 5 * recursiveFunction(4) но подождите... само возвращаемое значение содержит вызов, нам нужно решить его, прежде чем вернуться. поэтому он возвращает 5 * 4 * recursiveFunction(3) это продолжается как 5 * 4 * 3 * 2 * 1 * -1 * -2 * -3 * recursiveFunction(-4) и так далее.

Чтобы остановить рекурсивную функцию, нам нужно условие остановки, и в этом случае нам нужно остановиться, когда число станет равным 1.

поэтому мы можем изменить приведенный выше код следующим образом:

    function recursiveFunction(n){
      if (n=1){
        return 1;
        // it stops before calling itself again, and we get a number instead of another deep call.
      }
      
      // calling itself
      return n * recursiveFunction(n-1)
    }

поэтому после 5 * 4 * 3 * 2 * recursiveFunction(1) мы просто получаем 5 * 4 * 3 * 2 * 1

рекурсия полезна при решении многих алгоритмических задач. счастливого кодирования

В этом вопросе конкретно упоминается C. Почему вы предлагаете код на Javascript?

Chris 24.08.2024 23:16

Я думаю, ему нужно изучить эту концепцию, а я разработчик JS.

Ashfaque Ahmed 24.08.2024 23:25

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

Каждая рекурсия должна иметь хотя бы одно завершающее условие.
В функции factorial() условие завершения рекурсии таково:

if (num==1)
{
    return 1;
}

Например. принять значение num как 4

First call : num is 4
4==1 : false
factorial(4-1)    --> Recursive call 1 : num value is 4 here
|   3==1 : false
|   factorial(3-1)    --> Recursive call 2 : num value is 3 here
|   |   2==1 : false
|   |   factorial(2-1)    --> Recursive call 3 : num value is 2 here
|   |   |   1==1 : true
|   |   |   | [Hit the terminating condition]
|   |   |   | [Last recursive call will return 1 and stack will wind up now]
|   |   |   | 
|   |   |   |
|   |   |   return 1;
|   |   factNm1 = 1; factN = 1 * 2; return 2; // num is 2 here, factN calculated to 2
|   factNm1 = 2; factN = 2 * 3; return 6; // num is 3 here, factN calculated to 6
factNm1 = 6; factN = 6 * 4; return 24; // num is 4 here, factN calculated to 24

Следовательно, результат, который вы получаете для значения num4, равен 24.

замечательный парень, долго пытался это понять, мне очень помогло!

Zaryab Ahsan 25.08.2024 13:26

Другие вопросы по теме