FONDAMENTI DI INFORMATICA
Prof. PIER LUCA MONTESSORO Ing. DAVIDE PIERATTONI
Facoltà di Ingegneria
Università degli Studi di Udine
Linguaggio C
Strutture di controllo
Questo insieme di trasparenze (detto nel seguito slide) è protetto dalle leggi sul copyright e dalle disposizioni dei trattati internazionali. Il titolo ed i copyright relativi alle slides (ivi inclusi, ma non limitatamente, ogni immagine, fotografia, animazione, video, audio, musica e testo) sono di proprietà degli autori prof. Pier Luca Montessoro e ing. Davide Pierattoni, Università degli Studi di Udine.
Le slide possono essere riprodotte ed utilizzate liberamente dagli istituti di ricerca, scolastici ed universitari afferenti al Ministero della Pubblica Istruzione e al Ministero dell’Università e Ricerca Scientifica e Tecnologica, per scopi istituzionali, non a fine di lucro. In tal caso non è richiesta alcuna autorizzazione.
Ogni altro utilizzo o riproduzione (ivi incluse, ma non limitatamente, le riproduzioni su supporti magnetici, su reti di calcolatori e stampe) in toto o in parte è vietata, se non esplicitamente autorizzata per iscritto, a priori, da parte degli autori.
L’informazione contenuta in queste slide è ritenuta essere accurata alla data della pubblicazione. Essa è fornita per scopi meramente didattici e non per essere utilizzata in progetti di impianti, prodotti, reti, ecc. In ogni caso essa è soggetta a cambiamenti senza preavviso. Gli autori non assumono alcuna responsabilità per il contenuto di queste slide (ivi incluse, ma non limitatamente, la correttezza, completezza, applicabilità, aggiornamento dell’informazione).
In ogni caso non può essere dichiarata conformità all’informazione contenuta in queste slide.
In ogni caso questa nota di copyright e il suo richiamo in calce ad ogni slide non devono mai essere rimossi e devono essere riportati anche in utilizzi parziali.
Nota di Copyright
Strutture di controllo
• In ogni linguaggio le strutture di controllo permettono di scrivere programmi nei quali il flusso di esecuzione non sia strettamente sequenziale
• I costrutti possono essere:
– condizionali: if-else, switch
– iterativi: while, for, do … while
Istruzioni if-else
• L’istruzione condizionale if-else viene usata per esprimere una decisione
• La sintassi più generale è:
if (espressione)
istruzione_1;
else
istruzione_2;
• if valuta l’espressione, e se risulta vera (Ï non nulla) viene eseguita l’istruzione_1; in caso contrario viene eseguita l’istruzione_2
Y N
Istruzioni if-else
• Esempio
if (i != 0) x = a / i;
else
printf ("Divisione impossibile");
Istruzioni if
• Nel costrutto if-else la parte relativa all’else è opzionale
• L’if semplice permette delle codifiche molto
compatte, quando non è necessaria la ramificazione delle istruzioni
if (k == 0)
printf ("k vale zero\n");
if (x > 0) {
z = y / x;
printf ("z vale %f\n", z);
}
Y N
All’interno di un costrutto condizionale si possono eseguire anche
dei blocchi di istruzioni
Istruzioni if annidate
• In assenza di un else all’interno di una sequenza di if annidati, ogni else viene associato all’if più
vicino
if (n > 0)
if (a > b) z = a;
else
z = b;
• L’indentazione non è discriminante per il compilatore;
con gli if annidati, ogni ambiguità va risolta utilizzando le parentesi
if (n > 0) {
if (a > b) z = a;
else
z = b;
}
Istruzioni if annidate
• Per fare in modo che il costrutto precedente sia interpretato correttamente dal compilatore, si dovrà scrivere:
if (n > 0) {
if (a > b) z = a;
}
else
z = b;
SIMILI AMBIGUITÀ POSSONO ESSERE MOLTO PERICOLOSE!
Istruzioni else if
• La sintassi:
if (espressione_1) istruzione_1;
else if (espressione_2) istruzione_2;
else if (espressione_3) istruzione_3;
else
istruzione_4;
è il modo più generale per realizzare una scelta tra più opzioni
• Le espressioni vengono analizzate nell’ordine in cui si presentano; se una di esse è vera, viene eseguita l’istruzione corrispondente e l’intera catena termina
N Y
Y Y N
N
Istruzioni else if
• Il codice corrispondente ad ogni istruzione può essere anche un blocco di istruzioni tra parentesi graffe
• L’ultimo else è il caso di default: viene eseguito
quando nessuna delle espressioni risulta vera, e alle volte può essere omesso
• Simili costrutti possono risultare complicati se nella scelta si devono valutare numerose espressioni
Istruzioni switch
• L’istruzione switch effettua una scelta multipla controllando se un’espressione assume uno dei valori in un insieme di costanti intere
switch (espressione) {
case costante_1: istruzione_1;
break;
case costante_2: istruzione_2;
break;
...
default: istruzione_default;
break;
}
Istruzioni switch
• Ogni caso possibile è etichettato da un’espressione o da un valore intero costanti
• Le espressioni e le costanti nei diversi casi devono essere tra loro differenti
• Il caso default, opzionale, viene eseguito solo se nessuno dei casi precedenti si è verificato
• L’esecuzione delle istruzioni relative a un caso è seguita dall’esecuzione sequenziale di tutti i casi successivi
L’istruzione break, aggiunta in fondo ad ogni blocco di istruzioni, provoca l’uscita immediata dallo switch
Istruzioni switch
char risposta;
int favorevoli, contrari;
...
printf ("Sei favorevole?");
scanf ("%c", &risposta);
switch (risposta) {
case 's':
case 'S':
case 'y':
case 'Y': favorevoli++;
break;
case 'n':
case 'N': contrari++;
break;
default: printf("Risposta errata!");
break;
}
Si possono anche associare più etichette allo stesso
blocco di istruzioni
Es.: risposta = 'S'
Costrutti iterativi (cicli)
• L’iterazione serve a fare in modo che un’istruzione o un blocco di istruzioni vengano eseguite ripetutamente per
“un certo numero di volte”
• Tale numero può essere:
– noto a priori, essendo uguale al valore di una
costante o di una variabile che non muta durante l’iterazione
– determinato da condizioni dipendenti dall’iterazione
• In C esistono tre costrutti iterativi:
while for
do … while
Ciclo while
• Il costrutto while ha la sintassi:
while (espressione) istruzione;
oppure
while (espressione) {
blocco di istruzioni }
• Se l’espressione risulta vera, allora viene eseguito il blocco di istruzioni, al termine del quale l’espressione viene rivalutata
• Non appena l’espressione diventa falsa, l’iterazione si interrompe e viene eseguita la prima istruzione successiva al costrutto while
Y
N
Ciclo while
• Il frammento di codice
i = 0;
while (i < 100) {
printf ("Messaggio ripetuto 100 volte\n");
i = i + 1;
}
verifica la condizione i < 100 e, trovandola vera per i = 0, esegue il ciclo while, stampa il messaggio, incrementa di uno la variabile i, e ripete la verifica della condizione. L’iterazione prosegue fino a quando i raggiunge il valore 100 (non più strettamente
minore di 100)
Ciclo for
• Il costrutto for ha la sintassi:
for (istr_1; espr_2; istr_3)
istruzione;
oppure
for (istr_1; espr_2; istr_3)
{
blocco di istruzioni }
• istr_1 rappresenta una o più istruzioni di inizializzazione
• espr_2 è la condizione da verificare prima di ogni iterazione
• istr_3 rappresenta una o più istruzioni di aggiornamento, eseguite ad ogni ciclo dopo le istruzioni
Y
N
Operatore virgola
• L’operatore , (virgola) consente di raggruppare più assegnazioni (o statement) in un’unica istruzione
• Il costrutto for permette di avere più assegnazioni in un unico statement per le istruzioni di inizializzazione e di aggiornamento
• Il costrutto:
for (i = 0, j = 5; funz_1(i) < funz_2(j) ; i++, j--) {
istruzioni }
inizializza i a 0 e j a 5, valuta l’espressione e, dopo ogni esecuzione delle istruzioni del ciclo, incrementa i e decrementa j di uno
Ciclo for
• Il frammento di codice relativo al ciclo while
i = 0;
while (i < 100) {
printf ("Messaggio ripetuto 100 volte\n");
i = i + 1;
}
può essere riscritto nella forma più semplice:
for (i = 0; i < 100; i++)
printf ("Messaggio ripetuto 100 volte\n");
Ciclo do … while
• La sintassi del costrutto do … while è la seguente:
do
istruzione;
while (espressione);
oppure:
do {
blocco di istruzioni } while (espressione);
• L’istruzione (o il blocco di istruzioni) viene sempre eseguita almeno una volta; al termine viene valutata l’espressione e, finché questa è vera, l’istruzione viene ripetuta e l’espressione rivalutata (iterazione), altrimenti si passa all’istruzione successiva
Y N
break e continue
• L’istruzione break provoca l’uscita incondizionata da un ciclo for, while o do … while, senza eseguire le istruzioni successive né valutare la condizione di controllo
int n;
for (n = 10000; n > 0; n--) {
if (n % 7 == 0) break;
printf ("%d\n", a[i]);
}
Stampa in ordine
decrescente i numeri interi a partire da 10000 e si
ferma al primo multiplo di 7
FORTEMENTE SCONSIGLIATA!
break e continue
• L’istruzione continue permette di forzare l’inizio dell’iterazione successiva di un ciclo for, while o do … while, provocando l’esecuzione immediata della parte di controllo del ciclo
• Nel caso del for, si passa direttamente alle istruzioni di aggiornamento
int n;
for (n = 0; n < 10000; n++) {
if (n % 7 != 0) continue;
printf ("%d\n", a[i]);
}
Stampa in ordine
crescente i multipli di 7 inferiori a 10000
FORTEMENTE SCONSIGLIATA!
Cicli e sintassi
• Nella scrittura di un programma è importante verificare sempre la correttezza sintattica e semantica delle
istruzioni
• Il frammento di codice:
int i = 0;
while (i < 100);
{
printf ("Messaggio ripetuto 100 volte\n");
i = i + 1;
}
è sintatticamente corretto ed è accettato di buon grado dal compilatore, ma il programma non termina!
l’esecuzione si bloccherà su questa istruzione, a causa del punto e virgola “di troppo”!
Cicli e sintassi
• Lo stesso “baco” ricorre nei costrutti con il ciclo for:
for (i = 0; i < 100; i++);
{
istruzioni }
• Il do … while, invece, richiede il punto e virgola a chiusura dell’intero statement:
do {
printf ("Messaggio ripetuto 100 volte\n");
i = i + 1;
} while (i < 100);
In questo caso il blocco di istruzioni viene eseguito una e una sola volta