Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per...

44
Iterazione enumerativa (for). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia noto a priori il numero di ripetizioni da eseguire (iterazione enumerativa). for esamina il valore di una espressione di controllo o condizione, e se la trova diversa da zero (o “vera”) esegue una o più istruzioni, altrimenti esce dal ciclo. Dopo ogni esecuzione delle istruzioni del ciclo, ne viene eseguita una che modifica il valore dell’espressione, che viene quindi controllata di nuovo. Se ha ancora valore diverso da zero il ciclo ricomincia. Le istruzioni vengono eseguite un numero prefissato di volte, dopo di che si ha l’uscita dal ciclo. Il diagramma di flusso è indicato in figura.

Transcript of Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per...

Page 1: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Iterazione enumerativa (for). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia noto a priori il numero di ripetizioni da eseguire (iterazione enumerativa).

for esamina il valore di una espressione di controllo o condizione, e se la trova diversa da zero (o “vera”) esegue una o più istruzioni, altrimenti esce dal ciclo.

Dopo ogni esecuzione delle istruzioni del ciclo, ne viene eseguita una che modifica il valore dell’espressione, che viene quindi controllata di nuovo.

Se ha ancora valore diverso da zero il ciclo ricomincia.

Le istruzioni vengono eseguite un numero prefissato di volte, dopo di che si ha l’uscita dal ciclo.

Il diagramma di flusso è indicato in figura.

Page 2: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.
Page 3: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Ad esempio, per azzerare le componenti di un vettore a[k] di 100 componenti, si possono scrivere le istruzioni seguenti:

for (k = 1; k <= 100; k = k + 1) a[k] = 0;

dove la parentesi che segue for contiene, nell’ordine,

• l’inizializzazione della variabile di controllo (k);• la condizione che, se risulta vera, determina la ripetizione del ciclo;• l’istruzione che fa variare la variabile di controllo.

Inizialmente l’istruzione for imposta il contatore k a 1, e dato che questo valore rende vera (cioè diversa da zero) l’espressione di controllo (k <= 100), viene eseguita l’(unica) istruzione, che azzera il valore della componente a[1].

Page 4: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Quindi for incrementa di 1 il valore di k, e risultando k = 2 (e quindi ancora k <= 100), viene ripetuta l’istruzione. Viene così azzerato il valore di a[2], e così via.

Dopo che è stato azzerato il valore di a[100], risulta k = 101, il che determina l’uscita dal ciclo e l’esecuzione della istruzione successiva (se presente).

Il valore finale del contatore può essere:

• maggiore di quello iniziale, come in questo esempio, oppure minore; in tale caso la variabile contatore va decrementata a ogni passo di iterazione;

• una costante oppure una variabile (alla quale sia stato naturalmente assegnato in precedenza un valore).

Page 5: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Esempio: Somma dei primi n numeri naturali. Le pseudo istruzioni sono le seguenti:

Il corrispondente diagramma di flusso è indicato in figura.

leggi n;somma = 0;for (i=1; i<=n; i=i+1) somma = somma + i;

Page 6: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Osserviamo che l’algoritmo qui impiegato non è molto efficiente, dato che la somma dei primi n numeri naturali è fornita direttamente dalla formula di Gauss

n*(n+1)/2

ma l’esempio è solo indicativo del funzionamento di molti dei cicli che si incontrano in pratica.

Page 7: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Iterazione con guardia all’inizio (while). Nel caso invece in cui non sia noto a priori o non si voglia indicare il numero di ripetizioni da eseguire (iterazione non enumerativa), il linguaggio C mette a disposizione i due costrutti while e do-while, il primo con guardia all’inizio (come for), il secondo con guardia alla fine.

Il costrutto while inizia esaminando il valore di una espressione di controllo o condizione.

Se essa è diversa da zero (ossia è vera) le istruzioni del ciclo vengono eseguite, altrimenti si ha l’uscita dal ciclo.

Dopo le istruzioni del ciclo ne viene eseguita una che altera il valore dell’espressione di controllo, e quando questa risulta uguale a zero si ha l’uscita del ciclo.

