You are on page 1of 32

INFORMATICA

Strutture iterative

Strutture iterative
Si dice ciclo (loop) una sequenza di istruzioni che
deve essere ripetuta pi volte consecutivamente.
Si consideri ad esempio il calcolo del fattoriale di
un numero n > 0:

n! = n . (n - 1) . (n - 2)........ 2
con il caso particolare 0! = 1.
Sembrerebbe che basti una semplice
assegnazione, ma se non si conosce a priori il
valore di n, impossibile scrivere listruzione che
esegue il calcolo del fattoriale, poich la formula
contiene tanti fattori quanti ne indica n.
Piero Demichelis

Strutture iterative
Proviamo a riscrivere la formula del fattoriale
come:

.....
n! =((

. .
.
.....
.
(((1 2) 3) 4)
(n - 1) n)

Osservando la formula possiamo:

attribuire ad una variabile fatt il valore 1,


quindi moltiplicare fatt per 2 ed attribuire il risultato ancora ad
fatt,
poi fatt per 3 e cos via fino a n.
Piero Demichelis

Strutture iterative
L'algoritmo di soluzione pu quindi essere
formalizzato mediante un algoritmo iterativo:
assegna il valore 1 a fatt;
se n vale 0, hai finito;
con k che varia da 1 a n con passo unitario esegui:
moltiplica fatt per k ed attribuisci il risultato a fatt.

Il prodotto fatt. k viene eseguito n volte com


necessario.
La scelta di algoritmi ciclici influenza spesso altri
componenti del programma, come la base dati.
Piero Demichelis

Strutture iterative
Nel linguaggio C i cicli iterativi sono realizzati da
tre costrutti:
while

: realizza il costrutto WHILE - DO;

do while : realizza il costrutto REPEAT - UNTIL;


for

: realizza il ciclo a contatore.

Piero Demichelis

Istruzione while
Sintassi:
while (<condizione>)
<istruzione>

<condizione>

Finch <condizione>
vera esegue <istruzione>
che pu essere semplice
o composta.
Piero Demichelis

V
<istruzione>

F
O

Istruzione while : osservazioni


Il costrutto while realizza il costrutto while do della
programmazione strutturata.
<condizione> deve essere di tipo logico ed ricalcolata ad
ogni iterazione;
se <condizione> risulta falsa gi alla prima iterazione
<istruzione> non viene eseguita neppure una volta;
se <condizione> non diventa mai falsa non si esce mai dal
loop!
essendo <istruzione> una normale istruzione composta pu
contenere qualsiasi tipo di istruzione, in particolare altri
while, dando origine (come per lif) a while annidati.
Piero Demichelis

Istruzione while: esempio


Leggere un numero intero N da tastiera, e
calcolare la somma S dei primi N numeri interi.
Pseudocodice:
Legge N da tastiera;
inizializza laccumulatore di risultato S a 0;
inizializza un contatore indice a 1;
finch indice <= N;
aggiungi allaccumulatore S il valore di indice;
aggiorna indice (ovvero incrementalo di 1);
visualizza il risultato finale (valore di S).

Piero Demichelis

Istruzione while: esempio


#include <stdio.h>
main()
{
int N, indice, S;
printf (\nIntroduci N: );
scanf (%d, &N);
S = 0;
/* inizializzazioni */
indice = 1;
while (indice <= N)
{
S += indice;
/* S
S + indice: operazione iterativa */
indice++;
/* aggiornamento condizione */
}
printf (\nSomma = %d, S);
/* output */
}

Piero Demichelis

Esempio: calcolo del seno


Calcolare la funzione seno x mediante lo sviluppo in
serie
3
5
7

x
x
x
sin x x

L
3! 5! 7!

sino quando i fattori sono > 0.00005.


Osservando i singoli fattori dello sviluppo si pu
osservare che:

x x
fatt fatt . prec.
N 1 N 2

con N che varia a passi di 2.


Piero Demichelis

Esempio: calcolo del seno


Il primo termine lo conosciamo allatto della lettura da
tastiera del valore in radianti dellangolo.
Tutti gli altri termini possono essere ricavati in successione a
partire dal primo applicando la relazione che abbiamo
trovato che lega un termine al successivo.
Diagramma di flusso

Start

Legge il valore dellangolo x

1
Piero Demichelis

Esempio: calcolo del seno


1
Inizializzazioni:
n
1
termine
senx
termass
x|
termass > soglia ?

x
x
|
Falso

Vero
Calcola nuovo termine e lo
somma a senx.
n
n+2
termass
|
termine|

Piero Demichelis

Visualizza senx
Visualizza sin(x)
Stop

Esempio: calcolo del seno


#include <stdio.h>
#include <math.h>
const double soglia = 0.00005;
main()
{
double x, senx, termine, termass, n;
printf ("Angolo in radianti: ");
scanf ("%lf ", &x);
n = 1;
termine = x;
senx = x;
if (x < 0)
Inizializzazioni
termass = - x;
else
termass = x;
Piero Demichelis

Esempio: calcolo del seno


/*
Ad ogni ciclo calcola un nuovo contributo
*/
while (termass > soglia)
{
termine = - termine * (x * x) / ((n+1) * (n+2)); /* nuovo termine */
senx += termine;
/* accumula in senx */
n += 2;
/* aggiorna n */
if (termine < 0)
/* aggiorna il valore assoluto di termine */
termass = -termine;
else
termass = termine;
}
printf ("\nIl seno di %lf e' %lf\n", x, senx);
printf ("\nValore fornito dalla funzione di libreria: %lf\n", sin(x));
}

Piero Demichelis

Istruzione for
In altri linguaggi il costrutto for permette di eseguire
una istruzione, semplice o composta, per un numero
prefissato di volte (ciclo a contatore).
Nel linguaggio C pi generale, al punto da poter
essere assimilata ad una particolare riscrittura del
costrutto while.
Sintassi:

for (<inizializzazione>; <condizione>;


<aggiornamento>)
<istruzione>;
Piero Demichelis

Istruzione for
<condizione> un'espressione logica;
<inizializzazione> e <aggiornamento> sono
invece espressioni di tipo qualsiasi.
L'istruzione for opera secondo il seguente
algoritmo:

viene calcolata <inizializzazione> ;


finch <condizione> vera (valore non nullo) ;
viene eseguita <istruzione>;
viene calcolato <aggiornamento>.
Piero Demichelis

Istruzione for
Diagramma di flusso:

I
Calcola lespressione
<inizializzazione>

<condizione>

F
O

V
<istruzione>
Calcola lespressione
<aggiornamento>

Piero Demichelis

Istruzione for
Di fatto il costrutto for del tutto equivalente al
seguente frammento di programma:
<inizializzazione>
while (<condizione>)
{
<istruzione>
<aggiornamento>
}

Poich non vi sono restrizioni sulla <istruzione>


da eseguire nel corpo del ciclo, questa pu
contenere a sua volta istruzioni for (for annidati ),
o altri costrutti di controllo (if, while, switch, ecc.).
Piero Demichelis

Istruzione for
Problema: leggere da tastiera un valore intero N e un
carattere carat, e visualizzare una riga di N caratteri carat
esempio: N = 10, carat = *

output

**********

soluzione iterativa: ripeti N volte loperazione stampa carat

Programma:
#include <stdio.h>
main() {
int N, indice;
char carat;
printf ("\nIntroduci un carattere e un intero: ");
scanf ("%c%d", &carat, &N);
for (indice=0; indice<N; indice++)
printf ("%c", carat);
/*senza
\n !!!!*/
printf ("\n");
Piero Demichelis
}

Istruzione for: esercizio


Leggere da tastiera un numero intero N;
successivamente leggere da tastiera N numeri interi, e
calcolarne la media.

Inoltre si controlli che ogni numero inserito sia


compreso tra 0 e 30; in caso contrario, il numero deve
essere ignorato.
Al termine visualizzare la media dei soli valori validi.
Analisi:
Problema iterativo: si devono leggere N numeri da tastiera.
Calcolo della media e controllo di ogni valore inserito (tra 0 e
30).
Piero Demichelis

Istruzione for: soluzione


Pseudocodice:
Legge N da tastiera;
Inizializza a 0 il totale (totale) ;
Inizializza a 0 un contatore per i validi (cont_validi);
Con un indice ind che va da 1 a N:
legge un valore num da tastiera;
Se num < 0 oppure > 30
segnala che non un valore valido e lo
trascura,
altrimenti :
accumula num nel totale;
incrementa di 1 cont_validi;
Calcola la media (totale / cont_validi).
Piero Demichelis

Istruzione for: soluzione


#include <stdio.h>
#include <conio.h>
main()
{
int num, ind, N, totale, cont_validi;
clrscr();
totale = 0;
cont_validi = 0;
printf ("\nIntroduci N: ");
scanf ("%d", &N);
Piero Demichelis

Istruzione for: soluzione


for (ind = 1; ind <= N; ind++)
{
/* per ogni valore introdotto */
printf ("\nIntroduci il valore di indice %d: ", ind);
scanf ("%d", &num);
if (num < 0 || num > 30)
/* controllo validit
*/
printf ("\nValore non valido");
else
{
totale += num;
/* accumula num nel totale */
cont_validi++;
}
}
printf ("\nLa media : %f\n", (float)totale/(float)cont_validi);
}

Piero Demichelis

Esercizio: generazione di un triangolo


Realizzare un programma in grado di generare un
triangolo di "*" sul video, le cui dimensioni
(numero di righe su cui si sviluppa il triangolo)
siano fornite da tastiera.

*
* *
* * *
* * * *

*
*
*
*
*

*
*
*
*
*
*

*
*
*
*
*

*
* *
* * *
* * * *

Poich il video composto da 80 colonne, sia 80 la


dimensione massima.
Piero Demichelis

Generazione di un triangolo: soluzione


Una possibile organizzazione del programma
potrebbe essere costituito dalla seguente
struttura:
controlla se il numero di colonne (calcolato in
base al numero di righe) < di 80;
se nrighe il numero di righe da stampare, per
nrighe volte esegui:
- scrivi un certo numero di spazi;
- scrivi un certo numero di "*".

Piero Demichelis

Generazione di un triangolo: soluzione


Per la relazione tra il numero di spazi ed il numero di '*' si
consideri la figura:
1a
2a
3a
na

riga
riga
riga
riga

*
* * *
* * * * *
* * * * * * *

N o spazi - nell'ultima riga se ne devono stampare 0, nella


penultima 1, nella terzultima 2, ecc.: in una generica riga
rigacorr saranno: nrighe - rigacorr;
N o asterischi - nella prima riga se ne deve stampare 1, nella
seconda 3, nella terza 5, ecc.: nella generica riga rigacorr
saranno: (rigacorr*2) - 1.
Piero Demichelis

Generazione di un triangolo: soluzione


#include <stdio.h>
main()
{
int nrighe, ncolon, rigacorr, coloncorr;
printf ("\nNumero righe del triangolo: ");
scanf ("%d", &nrighe);
printf ("\n\n\n");
ncolon = nrighe * 2 - 1;
/* calcola il numero di colonne
*/
if (ncolon >= 80)
printf ("\nErrore: troppe colonne!");
else
{
Piero Demichelis

Generazione di un triangolo: soluzione


for (rigacorr = 1; rigacorr <= nrighe; rigacorr++)
{
for (coloncorr = 1; coloncorr <= (nrighe - rigacorr);
coloncorr++)
spazi */

printf (" ");

/* output degli

for (coloncorr = 1; coloncorr <= (rigacorr*2)-1; coloncorr+

+)

asterischi */

printf ("*");

printf ("\n");
riga! */

/* output degli
/* output di new line: finita una

}
}

Piero Demichelis

Istruzione do ... while


Sintassi:
do
<istruzione>
while (<condizione>)

I
<istruzione>

Ripeti <istruzione>,
che pu essere semplice
o composta,
finch <condizione>
vera.
Piero Demichelis

<condizione>

Istruzione do ... while: osservazioni


Listruzione do ... while realizza il costrutto repeat - until della
programmazione strutturata.
<condizione> deve essere di tipo logico ed calcolata ad ogni
iterazione;
<istruzione> pertanto sempre eseguita almeno una volta
(anche se <condizione> subito falsa);
se <condizione> non diventa mai falsa non si esce mai dal loop!
come per gli altri costrutti<istruzione> una normale istruzione
composta e pu contenere qualsiasi tipo di istruzione o
costrutto (altri while, if, switch, ecc.), dando origine a strutture
annidate.
Piero Demichelis

Istruzione do ... while: esempio


Calcolare il valore della serie armonica:

1 1
1
y n 1 L
2 3
n
terminando il calcolo quando un fattore
contribuisce per meno di 0.00005.

La serie armonica si trova in numerose


applicazioni quale, ad esempio, il calcolo degli
interessi composti.

Piero Demichelis

Istruzione do ... while: esempio


#include <stdio.h>
const double soglia = 0.00005;
main()
{
double y, termine;
int n;
y = 0.0;
n = 1;
do
{
termine = 1.0 / n;
y += termine;
n++;
}
while (termine > soglia);
printf ("\nIl valore (trovato per n= %d) : %lf ", (n-1), y);
}
Piero Demichelis