Corso di C con Linux

Strutture di controllo - Parte V

 

Abbiamo terminato la scorsa lezione con un risultato (apparentemente) strano, ottenuto dall'esecuzione dell'ultimo esempio, che mostra il funzionamento del ciclo for.
Infatti, tenendo presente che l'istruzione printf ritorna come valore il numero di caratteri scritti, risulta evidente che l'esecuzione dell'istruzione for avviene con questi passaggi:
1) Viene eseguita l'inizializzazione del ciclo (solo la prima volta);
2) Viene valutata l'espressione: se è vera (o restituisce un valore diverso da zero, come in questo caso), viene eseguito il corpo del ciclo;
3) Al termine del ciclo viene aggiornato il contatore;
4) Viene rivalutata l'espressione e se è vera il ciclo ricomincia.

Per esercizio, riscrivere l'esempio "lez35_1.c", utilizzando il costrutto for.

L'istruzione for può essere utilizzata in maniera più complessa, includendo più di un'espressione sia nel campo di inizializzazione che in quello di aggiornamento del contatore, separandole per mezzo di una virgola.
Analizziamo l'esempio che segue:

/*
 * File lez38_1.c
 */
#include <stdio.h>

int main() {
    int x, y;

    for(x = 0, y = 10; ((x < 3) && (y > 9)); x++, y += 2)
                 printf("x = %d\ty = %d\n", x, y);

return 0;
}

L'esecuzione del programma produce il seguente risultato:

x = 0  y = 10
x = 1  y = 12
x = 2  y = 14


ovvero:
1) vengono inizializzate le variabili x e y a 0 e 10 rispettivamente;
2) poiché l'espressione è vera viene eseguito il corpo del ciclo, che stampa la prima riga;
3) x e y vengono incrementate di 1 e 2 rispettivamente;
4) poiché l'espressione è ancora vera viene eseguito il corpo del ciclo, che stampa la seconda riga e così via.

Oltre a poter includere più di un'espressione per inizializzare e aggiornare il ciclo for, è possibile anche omettere del tutto uno o più parametri (addirittura anche tutti e tre).
Ad es. l’istruzione:

for(;;);

è valida e quando il programma arriva nel punto in cui si trova questa istruzione si blocca in esso per sempre: ciò è dovuto al fatto che la condizione da verificare in questo caso non restituisce mai zero e il ciclo viene ripetuto infinite volte.
Ad es.:

char c = 'a'
for(;;)
    putchar (c);


stampa una linea senza fine di caratteri 'a'.

Questo tipo di ciclo, detto appunto ciclo infinito, può essere utile in svariati casi e, di fatto, non è raro vedere programmi che ne fanno uso.
E' possibile scrivere cicli infiniti anche con i costrutti while e do-while, che in tal caso assumono le forme:

while(1) {
    ...
}

do {
    ...
} while(1);


Generalmente, inserire cicli infiniti nei propri programmi non è opportuno ed occorre sempre prevedere un modo per poter terminare il programma in maniera controllata.
Questo è possibile tramite l'istruzione break, già vista qualche lezione fa.
Quando questa parola chiave viene incontrata all'interno di un ciclo, il controllo passa all'istruzione immediatamente successiva al ciclo.
Accanto ad essa, il C prevede anche un'altra istruzione, continue, il cui effetto è quello di saltare un'interazione del ciclo.
Break e  continue sono tipicamente associate ad un'istruzione if.
Chiariamoci le idee con un esempio:

/*
 * File lez38_2.c
 */
#include <stdio.h>

int main()
{
       short i, j;

       for (i = 1, j = 100; ; i++, j -= 2)
       {
              if (!(j % i))
printf("j=%d e' divisibile per i=%d", j, i);
              else
              {
                    printf ("j=%d non e' divisibile per i=%d\n", j, i);
                    continue;
              }
              printf("\tIl risultato e' %d\n", j/i);
              if (i >= j)
                    break;
       }
       putchar('\a');

return 0;
}

Ad ogni iterazione del loop, viene controllato il resto della divisione tra j e i: se è zero, la condizione dell'if è vera e viene stampato un messaggio che avvisa che j è divisibile per i, altrimenti viene stampato l'avviso che j non è divisibile per i e il controllo passa alla successiva iterazione, per effetto dell'istruzione continue.
Senza di essa, il controllo avrebbe proseguito con la stampa del risultato della divisione.
Il loop viene arrestato non appena i supera j, tramite l'istruzione break che fa saltare il controllo all'istruzione putchar('\a'), che provoca l'emissione di un 'bip' da parte del computer.

 

Torna all'indice Generale del corso di Corso di C con Linux di Software Planet