ricorro a voi non riesco a ricorrermi da me (ricorsione maledetta ricorsione)

allora, il pischello ha una mente contorta, buona per fare programmi molto ermetici
ma ho scoperto che non conosce le basi della programmazione
meglio, dico io, frequenterò molto mamma casa sua
e gli ho mostrato la differenza tra ricorsione e iterazione
con il classico esempio del fattoriale
poi gli ho detto:
occhio che la ricorsione usa molta ram, arduino ti molla
vedere, dice lui
visto dico io (abbiamo lo spirito da giocatori di poker)
fatto programma e esempliato iterazione

// di Nelson "StandardOil"
// Idea da sviluppare: ricorsione
#include "MemoryFree.h"

void setup(void)
{
    Serial.begin(9600);
    Serial.println("Calcolo del fattoriale, versione iterativa");

    for (byte i = 1; i < 10; i++)
    {
        Serial.print(i); 
        Serial.print(" "); 
        Serial.println(fattorialei(i));
    }
}

void loop(void)
{
}


unsigned long int fattoriale(int numero)
{
    Serial.println(freeMemory());

    if (numero == 1)
    {
        return (1);
    }
    else
    {
        return numero * fattoriale(numero - 1);
    }
}



unsigned long fattorialei(int numero)
{
  Serial.println(freeMemory());
    unsigned long risultato = 1;

    for (byte i = 2; i < numero + 1; i++)
    {
        risultato = risultato * (i);
    }

    return risultato;
}

risultato:

2 1806
2
3 1806
6
4 1806
24
5 1806
120
6 1806
720
7 1806
5040
8 1806
40320
9 1806
362880

bene, dico io, come vedi usa sempre la stessa quantità di memoria
adesso vediamo con la ricorsione, vedrai che ne usa di più e ad ogni ciclo sempre di più

// di Nelson "StandardOil"
// Idea da sviluppare: ricorsione
#include "MemoryFree.h"

void setup(void)
{
    Serial.begin(9600);
    Serial.println("Calcolo del fattoriale, versione ricorsiva");

    for (byte i = 1; i < 10; i++)
    {
        Serial.print(i); 
        Serial.print(" "); 
        Serial.println(fattoriale(i));
    }
}

void loop(void)
{
}


unsigned long int fattoriale(int numero)
{
    Serial.println(freeMemory());

    if (numero == 1)
    {
        return (1);
    }
    else
    {
        return numero * fattoriale(numero - 1);
    }
}



unsigned long fattorialei(int numero)
{
  Serial.println(freeMemory());
    unsigned long risultato = 1;

    for (byte i = 2; i < numero + 1; i++)
    {
        risultato = risultato * (i);
    }

    return risultato;
}

risultato:

Calcolo del fattoriale, versione ricorsiva
1 1802
1
2 1802
1802
2
3 1802
1802
1802
6
4 1802
1802
1802
1802
24
5 1802
1802
1802
1802
1802
120
6 1802
1802
1802
1802
1802
1802
720
7 1802
1802
1802
1802
1802
1802
1802
5040
8 1802
1802
1802
1802
1802
1802
1802
1802
40320
9 1802
1802
1802
1802
1802
1802
1802
1802
1802
362880

ecco, a parte che ne consuma un pochino di più, 4 byte
e che tante stampe implica tante chiamate ricorsive alla funzione
come faccio a uscire dall'impasse e recuperare la figura di palta che ho fatto col pischello?

È possibile che freeMemory non tenga conto dello stack?


PS: fortuna che ti sei fermato a 9!, con 10 avresti visto la svista :slight_smile:

Claudio_FF:

PS: fortuna che ti sei fermato a 9!, con 10 avresti visto la svista :slight_smile:

grastopesante cerebrolento
che svista?

Credo appunto che freeMemory ritorni la dimensione dello heap libero, mentre la ricorsione consuma lo stack. Dovresti mostrare che lo stack pointer (SPL/SPH) decresce ad ogni chiamata.

vediamo se il derebro ha ripreso giri....
faccio una malloc() per avere il puntatore
castro il puntatore a intero
con una free libero l'area, che tanto mi serviva solo per avere un puntatore
aggiungo all'intero la dimensione allocata
e ho un intero che indica (non è strettamente parlando un puntatore) la prima cella libera dello stack?
così funziona?

Ma perché mai? Accedi direttamente ai registri che ho citato sopra.

e secondo te ne sarei capce?
grazie del complimento, ma immeritato

word x = (SPH << 8) | SPL;

Potrebbe funzionare :D.