C факториальная программа с использованием рекурсии - PullRequest
0 голосов
/ 06 июня 2019

Программа принимает данные и должна рассчитать факториал числа.Однако после ввода числа возникает задержка, и программа останавливается

, пока я не сильно изменил код с моей первоначальной попытки, так как не до конца понимаю рекурсию и солнечные процедуры в C.

int calcFactorial(int n);
int input = 0, answer = 0;

int main()
{
    int n = 0;
    printf("Enter number:\n");
    scanf("%d", &input);
    answer = calcFactorial(input);
    printf("The factorial of %d is %d.\n", input, answer);
    system("pause");
    return 0;
}

int calcFactorial(int n){
    int factorial = 0;
    if (n==0){
        factorial = 1;
    }
    else{
        factorial = n * calcFactorial(n-1);
        printf(factorial);
    }
    return factorial;
}

Ответы [ 2 ]

3 голосов
/ 06 июня 2019

Это утверждение в функции calcFactorial

    printf(factorial);

имеет неопределенное поведение, поскольку первый параметр функции printf объявлен как const char *, пока вы предоставляете объект типа int.

Удалить оператор из функции.

Или, если вы хотите получить промежуточные значения, напишите

printf( "%d\n", factorial);

Также учтите, что для типа int, который обычно имеет размер 4 байта, максимальное число, для которого вы можете получить действительное значение факториала, равно 12.

Вы можете использовать тип unsigned long long int вместо типа int. В этом случае вы можете рассчитать факториал для числа, равного 20.

Вот демонстрационная программа

#include <stdio.h>

unsigned long long int calcFactorial( unsigned long long int n )
{
    return n == 0 ? 1 : n * calcFactorial( n - 1 );
}

int main( void )
{
    unsigned long long int input = 0, answer = 0;

    printf( "Enter number: " );
    scanf( "%llu", &input);

    answer = calcFactorial( input );

    printf( "The factorial of %llu is %llu.\n", input, answer );
}

Его вывод может выглядеть как

Enter number: 20
The factorial of 20 is 2432902008176640000.

Оператор возврата в функции может быть переписан также следующим образом

unsigned long long int calcFactorial( unsigned long long int n )
{
    return n < 2 ? 1 : n * calcFactorial( n - 1 );
}
0 голосов
/ 06 июня 2019

Однако после ввода числа происходит задержка, и программа останавливается

Как уже указывалось другими, printf(factorial) имеет неопределенное поведение.Он должен быть удален или должен называться должным образом (например, printf("%d\n", factorial)).

Не уверен, почему там есть system("pause"), поскольку это кажется ненужным.

Удаление этих двух элементов из вашегокод, у меня не было проблем с его запуском и получением правильного ответа для факториала до 12. Опять же, как уже отмечалось другими, ваша функция будет действительна только до 12! из-за целочисленного переполнения .

Кроме этого, ваш код может быть лучше отформатирован для ввода, например:

/* formats better than original */
printf("Enter number: ");
scanf("%d", &input);
printf("\n");

Вы можете уменьшить свою функцию calcFactorial, так как нет необходимости вПеременная int factorial или предложение else.Таким образом, вы можете сделать так, чтобы это выглядело так:

int calcFactorial(int n){

    if (n == 0) return 1; //base case, 0! is 1

    return n * calcFactorial(n - 1); //all other cases

}

Я не до конца понимаю рекурсию и солнечные процедуры в C

По сути, ваша функция будет вызываться снова и сновас n, и каждый раз, когда он вызывается, мы называем это экземпляром, и в каждом экземпляре n на единицу меньше, чем было в предыдущем экземпляре.Это будет происходить до тех пор, пока не будет достигнут базовый случай (n == 0), тогда этот экземпляр будет возвращаться к экземпляру до него, и это будет происходить до тех пор, пока не будут возвращены все экземпляры.

Для простоты, давайте пройдемся по calcFactorial(3).Достигнут базовый случай, который является экземпляром, который завершает дальнейшие рекурсивные вызовы и возвращает 1.В экземпляре до достижения базового случая n == 1, чтобы этот экземпляр возвращал 1*1, поскольку экземпляр до того, как он возвратил 1.Экземпляр до этого был n == 2, поэтому этот экземпляр возвращает 2*1.Экземпляр до этого был первым n == 3, поэтому этот экземпляр возвращает 3*2.Все экземпляры теперь вернулись, и результат равен 6, и это то, что мы ожидаем от 3!.

Подробнее о рекурсии можно узнать здесь

...