Page 8: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

while realizza il diagramma di flusso già visto

Se il ciclo è costituito da più istruzioni, esse vanno racchiuse tra parentesi graffe, { }, secondo lo schema seguente:

while (condizione) { istruzione_1 ; ......... ; istruzione_n ; }

Page 9: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Esempio: Massimo Comun Divisore (2). Come esempio di iterazione non enumerativa con guardia all’inizio, si consideri il seguente algoritmo, derivato anch’esso dal metodo di Euclide per trovare il Massimo Comun Divisore (MCD) di due interi positivi.

Per trovare il MCD di due interi positivi:

• si sottrae il minore dal maggiore

• se la differenza è uguale al minore, essa rappresenta il MCD cercato

• altrimenti la differenza trovata sostituisce il maggiore dei due numeri, e il procedimento ricomincia da capo.

Page 10: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Ecco le relative pseudo istruzioni

leggi X, Y;fino a che (X!=Y){ se (X > Y) X=X-Y; altrimenti Y=Y-X;}stampa X;fine

e il corrispondente diagramma di flusso.

Page 11: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Esempio: Stampa numero massimo. Come altro esempio di iterazione non enumerativa con guardia all’inizio, si può considerare il problema di:

trovare il massimo di un elenco di numeri immessi da tastiera.

In questo caso non conviene usare una iterazione enumerativa perché potrebbe non essere noto a priori il numero di numeri che si immetteranno (e quindi il numero di iterazioni da eseguire).

Conviene invece terminare l’elenco dei numeri con uno, detto sentinella, che sicuramente non si presenterà nell’elenco, e ogni volta che si legge un numero immesso controllare se esso sia diverso dalla sentinella.

In caso affermativo il programma prosegue, in caso negativo termina.

Chiamiamo:

•dato la variabile nella quale sono copiati i valori di volta in volta letti

•max la variabile in cui viene copiato il valore di dato se risulta dato>max

e poniamo la sentinella =0.

Page 12: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

L’espressione dell’algoritmo in pseudo istruzioni è la seguente:

poni max = 0;leggi dato; while (dato!=0) { if dato > max max = dato; leggi dato; }stampa max;

Il diagramma di flusso è indicato in figura.

Page 13: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Esempio: Calcolo del fattoriale (1). Molte volte i cicli for e while sono intercambiabili.

Si consideri, ad esempio, il fattoriale, n!, di un numero intero n, definito come il prodotto degli interi 1 * 2 * 3 * ... * n (definizione iterativa).

Quindi:

1! = 12! = 1 * 2 = 2...5! = 1 * 2 * 3 * 4 * 5 = 120

Questa definizione può dare luogo (per n 1) al semplice diagramma di flusso seguente:

Page 14: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.
Page 15: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

fatt = 1;i = 0;while (i < n) { i = i + 1; fatt = fatt * i;}

fatt = 1;for (i = 1; i <= n; ++i) fatt = fatt * i;

Vedremo più avanti un approccio del tutto diverso per calcolare il fattoriale.

Esso può essere realizzato dal ciclo while seguente:

oppure dal ciclo for seguente:

Page 16: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Iterazione con guardia alla fine (do-while). Il ciclo do-while inizia con la parola do, seguita dalla o dalle istruzioni da eseguire, e termina con la parola while seguita dalla condizione che deve essere verificata per la ripetizione del ciclo.

Esso realizza il diagramma di flusso già visto

Page 17: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

p = 0;k = a;do{ p = p + b; k = k - 1;}while (k == 0);

Naturalmente il costrutto do-while consente di eseguire anche un ciclo nel quale sia noto a priori il numero di ripetizioni, cioè una iterazione enumerativa.

Si consideri il seguente esempio.

Esempio: moltiplicazione tramite addizioni ripetute. Come primo esempio di ciclo do-while, consideriamo le pseudo istruzioni che traducono l’algoritmo della moltiplicazione tramite addizioni ripetute.

