[C] Problema esercizio Linguaggio C

pippopluto95
Salve a tutti! :-D
Mi trovo in difficoltà nel seguente esercizio:
"Si vuole scrivere un programma C che, preso in ingresso un valore n, calcoli il valore di fattoriale(n) utilizzando sia il costrutto for che il costrutto while. Inserire nel codiceil controllo sull’input dell’utente."

Ecco il mio codice:


#include <stdio.h>
#include <stdlib.h>

int main()

{
   int a, n, fatt;
   
          
   printf("Inserire un numero naturale per calcolarne il fattoriale: ");
   scanf("%d", &n);
   
      if (n == 0) {
         printf("\n0! = 1\n");
         }
      else {
           
           if (n < 0) {
           printf("\nIl numero inserito non e' valido.\n");
                        }
           else {
                printf("\n%d! = ", n);
                
           //COSTRUTTO FOR
           for (a = 0; (n - a) > 0; a++){
           fatt *= (n - a);
           }
             printf("%d (FOR)\n", fatt); }
             }   
                       
    
    system("pause");
    return 0;
}


Il problema risiede solo nella parte indicata come "//COSTRUTTO FOR": in sostanza se provo a calcolare un numero fattoriale, il risultato che ottengo è sempre il doppio rispetto a quello che dovrebbe venire.

Esempio:
3! = 6 (a me viene 12)
4! = 24 (a me viene 48)
5! = 120 (a me viene 240)

L'unico metodo che mi è venuto in mente per risolvere questo problema è un po' "barbaro":
nella printf finale al posto di sostituire %d con fatt, lo sostituirei con fatt/2 in modo da "aggiustare" il tutto.

Dov'è che sbaglio?

Grazie mille a tutti in anticipo per le risposte! :smt023 :D

PS. Usate il ciclo for e non usate nulla di troppo diverso da come ho fatto io, perchè sono al primo anno di programmazione (ho fatto al momento meno di un mese di scuola!) e sicuramente voi ne sapete più di me e più di quello che ho visto per ora a lezione.

Risposte
apatriarca
Da una rapida occhiata direi che non hai inizializzato la variabile fatt. Ti consiglio di inizializzare sempre le variabili quando vengono dichiarate. In questo modo le variabili hanno sempre un valore ben definito.

pippopluto95
Perdona la mia ignoranza :-D ma come mai dovrei inizializzare fatt? Mi spiego: fatt non dovrebbe cambiare in base a quale valore n assegno all'inizio del programma?
E se inizializzo fatt, cosa cambia se scrivo:

int fatt = 1
int fatt = -1
eccetera...
?

apatriarca
La prima volta che usi fatt scrivi:
fatt *= (n - a);
che è equivalente a
fatt = fatt * (n - a);
Se fatt ha inizialmente un valore casuale (non è inizializzato) allora il tuo risultato verrà moltiplicato per questo valore casuale (nella tua prova 2). Il fatto che sia sempre 2 è però abbastanza strano.. In effetti a me viene qualcosa del genere:
Inserire un numero naturale per calcolarne il fattoriale: 2

2! = -2147369744 (FOR)


P.S. Per inserire il codice utilizza il tag code (devi cioè scrivere [ code ] senza spazi prima del codice e poi inserire [/ code ] senza spazi quando è finito.

pippopluto95
Allora credo di aver inizializzato fatt:

//COSTRUTTO FOR
for (a = 0; (n - a) > 0; a++){
fatt *= (n - a);
}
printf("%d (FOR)\n", fatt); }
}


Va bene se l'ho fatto in questo punto?

PS. Ok scusami non lo sapevo

apatriarca
Non vedo alcuna inizializzazione. In quel codice stai riutilizzando il valore che fatt aveva prima di entrare nel ciclo.

pippopluto95
Quindi dovrei fare così se ho capito bene:
int main()

{
int a, n, fatt;
fatt *= (n - a);

sapo931
"pippopluto95":
Quindi dovrei fare così se ho capito bene:
int main()

{
int a, n, fatt;
fatt *= (n - a);


No, stai confondendo le due cose (inizializzazione e calcolo), ti faccio un esempio:

// Dichiarazione
int a; // a = Valore Casuale

// Inizializzazione
a = 4; // a = 4

// Calcolo
a *= 5  // a = a*5 = 4*5 = 20


Siccome nel tuo codice usi direttamente fatt *= (n - a), cerchi di moltiplicare fatt (che non sai quanto vale) per n - a, portando a risultati strani.

Devi inizializzarlo prima, dandogli un valore "utile", che non modifichi il risultato della moltiplicazione

pippopluto95
Ok! :-D :-D Ora ho tutto chiaro e infatti i conti tornano!

Grazie mille a entrambi!

vict85
Solo una curiosità. Perché hai scritto (n - a) > 0 invece dell'equivalente e più corto n > a?

pippopluto95
Ehm :? :? hai ragione: boh credo di aver fatto così per la mia inesperienza. :D

Grazie del suggerimento! :smt023

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.