Corso di C con Linux

Strutture di controllo - Parte IV

 

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