Невозможно получить факториальную функцию для работы в C - PullRequest
0 голосов
/ 09 мая 2009

Я не могу заставить работать следующий код.

#include <stdio.h>

// I am not sure whethere I should void here or not.
int main() {
    // when the first bug is solved, I put here arg[0]. It should be
    // similar command line parameter as args[0] in Java.
    int a=3;                  
    int b; 
    b = factorial(a);

    // bug seems to be here, since the %1i seems to work only in fprintf
    printf("%1i", b);
    return 0;      
}  

int factorial(int x) {
    int i; 
    for(i=1; i<x; i++) 
        x *= i; 
    return x; 
}  

Как заставить код работать?

Ответы [ 7 ]

15 голосов
/ 09 мая 2009

Вы изменяете завершающую переменную цикла (x) внутри цикла. В настоящее время ваш код взрывается после нескольких итераций, когда x переполняет диапазон 32-разрядного целого числа, а затем становится отрицательным и очень большим, что приводит к прекращению цикла.

Должно быть:

int factorial(int n) {
    int i, x = 1;
    for (i = 2; i <= n; ++i) {
        x *= i;
    }
    return x;
}

Еще лучше, вы должны использовать long вместо int для переменной x и возвращаемого значения, потому что n! становится очень большим очень быстро.

9 голосов
/ 09 мая 2009

AInitak дал правильный ответ, но я хочу добавить, что одним способом вы можете найти ошибка в вашем коде - вывести значения i и x в цикле факториала.

int factorial(int x) {
    int i;
    for(i=1; i<x; i++)
    {
        x *= i;
        printf("%d, %d\n", i, x);
    }
    return x;
}

Это дает вам вывод

1, 3
2, 6
3, 18
4, 72
5, 360
6, 2160
7, 15120
8, 120960
9, 1088640
10, 10886400
11, 119750400
12, 1437004800
13, 1501193216
14, -458131456
-458131456

Это облегчает понимание того, что происходит не так. Цикл не останавливается там, где вы ожидаете, по причинам, объясненным AInitak.

3 голосов
/ 09 мая 2009

Это плохой стиль в C: не указывать void при определении или объявлении функции. Так что положи в

int main(void)

Хотя это ничего не меняет в количестве параметров, которые имеет функция (функция имеет нулевые параметры и без этого void), она объявит функцию как принимающую только нулевые аргументы, в то время как она не будет Сообщите что-нибудь о количестве и типах принятых аргументов, когда вы опускаете void. Однако обе версии с void и без него являются правильными.

Прочтите этот ответ и об этом тоже.

2 голосов
/ 10 августа 2014
#include<stdio.h>

#include<stdlib.h>

int main(int c,char *v[])

{

    int x,y;

    int *num;

    if(c==1)

    {

    printf("Usage : programName : number");

    return 0;

    }

    num=(int *)malloc(sizeof(int));

    *num=atoi(v[1]);

    x=1;y=1;

    while(x<=*num)

    {

    y=y*x;

    x++;

    }

    printf("Factorial of %d is %d ",*num,y);

    free(num);

    return 0;

}
1 голос
/ 26 июля 2016

Более элегантная нерекурсивная функция.

#include<stdio.h>
long long int fact(long long int);

long long int fact(long long int n){
    long long int num = 1;
    long long int fi = 0;
    for(long long int i=2;i<=n;i++){
        for(long long int j=1;j<=i;j++){
            fi += num;      
        }
        num = fi;
        fi = 0;
    }       
return num;
}    
int main(){
    long long int n;
    scanf("%lld",&n);
    printf("%lld\n",fact(n));
return 0;
}
1 голос
/ 09 мая 2009

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

double fact( double n)
{
   if ( n == 1)
        return 1;
   return n*(fact(n-1));
}
1 голос
/ 09 мая 2009

Какое сообщение об ошибке вы получаете?

Прежде всего, объявите вашу функцию factorial перед main Также обратите внимание на правильные отступы. Кстати, ваше объявление функции main правильное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...