Page 18: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Esempio: Somma di 5 numeri. Per scrivere un algoritmo che legga 5 numeri e ne stampi la somma usiamo le seguenti variabili:

• S per contenere la somma

• K per contare il numero dei valori letti (ossia quante volte è stato eseguito il ciclo),

• X per indicare il numero di volta in volta letto.

Page 19: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Ecco il corrispondente diagramma di flusso

poni S = 0;poni K = 0;do{ leggi X; poni K = K+1; poni S = S+X;}while (K != 5);stampa S;

Le pseudo istruzioni sono le seguenti:

Page 20: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

La traduzione di queste istruzioni in un programma C è immediata, come vedremo più avanti.

Esercizio. Una leggera modifica dei questo diagramma di flusso, ponendo la guardia all’inizio, consente di risolvere il seguente problema:

scrivere un algoritmo che legga 5 numeri estampi la somma di quelli maggiori di 100

come indica la figura seguente.

Page 21: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.
Page 22: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

2

11

0

2

xx

x

x

20

1

xx

Se in questa formula si sostituisce a x1 il valore trovato di x2, si ottiene x3

Da x1 si calcola il valore di seconda approssimazione, x2, con la formula

2

22

0

3

xx

x

x

Calcolo della radice quadrata. Il calcolo della radice quadrata di un numero x0 può essere eseguito con il metodo delle approssimazioni successive. Questo consiste nel calcolare dapprima il valore di prima approssimazione, x1, con la formula

Page 23: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

e così di seguito.

Il calcolo termina quando si è calcolato un valore che differisca dal precedente meno di un numero scelto piccolo a piacere (eps).

Supponiamo, per esempio, di volere calcolare la radice quadrata di x0 = 16. Avremmo:

x1 = 16/2 = 8x2 = (16/8 + 8)/2 = 5x3 = (16/5 + 5)/2 = 4,1x4 = (16/4,1 + 4,1)/2 = 4,0012195121x5 = (16/4,0012195 + 4,0012195)/2 = 4,0000001858

Page 24: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

leggi x0, eps;x2 = x0/2;do{ x1 = x2;

x2=(x0/x1+x1)/2; d = x1 - x2;}while (d > eps)stampa x2;

e quindi nel diagramma di flusso indicato a lato

L’algoritmo si traduce nelle seguenti pseudo istruzioni:

Page 25: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Esercizio: stampa di numeri pari. Scrivere un algoritmo che stampi i numeri pari di un elenco.

L’algoritmo può essere il seguente:

Se indichiamo con:

- n il numero degli elementi dell’elenco

- x l’elemento via via letto

- r il resto della divisione per 2 di ogni elemento (pertanto r = 0 se l’elemento letto è pari)

- cont un contatore che memorizza il numero di elementi letti (ossia di ripetizioni del ciclo)

Si calcola il resto della divisione per 2 di ogni valore dell’elenco, e si stampano i soli valori per i quali tale resto sia 0.

Si ripete l’operazione per tutti i valori dell’elenco, supponendo noto il loro numero.

Page 26: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

leggi n;poni cont = 0;do leggi x; dividi x per 2 e chiama r il resto; se r == 0 stampa x; poni cont = cont+1;while cont != n

e quindi al diagramma di flusso indicato a lato

il precedente algoritmo corrisponde alle pseudo istruzioni seguenti:

Page 27: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Cicli nidificati. Anche i cicli do-while, come gli altri, si possono trovare l’uno dentro l’altro, cioè essere nidificati.

Vediamo, a questo proposito, un algoritmo che stampa la tavola pitagorica di dimensione n qualsiasi.

Ovviamente esso può essere realizzato sia con un ciclo do-while, sia con uno for.

Page 28: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.
Page 29: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Confronto tra do-while e while. Si considerino i seguenti segmenti di programmi:

Sebbene producano entrambi la stampa dei numeri 10, 9, 8, 7, 6, 5, dal punto di vista concettuale essi non sono equivalenti.

cont = 10; while (cont >= 5) { printf(“%d “, cont); -- cont; }

