Ricorsione Fibonacci in C

di il
19 risposte

Ricorsione Fibonacci in C

Scusate se mi accodo anche io. La mia richiesta è leggermente diversa in quanto sto cercando ci capire un codice di linguaggio C per quanto riguarda la ricorsione di Fibonacci. Il codice è il seguente:
#include <stdio.h>
#include <stdlib.h>

long fibonacci (long);

int main(int argc, char *argv[])

{
    int n;
    printf("Calcolo numero di Fibonacci - Digita un numero naturale: ");
    scanf("%d", &n);
    printf("Il numero di Fibonacci nella posizione %d e': %ld\n", n, fibonacci (n));
    system("PAUSE");
    return 0;
}
  long fibonacci (long i)

{
    if (i==0)
        return 0;
    else if (i==1)
        return 1;
    else
        return fibonacci(i-1) + fibonacci(i-2);
}
Quello che voglio capire è come fa il compilatore a sapere che posizioni hanno i numeri che inserisco in base al calcolo della funzione.
Mi spiego meglio, se io metto il numero 13 mi da risultato 233, il chè è corretto, ma come e dove lo fa il calcolo?
Nella mia ignoranza ho pensato che fibonacci(13-1) + fibonacci(13-2) = 12 + 11 = 23, mentre il compilatore fa un altro tipo di calcolo che non riesco a notare nel codice.
Quello che mi serve sapere è l'operazione, graficamente nascosta, che fa l' ultimo return (sicuramente è un ciclo).

