next up previous contents index
Next: Costrutti ciclici: while e Up: Costrutti condizionali e iterativi Previous: La scelta condizionata   Indice   Indice analitico

Costrutti ciclici: for

In questo paragrafo e nel seguente introdurremo tre importanti costrutti, che possiamo indicare come cicli. Il primo di essi, oggetto del presente paragrafo, è il ciclo for, la cui sintassi è la seguente:
for (inizializzazione; condizione; incremento) statement
Questo costrutto permette di iterare una o più operazioni (in quest'ultimo caso lo statement deve consistere in un blocco, racchiuso da parentesi graffe) un numero di volte stabilito; l'iterazione avviene controllando (nella condizione) ciclo per ciclo la variabile di controllo, la quale viene inizializzata nella inizializzazione e incrementata nell'incremento. Vediamo il seguente esempio:


// ex3_3_1.cpp
#include <iostream.h>
void main() {
   for (int i = 0; i < 5; i++)
      cout << "ciao!";
}

output:
ciao!ciao!ciao!ciao!ciao!

Si noti bene che la variabile di controllo, che viene solitamente detta contatore (counter), può essere utilizzata liberamente all'interno del corpo del for, come nel seguente


// ex3_3_2.cpp
#include <iostream.h>
void main() {
   for (int i = 0; i < 5; i++)
      cout << i << "\t";
}

output:
 0 1 2 3 4

Il contatore può addirittura essere modificato, essendo una variabile esattamente come le altre; tuttavia si sconsiglia vivamente di utilizzare tale possibilità, per evitare di cadere in trappole come quelle dell'esempio successivo, che si invita a non eseguire:


// ex3_3_3.cpp
// ATTENZIONE: il programma NON termina
void main() {
   for (int i = 0; i < 5; i++)
      i--;
}

ad ogni ciclo il contatore i viene incrementato, per poi essere decrementato ogni volta all'interno del corpo del for, per cui la condizione i < 5 è sempre vera ed il ciclo continua all'infinito; abbiamo incontrato per la prima volta un infinite loop, cioè un ciclo senza fine (teorica), il quale è senza dubbio nocivo alla stabilità di qualunque programma.

Come si si può aspettare, l'incremento della variabile contatore è del tutto arbitrario; si considerino come esempio i seguenti programmi, del tutto equivalenti:


// ex3_3_4.cpp
// stampa la tabellina dell'11
#include <iostream.h>
void main() {
   for (int i = 11; i <= (11*11); i+=11)
      cout << i << "\n";
}


// ex3_3_5.cpp
// idem
#include <iostream.h>
void main() {
   for (int i = 1; i <= 11; i++) {
      int multiplo = 11 * i;
      cout << multiplo << "\n";
   }
}

output di entrambi:
11
22
$\vdots$
121

Abbiamo portato precedentemente come esempio un programma che calcoli la somma dei primi $n$ numeri interi; vediamo ora un programma ad esso equivalente, che non sfrutti la formula di Gauss:


// ex3_3_6.cpp
#include <iostream.h>
void main() {
   int n;
   cout << "n = "; cin >> n;
   int somma = 0;
   for ( ; n > 0; n--)
      somma += n;
   cout << "la somma dei numeri da 1 a "
      << n << " e' " << somma;
}

Si noti che non abbiamo volutamente creato nessuna variabile contatore, in quanto si è utilizzata la variabile n preesistente, il cui valore è fornito in ingresso dall'utente; in generale, tutti e tre gli argomenti del for sono opzionali:


// ex3_3_7.cpp
#include <iostream.h>
void main() {
   for (int i = 0; i < 5; ) {
      i++;
      cout << "ciao!";
   }
}

è del tutto equivalente all'esempio ex3_3_1.cpp. Come è ovvio, se manca il secondo argomento del for, cioè la condizione di terminazione del ciclo, esso è implicitamente infinito. Anche i cicli for, così come il costrutto if, possono essere annidati l'uno nell'altro:


// ex3_3_8.cpp
// scrive le tabelline dal 2 al 10
#include <iostream.h>
void main () {
   for (int i = 2; i <= 10; i++) {
      for (int j = 1; j <= 10; j++) {
         int n = i * j;
         cout << n << " - ";
      }               // chiude il for interno
      cout << "\n";
   }                  // chiude il for esterno
}

output:
2 - 4 - 6 - 8 - 10 - 12 - 14 - 16 - 18 - 20 -
3 - 6 - 9 - 12 - 15 - 18 - 21 - 24 - 27 - 30 -
4 - 8 - 12 - 16 - 20 - 24 - 28 - 32 - 36 - 40 -
5 - 10 - 15 - 20 - 25 - 30 - 35 - 40 - 45 - 50 -
6 - 12 - 18 - 24 - 30 - 36 - 42 - 48 - 54 - 60 -
7 - 14 - 21 - 28 - 35 - 42 - 49 - 56 - 63 - 70 -
8 - 16 - 24 - 32 - 40 - 48 - 56 - 64 - 72 - 80 -
9 - 18 - 27 - 36 - 45 - 54 - 63 - 72 - 81 - 90 -
10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100 -

In quest'ultimo esempio abbiamo utilizzato due contatori; vedremo in seguito che questo costrutto è tipico delle tabelle (o matrici).

ex-2
si scriva un programma che calcoli il fattoriale di un numero intero non negativo; si ricorda che il fattoriale di un numero è definito come segue:

\begin{displaymath}
n! = n \cdot (n - 1) \cdot (n - 2) \cdot \ldots \cdot 1
\end{displaymath}

nel caso si voglia provare poi il programma (CONSIGLIATO, come per tutti i programmi contenuti in questo corso) si inseriscano in ingresso dei numeri piccoli, per evitare l'overflow della macchina; infatti, il fattoriale di un numero relativamente piccolo come 60, è dell'ordine di $8 \cdot 10^{81}$.
ex-3
si scriva un programma che abbia il seguente output:
 16 8 4 2
 64 128 256 512
ex-4
Si cerchi di modificare il programma ex3_3_8.cpp in modo tale da non stampare l'ultimo trattino (-) a fine riga. Una possibile soluzione è la seguente:

// ex3_3_8bis.cpp
#include <iostream.h>
void main() {
   for (int i = 2; i <= 10; i++) {
      for (int j = 1; j <= 9; j++) {
         int n = i * j;
         cout << n << " - ";
      }
      cout << (j++ * i) << "\n";
   }
}


next up previous contents index
Next: Costrutti ciclici: while e Up: Costrutti condizionali e iterativi Previous: La scelta condizionata   Indice   Indice analitico
Claudio Cicconetti
2000-09-06