cont = 10; do { printf(“%d “, cont); -- cont; } while (cont >= 5);

Page 30: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Infatti nel ciclo do-while, nel quale la guardia è alla fine, le istruzioni contenute all’interno sono eseguite almeno una volta, mentre nel ciclo while, nel quale la guardia è all’inizio, le istruzioni potrebbero anche non essere eseguite mai.

Pertanto lo schema do-while non consente di rappresentare facilmente tutti i casi di iterazione che si possono incontrare in pratica, e quindi la scelta tra i due tipi di cicli va effettuata con attenzione.

Mostriamo ciò con il seguente esempio.

Page 31: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

L’algoritmo della divisione con sottrazioni ripetute, già visto

si traduce nel seguente ciclo while

quoz = 0;res = num;while (res >= den){ res = res - den; quoz = quoz + 1;}

Page 32: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

In questo algoritmo lo schema while esprime la ripetizione di una sequenza di due azioni, controllata dalla condizione res >= den, che specifica la condizione per rimanere dentro l’iterazione.

La condizione viene valutata prima di ogni esecuzione della sequenza e, se è falsa, la ripetizione termina (o non ha inizio, se si è all’inizio del processo).

Viceversa, se utilizzassimo il seguente ciclo do-while

quoz = 0;res = num;do{ res = res - den; quoz = quoz + 1;}while (res < den);

Page 33: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

scriveremmo una sequenza non corretta, in quanto fornisce un risultato errato se il dividendo è minore del divisore.

Ad esempio, se (num == 15) e (den == 20), otterremmoquoz = 1 e res = –5

(al posto dei valori corretti quoz = 0 e res = 20).

Affinché la sequenza sia corretta occorre che le istruzioni del ciclo non siano eseguite quando la condizione di ripetizione (res < den) si verifica prima dell’inizio dell’iterazione.

Osserviamo che ciascuna delle tre strutture, sequenza, selezione, iterazione, presenta un unico punto di entrata e un unico punto di uscita.

Ciò comporta che esse siano “componibili” sequenzialmente, ovvero che si possano collegare in successione.

Esse si possono anche nidificare l’una dentro l’altra, senza alcun limite.

Page 34: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Iterazione e ricorsività

La potenza dei calcolatori è dovuta alla loro capacità di eseguire in modo ripetitivo lo stesso compito o versioni diverse di esso.

Nell’informatica il concetto di iterazione s’incontra in molte forme, tra le quali i modelli dei dati dove molti concetti, come le liste, sono definiti in modo ripetitivo.

Per esempio:

una lista è vuota oppure è un elemento seguitoda un altro, seguito da un altro ancora e così via.

Alternativa all’iterazione è la ricorsività, una tecnica in cui un concetto viene definito, direttamente o indirettamente, in termini di se stesso.

Per esempio una lista si può definire anche come:

una lista è vuota oppure è un elemento seguito da una lista

Page 35: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.
Page 36: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

La ricorsività è prevista in molti linguaggi di programmazione tra i quali il C, che consente di definire funzioni ricorsive, che possono cioè invocare se stesse sia direttamente, all’interno del proprio corpo, sia indirettamente, invocando un’altra funzione che ne invoca un’altra, che a sua volta ne invoca un’altra ancora a così via, finché qualche funzione in questa sequenza invoca quella di partenza.

Spesso i programmatori alle prime armi si sentono più sicuri quando scrivono programmi iterativi piuttosto che programmi ricorsivi, ma è buona abitudine abituarsi a pensare e programmare in modo ricorsivo quando ciò risulti appropriato.

I programmi ricorsivi possono risultare più semplici da scrivere, analizzare e comprendere.

Page 37: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

La ricorsività trova il suo equivalente nel procedimento matematico della induzione, utilizzato per dimostrare la verità di un asserto.

In una dimostrazione induttiva si dimostra che un asserto S(n), funzione di una variabile n è vero, dimostrando dapprima una base, ovvero l’asserto S(n) per un valore particolare di n.

Per esempio si pone n = 0 e si dimostra l’asserto S(0).

