2009-05-09 8 views
0

zu bekommen. Ich kann den folgenden Code nicht zum Funktionieren bringen.Es ist nicht möglich, eine faktorielle Funktion in C

#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; 
} 

Wie können Sie den Code zu arbeiten?

Antwort

9

gab AInitak die richtige Antwort, aber ich mag, dass ein Weg addieren Sie der Fehler im Code finden ist, die Werte von i und x in der Fakultäts Schleife auszudrucken.

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

Dies gibt Ihnen die Ausgabe

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 

Dies macht es leichter zu sehen, was falsch läuft. Die Schleife hört nicht auf, wo Sie es aus den Gründen erwarten, die AInitak erklärte.

1

Welche Fehlermeldung erhalten Sie?

Zuerst erkläre deine Funktion factorialvormain. Achten Sie auch auf korrekte Einrückung. Ihre Funktionserklärung main ist übrigens richtig.

+0

Nicht in C; es sollte eine "Leere" haben. Siehe Litb's Antwort. –

+0

@Danke, dass du auf die Konvention hingewiesen hast, der ich nicht gefolgt bin. Mein Fehler "Nachricht" war, dass ich eine zu große negative Nummer bekommen habe. –

+0

Was soll ich in meiner Einrückung korrigieren, um es C-ähnlicher zu machen? –

15

Sie ändern Ihre Schleifenbeendigungsvariable (x) innerhalb der Schleife. Zur Zeit explodiert Ihr Code nach ein paar Iterationen, wenn x den Bereich einer 32-Bit-Ganzzahl überläuft und dann negativ und sehr groß wird, wodurch die Schleife beendet wird.

Es sollte sein:

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

Noch besser wäre es, Sie long statt int für die Variable x und den Rückgabewert, da n verwenden sollten! wird sehr schnell sehr groß.

+0

Ich änderte ints zu longs. Ich erhalte die folgende Fehlermeldung: http://dpaste.com/42442/. Ich brauche anscheinend eine Bibliothek. –

+0

Sie haben zu viele Eingaben geändert. Die Rückkehr von main sollte immer noch ein int sein. – Alnitak

1

Ich würde vorschlagen, auch doppelt oder unsigned long für faktorielle Berechnung zu verwenden, um in der Lage zu sein, den größeren Wert der faktoriellen Funktion zu berechnen.

double fact(double n) 
{ 
    if (n == 1) 
     return 1; 
    return n*(fact(n-1)); 
} 
3

Es ist schlechter Stil in C void auszulassen bei der Definition oder eine Funktion zu deklarieren. Also es ausdrückte in

int main(void) 

Während es nichts über die Anzahl der Parameter ändert sich die Funktion (die Funktion hat null Parameter, ohne dass void entweder), wird die Funktion erklärt als eine, die nur null Argumente akzeptiert , während es nichts über die Menge und Arten der akzeptierten Argumente sagt, wenn Sie die void weglassen. Beide Versionen mit und ohne void sind jedoch korrekt.

Lesen Sie this answer über diese Angelegenheit auch.

+0

@Danke, dass du darauf hingewiesen hast! :) –

+0

@litb: Es scheint, dass C wie Python ist. Nehmen wir an, ich verwende die Konvention "Explizit ist besser als implizit". Bin ich damit besser in C als ohne? –

+0

Ja, ich denke, dass diese Regel im Allgemeinen in Ordnung ist. Es gibt Fälle, in denen ich implizite Dinge verwenden würde: Wie die Umwandlung von void * in etwas anderes, wenn das Ergebnis sowieso gleich ist, oder die Umwandlung von int in long (aber nicht umgekehrt). In diesem speziellen Fall wird fehlende void jedoch ein anderes Ergebnis haben (wird der Funktion keinen Prototyp geben - so können weder Argumente überprüft werden, noch ist bekannt, wie viele Argumente erwartet werden). Also geh in diesem Fall immer mit "void". –

2
#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; 

} 
+0

Beispielausgabe? –

+1

Ausgabe: Fakultät: 5 Fakultät von 5 ist 120 – Priyanka

1

Eine elegantere nicht-rekursive Funktion.

#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; 
} 
+0

Können Sie Ihren Vorschlag bitte mit BillTheLizard vergleichen. http://Stackoverflow.com/a/843221/54964 Also, warum ist Ihr Vorschlag besser als sein? Was ist der Zweck von 'long long int'? –