19 Risposte

  • Re: Ricorsione Fibonacci in C

    Niente cicli ma tante chiamate della funzione. Se sai cosa succede quando si chiama una funzione, con il passaggio dei parametri e il valore restituito, prova a scrivere su carta come viene eseguita la funzione ad esempio per il valore 5.

    E attento che fibonacci(13-1) non è uguale a 12 come hai scritto tu ma a fibonacci(12)
  • Re: Ricorsione Fibonacci in C

    oregon ha scritto:


    Niente cicli ma tante chiamate della funzione. Se sai cosa succede quando si chiama una funzione, con il passaggio dei parametri e il valore restituito, prova a scrivere su carta come viene eseguita la funzione ad esempio per il valore 5.

    E attento che fibonacci(13-1) non è uguale a 12 come hai scritto tu ma a fibonacci(12)
    ecco, infatti prima di mettermi a scrivere su un foglio la sequenza dei calcoli, vorrei sapere prima da voi che tipo di calcolo devo fare.
    l' unica cosa che so, o meglio penso di sapere, è che le chiamate di funzione sono delle sorte di cicli fatti a ritroso...
  • Re: Ricorsione Fibonacci in C

    Il modo ideale è rappresentarla come un albero ricorsivo. Ho postato uno schema per facilitare la comprensione della chiamata a fibonacci(4). Le scritte in blu sono i risultati. I calcoli vanno fatti a partire dal basso, cioè l'ultima chiamata che restituisce un risultato alla chiamata sovrastante.
    Allegati:
    24079_13d18b696288c21a584c5531e2e2d19c.png
    24079_13d18b696288c21a584c5531e2e2d19c.png
  • Re: Ricorsione Fibonacci in C

    Aggiungo che se vuoi fare i calcoli senza diagramma, bisogna prima impostare:
    F(0) = 0
    F(1) = 1
    --------
    F(4) = F(3) + F(2)
    F(3) = F(2) + F(1)
    F(2) = F(1) + F(0)

    Conoscendo le prime 2 condizioni (che corrispondono a quella di fine ricorsione), puoi calcolare tutti gli altri per sostituzione.
  • Re: Ricorsione Fibonacci in C

    Alexv ha scritto:


    Il modo ideale è rappresentarla come un albero ricorsivo. Ho postato uno schema per facilitare la comprensione della chiamata a fibonacci(4). Le scritte in blu sono i risultati. I calcoli vanno fatti a partire dal basso, cioè l'ultima chiamata che restituisce un risultato alla chiamata sovrastante.
    è uno schema molto interessante è soprattutto chiaro. Però ti faccio un'altra domanda: c'è la possibilità di avere uno schema leggermente diverso dove i calcoli partono dall' alto?
  • Re: Ricorsione Fibonacci in C

    Non ti basta che ti abbia fatto lo schema di tutte le chiamate?
  • Re: Ricorsione Fibonacci in C

    Volevi sapere come funziona la ricorsione? Fisicamente i calcoli vengono eseguiti a partire dall'ultima chiamata. Poi se vuoi leggerlo dall'alto, ruotalo e cambia il verso delle frecce. Il risultato è lo stesso ma ne cambierebbe in significato.
  • Re: Ricorsione Fibonacci in C

    Si si, l' ho capito, lo schema mi basta per avere capito.
    la mia era solo una domanda riflessiva dal momento che andando su wikipedia ho trovato una marea di varianti sui calcoli di Fibonacci e allora ho pensato - " non è che il codice sì può calcolare anche dall'alto verso il basso andando a ritroso?"
  • Re: Ricorsione Fibonacci in C

    Deimos84 ha scritto:


    Si si, l' ho capito, lo schema mi basta per avere capito.
    la mia era solo una domanda riflessiva dal momento che andando su wikipedia ho trovato una marea di varianti sui calcoli di Fibonacci e allora ho pensato - " non è che il codice sì può calcolare anche dall'alto verso il basso andando a ritroso?"
    Certo, facendone una versione non ricorsiva. Quell'algoritmo viene usato come esempio di ricorsione, o dai matematici per definire la funzione di Fibonacci, ma è spazialmente inefficiente da computare. Ogni chiamata occupa spazio nell'area stack della memoria... ed ognuna di esse ne produce altre due! Immagina quanti rettangoli mi sarebbero serviti per fare f(13).
  • Re: Ricorsione Fibonacci in C

    Deimos84 ha scritto:


    la mia era solo una domanda riflessiva ...
    Domanda riflessiva? Ma che vuol dire?

    Se vuoi imparare un po' di informatica (e di programmazione in particolare) non devi andare "a caso".

    Stai parlando di funzione "ricorsiva", il punto non è Fibonacci (che si calcola in tanti modi) ma la "ricorsione". E' quello il punto centrale su cui ti devi concentrare. La ricorsione, non il calcolo di Fibonacci.
  • Re: Ricorsione Fibonacci in C

    Alexv ha scritto:


    Deimos84 ha scritto:


    Si si, l' ho capito, lo schema mi basta per avere capito.
    la mia era solo una domanda riflessiva dal momento che andando su wikipedia ho trovato una marea di varianti sui calcoli di Fibonacci e allora ho pensato - " non è che il codice sì può calcolare anche dall'alto verso il basso andando a ritroso?"
    Certo, facendone una versione non ricorsiva. Quell'algoritmo viene usato come esempio di ricorsione, o dai matematici per definire la funzione di Fibonacci, ma è spazialmente inefficiente da computare. Ogni chiamata occupa spazio nell'area stack della memoria... ed ognuna di esse ne produce altre due! Immagina quanti rettangoli mi sarebbero serviti per fare f(13).
    si, in effetti è parecchio macchinoso e dispendioso a livello computazionale.
    infatti la sola ricorsione che fa il compilatore con il codice da me postato è un calcolo complesso e lungo nonostante sia scritto in poche righe
  • Re: Ricorsione Fibonacci in C

    Però come ha detto Oregon la ricorsione ha una sua importanza e non la si può evitare sempre solo perché difficile da capire (all'inizio).

    Non fare confusione, non è il compilatore che fa il lavoraccio. Il compilatore (a meno di ottimizzazioni di sua iniziativa), si limita a mettere quelle 4 - 5 istruzioni del codice. È l'esecuzione la parte costosa.
  • Re: Ricorsione Fibonacci in C

    Alexv ha scritto:


    Però come ha detto Oregon la ricorsione ha una sua importanza e non la si può evitare sempre solo perché difficile da capire (all'inizio).

    Non fare confusione, non è il compilatore che fa il lavoraccio. Il compilatore (a meno di ottimizzazioni di sua iniziativa), si limita a mettere quelle 4 - 5 istruzioni del codice. È l'esecuzione la parte costosa.
    forse non mi sono spiegato bene, io non sto assolutamente evitando l' importanza della ricorsione, al contrario, sono qui per capirla al meglio possibile. Con lo schema che mi è stato presentato ho azzerato praticamente tutti i dubbi che avevo aggiungendo però una mia riflessione personale sulla possibilità che l'esecuzione della ricorsione potesse essere svolta anche in maniera opposta ma con risultato identico. Ora mi pare di capire che questo non è possibile.

    P.S.:la parte costosa dell' esecuzione da "cosa" viene eseguita? dal pre-processore? (ho un lapsus)
  • Re: Ricorsione Fibonacci in C

    La ricorsione è un metodo che non utilizzi come vuoi (in maniera diretta o opposta). Non ha senso dire una cosa del genere.

    Ti ho già detto (ma sembra che non mi leggi) che devi avere molto chiaro il metodo con cui sono eseguite le chiamate delle funzioni, come vengono passati gli argomenti nello stack, come viene restituito il valore e il controllo alla funzione chiamante.
    Compresi bene questi concetti, comincerai a capire la ricorsione e a capire che non ci sono "modi" diversi di usarla.

    La parte costosa è nell'occupazione dello stack (che devi sapere cosa sia) e nel tempo impiegato per allocare/deallocare argomenti e variabili locali. Il preprocessore non c'entra nulla (e neanche i lapsus).
Devi accedere o registrarti per scrivere nel forum
19 risposte