In questa lezione di C presentiamo i costrutti che permettono di eseguire ciclicamente istruzioni, o blocchi di istruzioni, fino al verificarsi di alcune condizioni. Questi costrutti prendono il nome di strutture di controllo iterative o istruzioni di ciclo.
Le istruzioni di ciclo sono una delle componenti fondamentali della programmazione e permettono di risparmiare la quantità di codice scritta rendendo quindi il programma più leggero e più facile da comprendere. Le istruzioni di ciclo, come le istruzioni condizionali, hanno bisogno che alcune condizioni vengano verificate affinché il ciclo continui nella sua opera o si interrompa.
Le istruzioni di ciclo del C sono tre:
- il while, che continua il suo ciclo fino a quando l'espressione associata non risulta falsa
- il do-while, che agisce come il while, ma assicura l'esecuzione delle istruzioni associate almeno una volta
- il for, che è il costrutto più usato, versatile e potente tra i tre, ma che proprio per questo è quello a cui bisogna prestare un po' più di attenzione.
Come per le istruzioni condizionali, quando parliamo di "istruzione" ci riferiamo ad una o più istruzioni associate, ricordando che se le istruzioni sono due o più bisogna usare le parentesi graffe per delimitarle, mentre una singola istruzione non ne ha necessariamente bisogno.
While in C
La struttura del while è la seguente:
while (condizione)
istruzione/i
Generalmente l'istruzione o le istruzioni all'interno del while agiscono sulla condizione che il while aspetta essere falsa per poter uscire dal ciclo, questo perché altrimenti il ciclo non terminerebbe. Ad esempio per stampare a video una successione di cifre da 0 a 99, proponiamo il codice seguente:
int i = 0;
while (i != 100)
{
printf("%d n", i);
i++;
}
Affinché il while possa verificare la condizione associata, è necessario aver dichiarato la variabile prima del while, questo, come nell'esempio, può essere fatto nella riga soprastante o in un altra parte del programma.
Do - While
Molto simile al while è il do-while che ha la seguente struttura:
do
istruzione/i
while (condizione)
Tenendo valide tutte le considerazioni fatte per il while, va notato che in questo modo si esegue l'istruzione all'interno del do-while almeno una volta, indipendentemente dal fatto che la condizione associata al while risulti vera o falsa. L'esempio seguente mostra come sia possibile utilizzare il do-while, ad esempio, per porre una domanda all'utente e continuare nell'esecuzione solo se l'utente risponde correttamente, oppure ripetere la domanda:
do {
printf("Premere 1 per continuare : ");
scanf("%d", & valore);
printf("n");
} while (valore !=1)
Ciclo For - C
Prima di spiegare le caratteristiche del for, ne proponiamo la struttura generale:
for (inizializzazione ; condizione ; incremento)
istruzione/i
che equivale alla rappresentazione con un while con la seguente struttura:
inizializzazione
while (condizione)
istruzione/i
incremento
Il for, quindi, potrebbe tranquillamente essere sostituito da un while, se non fosse che è più conciso ed è concettualmente usato quando sappiamo a priori il numero di iterazioni che vogliamo fare. I parametri all'interno del for hanno diversi compiti, e sono separati da un punto e virgola:
- Il primo viene eseguito prima di entrare nel ciclo, ed inizializza una variabile, generalmente la variabile è usata come variabile di controllo del ciclo, in poche parole servirà per tenere traccia del numero di iterazioni del ciclo; a differenza del C++, dove la dichiarazione può essere fatta contemporaneamente all'inizializzazione, nel C, in questo costrutto, la variabile deve essere dichiarata fuori, prima del for;
- Il secondo è la condizione (che coinvolge anche la variabile di controllo), che se risulta falsa interrompe l'esecuzione del ciclo;
- Il terzo parametro è l'istruzione di incremento, che viene eseguita dopo ogni ciclo del for; questa istruzione agisce generalmente sulla variabile di controllo incrementandone (o decrementandone) il valore.
Per chiarire meglio l'uso del for presentiamo un semplice codice che conta da zero a cento, stampando a video la variabile di controllo:
int i;
for (i=0; i<=100; i++)
printf("%d n", i);
Ognuna delle tre istruzioni all'interno del for può essere omessa, con il risultato di condizionare il ciclo, o non modificando la variabile, o facendo essere sempre vera la "condizione" del for; in questo ambito bisogna citare un uso particolare del ciclo for, che è quello del cosiddetto "ciclo for infinito". Un ciclo che non termina, abbiamo detto precedentemente, è da considerarsi errore, ma esiste una situazione in cui vogliamo, invece, ciclare all'infinito fino a quando l'utente non decide di interrompere volontariamente il programma, ad esempio avendo un menu generale che ogni volta deve presentarsi sullo schermo. Il for utilizzato in questo caso ha una struttura particolarissima, ovvero non ha nessuno dei tre parametri sopra esposti, ma contiene solamente due caratteri punto e virgola:
main ()
{
for ( ; ; )
{
printf ("premi CtrL+Z per interromperen");
}
}
è anche possibile utilizzare all'interno delle tre istruzioni, più di una variabile di controllo, in modo da avere un ciclo dinamico; un esempio può essere quello di due variabili, "high" e "low" che convergono:
int high;
int low;
for (high=100, low=0; high >= low; high--, low++)
printf("H=%d - L=%d n", high, low);
Break in C e l'istruzione Continue
Abbiamo già usato l'istruzione break quando stavamo parlando dello switch, senza addentrarci nel dettaglio, adesso, invece, conviene spiegare le caratteristiche del break e di un'altra istruzione, continue:
- break - esce dal ciclo o dallo switch;
- continue - salta una iterazione del ciclo senza interromperlo;
Per capire la sottile, quanto importante, differenza tra le due istruzioni, presentiamo un semplice codice in cui si legge un numero da tastiera che volgiamo sia compreso tra 0 e 100, se tale valore risulta essere negativo, si esce dal ciclo, mentre se è maggiore di cento si richiede di inserire un valore valido; se il valore è tra 1 e 100, si stampa a video il suo quadrato, se è zero si esce:
int valore;
while (scanf("%d", &valore) == 1 && valore != 0)
{
if (valore < 0)
{
printf("Valore non consentiton");
break;
/* esce dal ciclo */
}
if (valore > 100)
{
printf("Valore non consentiton");
continue;
}
int quadrato = valore * valore;
printf("%d n", quadrato);
}
ESEMPIO PRATICO (Visualizza il sorgente completo)
Anche i cicli FOR ed i cicli WHILE vengono usati largamente all'interno del programma. Servono soprattutto per scorrere gli elementi, ad esempio, per salvarli o stamparli a video. Mostriamo di seguito due esempi:
[Legge una serie di elementi e li stampa a video]
186 while (p != NULL)
187 { // WHILE - OPEN
188
189 /*
190 * Stampo gli altri contatti
191 */
192 system(pulisci); // PULISCE LO SCHERMO
193 printf (" #######################n");
194 printf (" # RUBRICA EASY v1.0 #n");
195 printf (" #######################n");
196 printf (" # VISUALIZZA CONTATTO #n");
197 printf (" #######################nn");
198 printf (" NOME > %sn", p->inf.nome);
199 printf (" COGNOME > %sn", p->inf.cognome);
200 printf (" TELEFONO > %sn", p->inf.telefono);
201 printf (" EMAIL > %sn", p->inf.email);
202 printf (" SITOWEB > %sn", p->inf.sitoweb);
203 pausa();
204 // Leggo l'elemento successivo
205 p = p->pun;
206
207 } // WHILE - CLOSE
[...]
[...]
[Modifica una serie di elementi]
326 for (n=1; n<i; n++)
327 { // FOR - OPEN
328
329 /*
330 * trovato l'elemento modifico l'informazione dentro di esso
331 */
332 if (subscelta == n)
333 { // IF - OPEN
334
335 // Popolo la variabile daInserire
336 printf (" NOME [%s] > ", p->inf.nome);
337 scanf ("%s", p->inf.nome);
338 printf (" COGNOME [%s] > ", p->inf.cognome);
339 scanf ("%s", p->inf.cognome);
340 printf (" TELEFONO [%s] > ", p->inf.telefono);
341 scanf ("%s", p->inf.telefono);
342 printf (" EMAIL [%s] > ", p->inf.email);
343 scanf ("%s", p->inf.email);
344 printf (" SITOWEB [%s] > ", p->inf.sitoweb);
345 scanf ("%s", p->inf.sitoweb);
346
347 } // IF - CLOSE
348
349 p = p->pun;
350
351 } // FOR - CLOSE