Successivamente si prova un passo induttivo, nel quale si dimostra che l’asserto S, per un generico valore del suo argomento, deriva dalla verità dell’asserto medesimo per valori precedenti del suo argomento.

Nella forma più semplice di induzione, si dimostra che S(n) implica S(n+1)qualunque sia n 0.

Page 38: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Per esempio, S(n) potrebbe essere l’asserto:

la somma degli interi da 1 a n è uguale a n*(n+1)/2

cioè S(n) potrebbe essere la nota formula

n

i1

= n*(n+1)/2

La base sarebbe allora S(1), ovvero l’equazione precedente con 1 al posto di n, che si riduce semplicemente all’uguaglianza

1 = 1 * 2/2 .

Il passo induttivo consiste nel dimostrare che, supposta vera S(n) (cioè la formula precedente), risulta vera anche S(n+1), cioè l’equazione

1

1

n

i = (n+1)*(n+2)/2

Page 39: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Ora, che questa equazione sia vera è evidente, in quanto la formula

n

i1

= n*(n+1)/2

è valida per qualsiasi valore di n, quindi anche per n+1, valore che sostituito in essa fornisce appunto l’equazione

1

1

n

i = (n+1)*(n+2)/2

L’iterazione e la ricorsività sono due concetti fondamentali che compaiono in varie forme nei modelli dei dati, nelle strutture dati e negli algoritmi.

Vediamo alcuni esempi di utilizzo del secondo concetto, riscrivendo in modo ricorsivo la definizione di fattoriale, già vista nella sua versione iterativa.

Page 40: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Definizione ricorsiva di fattoriale. La funzione fattoriale si può definire in maniera ricorsiva come segue:

base: 1! = 1induzione: n! = n * (n – 1)!

Dato che la base ci dice che 1! = 1, possiamo utilizzare questo fatto nel passo induttivo con n = 2 per determinare 2!, scrivendo:

2! = 2 * 1! = 2 * 1 = 2.

Con n = 3, 4 e 5 otteniamo:

3! = 3 * 2! = 3 * 2 = 64! = 4 * 3! = 4 * 6 = 245! = 5 * 4! = 5 * 24 = 120

e così via.

Page 41: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Notiamo che, sebbene possa sembrare che il termine “fattoriale” sia definito in termini di se stesso, in pratica possiamo ottenere il valore di n!, per valori via via maggiori di n, nei termini del fattoriale di valori più piccoli di n.

Abbiamo dunque una definizione “sensata” di fattoriale.

La trascrizione di questa definizione ricorsiva di n! è costituita dal frammento di programma seguente:

if (n == 0) return(1);return(n * fatt(n - 1));

Page 42: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Per esempio, se effettuiamo la chiamata fatt(4), il risultato è una chiamata a fatt(3), che chiama fatt(2), che a sua volta chiama fatt(1).

A questo punto, fatt(1) applica la regola base, poiché n<=1, e restituisce il valore 1 a fatt(2).

La chiamata fatt(2) termina l’esecuzione della penultima linea, restituendo 2 a fatt(3).

A sua volta, fatt(3) restituisce 6 a fatt(4), che completa l’esecuzione della linea restituendo 24 come risposta.

Page 43: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

La figura mostra la struttura delle chiamate e dei risultati.

Page 44: Iterazione enumerativa ( for ). Il costrutto iterativo for fornisce il modo più semplice per eseguire ripetutamente una sequenza di operazioni quando sia.

Definizione ricorsiva di potenza. Anche la potenza può essere definita in modo ricorsivo. Consideriamo la funzione pot, che ha come argomenti

• un numero reale positivo, base, elevato a • un numero intero, esp.

Risulta che pot(base, esp) può essere definita in maniera ricorsiva come segue:

base: pot(base, 0) = 1induzione: pot(base, esp) = base * pot(base, esp-1).

Ciò dà luogo al seguente segmento di programma, che calcola la potenza in modo ricorsivo:

if (esp == 0) pot(base, esp) = 1else pot(base, esp) = base*pot(base, esp-1)