Esaminiamo adesso altre due strutture di controllo, partendo dal costrutto
do-while, che ha il seguente formato:
do {
istruzione_1;
istruzione_2;
...
istruzione_n;
} while (condizione);
Com'è immediato rilevare, questa istruzione è molto simile al
while, eccezion fatta per la posizione in cui viene eseguito
il test sulla condizione.
Infatti nel while la condizione viene verificata prima
di eseguire qualsiasi istruzione del ciclo, mentre il costrutto
do-while esegue la verifica della condizione dopo aver
eseguito una volta le istruzioni del ciclo.
Di conseguenza, in do-while il ciclo viene eseguito sempre
almeno una volta, anche se la condizione viene trovata subito
falsa.
Per sottolineare questa differenza fra i due costrutti, si esegua
il seguente programma:
/*
* File lez37_1.c
*/
#include <stdio.h>
int main()
{
while (2 < 1)
printf("Ciclo while\n");
do
printf("Ciclo do-while\n");
while (2 < 1);
return 0;
}
Poiché la condizione 2 < 1 non è mai vera, il ciclo while
termina senza eseguire la sua istruzione printf, mentre
il ciclo do-while esegue prima l'istruzione printf,
poi valuta l'espressione e quindi esce.
A parte questa caratteristica, le due strutture di controllo si
comportano esattamente allo stesso modo; anzi è raro trovare cicli
do-while nei programmi C, poiché sono veramente poche le
occasioni in cui si possa voler eseguire un ciclo almeno una volta
indipendentemente dal valore della sua condizione.
Si noti, nell'esempio, che non sono state utilizzate le parentesi
graffe per il corpo dell'istruzione do-while: ciò può essere
fatto quando il ciclo è costituito da una sola istruzione.
Per esercizio, riscrivere l'esempio “lez35_1.c”, utilizzando
il costrutto do-while.
Qualora l'esecuzione di una o più istruzioni debba avvenire un
numero definito di volte, si può utilizzare il costrutto for,
la cui forma è la seguente:
for (inizializzazione
contatore; condizione; aggiornamento contatore)
{
istruzione_1;
istruzione_2;
...
istruzione_n;
}
Questa istruzione, molto usata dalla maggior parte dei programmatori,
definisce tre parametri del ciclo:
1) l'inizializzazione di un contatore;
2) la valutazione di una condizione o di un'espressione;
3) l'aggiornamento del valore del contatore tramite un'espressione
opportuna;
ed è sostanzialmente equivalente ad un ciclo while del
tipo:
inizializzazione contatore;
while (condizione)
{
istruzione_1;
istruzione_2;
...
istruzione_n;
aggiornamento contatore;
}
In realtà, internamente il C tratta un ciclo for come
un ciclo while a tutti gli effetti.
Il primo e l'ultimo parametro non devono necessariamente inizializzare
e aggiornare il contatore: ognuno di essi può essere una qualsiasi
istruzione C o essere addirittura omesso.
Anche il secondo parametro può essere un'istruzione qualsiasi,
ma il compilatore lo interpreta sempre come una condizione da
verificare ed il suo risultato viene valutato come vero o falso
(si ricordi sempre che il C considera falso lo zero binario e
vero qualsiasi altro valore).
A tal proposito, è utile il seguente programma:
/*
* File lez37_2.c
*/
#include <stdio.h>
int main()
{
for (printf("Inizializzazione contatore\n");
printf("Valutazione condizione\n");
printf("Aggiornamento contatore\n"))
{
printf("Istruzioni del ciclo\n");
}
return 0;
}
Compilate il codice precedente con il comando:
cc -o lez37_2 lez37_2.c
ed eseguitelo con il comando:
./lez37_2 > lez37_2.txt
Sullo schermo non apparirà alcuna scritta, benché ci si aspetti
di vedere almeno qualcuno dei vari printf del nostro sorgente:
ciò è dovuto al simbolo '>' che segue il nome dell'eseguibile
e che indica al sistema operativo di non stampare l'output del
programma sul video ma di redirigerlo sul file “lex37_2.txt”
(se il file non esiste viene creato).
Premendo contemporaneamente i tasti [Ctrl] e [C], riapparirà il
prompt della shell, segno che l'esecuzione del programma è stata
interrotta.
A questo punto troverete nella directory dell'eseguibile il file
“lez37_2.txt”: apritelo con un editor di testo qualsiasi
e vedrete che esso contiene le seguenti righe (se il file è troppo
lungo, potete visualizzare solo le prime 10 righe tramite il comando
“head -n 10 lez37_2.txt”):
Inizializzazione contatore
Valutazione condizione
Istruzioni del ciclo
Aggiornamento contatore
Valutazione condizione
Istruzioni del ciclo
Aggiornamento contatore
Valutazione condizione
Istruzioni del ciclo
Aggiornamento contatore
...
Avete un pò di tempo per riflettere su questo risultato, che commenteremo
nella prossima lezione.
Torna all'indice Generale del corso di Corso di C con Linux di Software Planet