Nella lezione di oggi cominceremo a vedere le strutture di controllo presenti all'interno di un programma C. Queste strutture che oggi analizzeremo sono di fondamentale importanza in quanto ci consentono di realizzare quello che sarà il flusso del programma e quindi rappresentano la logica vera e propria che il nostro programma finale assumerà. In pratica un programma è una sorta di scelte che possono venire effettuate dall'utente e su cui il programma stesso dovrà assumere comportamenti diversi a seconda della scelta fatta. Questo è possibile proprio grazie alle strutture di controllo e di iterazione.
In questa lezione prenderemo in esame le prime, mentre nella prossima lezione focalizzeremo l'attenzione sulle strutture iterative.
Le strutture di controllo o "strutture condizionali" sono righe di codice strutturate secondo una logica ben precisa. Vengono utilizzate quando si vuole far fare una scelta al programma. Queste strutture prendono in input il valore di una variabile e rispondono eseguendo del codice differente a seconda del valore assunto da quest'ultima. Esistono due tipi principali di strutture condizionali in C. Il primo tipo viene chiamata "struttura if-else" ed ha una forma di questo tipo:
if(<condizione>) {
...<fai qualcosa>...
} else {
...<fai qualcos'altro>...
}
All'interno delle parentesi tonde presenti sulla prima riga di codice va inserita la variabile da controllare. Nel caso in cui il controllo su questa variabile sia verificato positivamente (ritorni true) allora verrà eseguito il codice racchiuso dalle prime parentesi graffe. In caso negativo verrà eseguito il codice racchiuso nelle seconde parentesi graffe (quello dopo la clausola "else"). Mi spiego meglio: come condizione abbiamo detto che va inserita una qualsiasi variabile (l'importante che sia una variabile di tipo primitivo...non abbiamo ancora visto quali siano i tipi composti, ma tenete buona questa cosa per quando li affronteremo!). Viene effettuato un test dal processore per verificare se ciò che è rappresentato all'interno delle parentesi tonde sia vero o meno. Nel caso il test sia positivo (vero) allora si dice che la condizione "è soddisfatta" quindi verrà eseguito il codice immediatamente successivo (quello rappresentato dalle prime parentesi graffe). Nel caso in cui la condizione non sia soddisfatta verrà eseguito il codice che viene immediatamente dopo la clausola "else".
Un esempio di quanto detto è il codice seguente:
int voto_scolastico;
voto_scolastico = 8;
if(voto_scolastico < 6) {
printf("Il voto è insufficiente! Devi studiare di più!\n");
} else {
printf("Complimenti! Sei stato promosso!\n");
printf("Adesso non ti resta che mettere in pratica ciò che hai imparato.\n");
}
In questo caso viene verificato il valore della variabile "voto_scolastico". Se questa assume un valore minore di 6 viene eseguito il codice immediatamente successivo. In questo caso la condizione assume il valore di false in quanto, come si può ben vedere dal codice il voto NON è minore di 6 (in quanto equivale a 8) e quindi verrà eseguito il codice successivo alla clausola else. Tutto il codice che deve essere eseguito nel caso di condizione positiva o negativa è racchiuso tra parentesi graffe. Questo è sempre vero tranne nei casi in cui si voglia far eseguire al nostro programma una singola linea di codice. In questo caso le parentesi graffe possono anche essere omesse. Il codice dell'esempio sopra riportato potrebbe essere quindi trascritto nel seguente modo:
int voto_scolastico;
voto_scolastico = 8;
if(voto_scolastico < 6)
printf("Il voto è insufficiente! Devi studiare di più!\n");
else {
printf("Complimenti! Sei stato promosso!\n");
printf("Adesso non ti resta che mettere in pratica ciò che hai imparato.\n");
}
Come vedete nel primo caso abbiamo omesso le parentesi in quanto il codice da eseguire era composto da un'unica riga. Le abbiamo, però, mantenute nella condizione "else" in quanto in questo caso il nostro codice è rappresentato da due righe quindi non ci è possibile eliminare le parentesi.
Va fatta un'ulteriore precisazione riguardo il costrutto "if/else". La clausola else è del tutto opzionale. In tale costrutto può essere specificata per far compiere un azione al nostro programma nel caso in cui la condizione non risulti soddisfatta, ma comunque questo comportamento non è obbligatorio. Se ad esempio avessimo voluto solamente informare lo studente di una sua bocciatura, avremmo potuto scrivere in questo modo:
int voto_scolastico;
voto_scolastico = 8;
if(voto_scolastico < 6) {
printf("Il voto è insufficiente! Mi dispiace, ma dovrai ripetere l'anno!\n");
return 0; // Serve per uscire dalla funzione (o dal programma nel caso ci trovassimo nel main)
}
// Continua il codice nel caso di promozione
........
Con il costrutto if/else è possibile anche effettuare test multipli su una stessa variabile (o anche su più variabili). Se ad esempio avessimo voluto esprimere un parere a seconda del voto ottenuto dallo studente avremmo potuto scrivere una cosa del tipo:
.......................
if(voto_scolastico == 0)
printf("Ma cosa segui a fare il corso che tanto non hai imparato nulla?\n");
else if(voto_scolastico > 0 && voto_scolastico < 4)
printf("Sei davvero scarso! Cerca di applicarti di più!\n");
else if(voto_scolastico >= 4 && voto_scolastico < 6)
printf("Ancora uno sforzo per raggiungere la sufficienza!\n");
else if(voto_scolastico >= 6 && voto_scolastico < 8)
printf("Stai andando bene! Continua così!\n");
else if(voto_scolastico >= 8 && voto_scolastico < 10)
printf("Complimenti, sei davvero in gamba!\n");
else // In questo caso sicuramente il voto vale 10!
printf("Eccellente!\n");
In questo esempio vengono analizzati casi diversi e solamente quando una delle condizioni viene soddisfatta viene eseguito il codice corrispondente. va fatto notare che è possibile esprimere una condizione anche come espressione di variabili...l'importante è che il risultato ultimo possa essere solamente true oppure false. Se prendiamo ad esempio la seguente riga di codice:
else if(voto_scolastico >= 4 && voto_scolastico < 6)
questa esegue due test distinti: prima verifica che voto_Scolastico sia maggiore o uguale a 4 dopodichè (se questo è positivo) verifica che sia anche minore di 6. Se entrambi le condizioni sono soddisfatte (dico entrambi in quanto questi due test sono legati tra loro dall'operatore AND rappresentato dal costrutto &&) restituisce true altrimenti se solamente una delle due fosse falsa restituirebbe false.
Va notato, inoltre, che per esprimere un'uguaglianza non va utilizzato l'operatore =, ma bensì ==. Questo perchè se la prima riga avessimo scritto:
if(voto_scolastico = 0)
il compilatore C avrebbe interpretato la riga di codice nel seguente modo:
assegno il valore 0 alla variabile voto_scolastico dopodichè eseguo il test --> if(voto_scolastico). Essendo voto_scolastico uguale a zero perchè glielo abbiamo appena assegnato, questo è l'equivalente del valore false quindi l'intera condizione sarebbe stata giudicata false.
Tutto questo ragionamento può sembrare corretto a prima vista ma ci sono delle incongruenze:
1) Dopo il primo test voto_scolastico non vale più 8 bensì 0 e continuando nei test l'unica condizione che lo soddisferebbe sarebbe l'ultima
2) Pensate se voto_scolastico valesse davvero 0 prima dell'inizio dei test: la conseguenza sarebbe comunque identica al caso precedente....Eccellente!
In questa lezione prenderemo in esame le prime, mentre nella prossima lezione focalizzeremo l'attenzione sulle strutture iterative.
Le strutture di controllo o "strutture condizionali" sono righe di codice strutturate secondo una logica ben precisa. Vengono utilizzate quando si vuole far fare una scelta al programma. Queste strutture prendono in input il valore di una variabile e rispondono eseguendo del codice differente a seconda del valore assunto da quest'ultima. Esistono due tipi principali di strutture condizionali in C. Il primo tipo viene chiamata "struttura if-else" ed ha una forma di questo tipo:
if(<condizione>) {
...<fai qualcosa>...
} else {
...<fai qualcos'altro>...
}
All'interno delle parentesi tonde presenti sulla prima riga di codice va inserita la variabile da controllare. Nel caso in cui il controllo su questa variabile sia verificato positivamente (ritorni true) allora verrà eseguito il codice racchiuso dalle prime parentesi graffe. In caso negativo verrà eseguito il codice racchiuso nelle seconde parentesi graffe (quello dopo la clausola "else"). Mi spiego meglio: come condizione abbiamo detto che va inserita una qualsiasi variabile (l'importante che sia una variabile di tipo primitivo...non abbiamo ancora visto quali siano i tipi composti, ma tenete buona questa cosa per quando li affronteremo!). Viene effettuato un test dal processore per verificare se ciò che è rappresentato all'interno delle parentesi tonde sia vero o meno. Nel caso il test sia positivo (vero) allora si dice che la condizione "è soddisfatta" quindi verrà eseguito il codice immediatamente successivo (quello rappresentato dalle prime parentesi graffe). Nel caso in cui la condizione non sia soddisfatta verrà eseguito il codice che viene immediatamente dopo la clausola "else".
Un esempio di quanto detto è il codice seguente:
int voto_scolastico;
voto_scolastico = 8;
if(voto_scolastico < 6) {
printf("Il voto è insufficiente! Devi studiare di più!\n");
} else {
printf("Complimenti! Sei stato promosso!\n");
printf("Adesso non ti resta che mettere in pratica ciò che hai imparato.\n");
}
In questo caso viene verificato il valore della variabile "voto_scolastico". Se questa assume un valore minore di 6 viene eseguito il codice immediatamente successivo. In questo caso la condizione assume il valore di false in quanto, come si può ben vedere dal codice il voto NON è minore di 6 (in quanto equivale a 8) e quindi verrà eseguito il codice successivo alla clausola else. Tutto il codice che deve essere eseguito nel caso di condizione positiva o negativa è racchiuso tra parentesi graffe. Questo è sempre vero tranne nei casi in cui si voglia far eseguire al nostro programma una singola linea di codice. In questo caso le parentesi graffe possono anche essere omesse. Il codice dell'esempio sopra riportato potrebbe essere quindi trascritto nel seguente modo:
int voto_scolastico;
voto_scolastico = 8;
if(voto_scolastico < 6)
printf("Il voto è insufficiente! Devi studiare di più!\n");
else {
printf("Complimenti! Sei stato promosso!\n");
printf("Adesso non ti resta che mettere in pratica ciò che hai imparato.\n");
}
Come vedete nel primo caso abbiamo omesso le parentesi in quanto il codice da eseguire era composto da un'unica riga. Le abbiamo, però, mantenute nella condizione "else" in quanto in questo caso il nostro codice è rappresentato da due righe quindi non ci è possibile eliminare le parentesi.
Va fatta un'ulteriore precisazione riguardo il costrutto "if/else". La clausola else è del tutto opzionale. In tale costrutto può essere specificata per far compiere un azione al nostro programma nel caso in cui la condizione non risulti soddisfatta, ma comunque questo comportamento non è obbligatorio. Se ad esempio avessimo voluto solamente informare lo studente di una sua bocciatura, avremmo potuto scrivere in questo modo:
int voto_scolastico;
voto_scolastico = 8;
if(voto_scolastico < 6) {
printf("Il voto è insufficiente! Mi dispiace, ma dovrai ripetere l'anno!\n");
return 0; // Serve per uscire dalla funzione (o dal programma nel caso ci trovassimo nel main)
}
// Continua il codice nel caso di promozione
........
Con il costrutto if/else è possibile anche effettuare test multipli su una stessa variabile (o anche su più variabili). Se ad esempio avessimo voluto esprimere un parere a seconda del voto ottenuto dallo studente avremmo potuto scrivere una cosa del tipo:
.......................
if(voto_scolastico == 0)
printf("Ma cosa segui a fare il corso che tanto non hai imparato nulla?\n");
else if(voto_scolastico > 0 && voto_scolastico < 4)
printf("Sei davvero scarso! Cerca di applicarti di più!\n");
else if(voto_scolastico >= 4 && voto_scolastico < 6)
printf("Ancora uno sforzo per raggiungere la sufficienza!\n");
else if(voto_scolastico >= 6 && voto_scolastico < 8)
printf("Stai andando bene! Continua così!\n");
else if(voto_scolastico >= 8 && voto_scolastico < 10)
printf("Complimenti, sei davvero in gamba!\n");
else // In questo caso sicuramente il voto vale 10!
printf("Eccellente!\n");
In questo esempio vengono analizzati casi diversi e solamente quando una delle condizioni viene soddisfatta viene eseguito il codice corrispondente. va fatto notare che è possibile esprimere una condizione anche come espressione di variabili...l'importante è che il risultato ultimo possa essere solamente true oppure false. Se prendiamo ad esempio la seguente riga di codice:
else if(voto_scolastico >= 4 && voto_scolastico < 6)
questa esegue due test distinti: prima verifica che voto_Scolastico sia maggiore o uguale a 4 dopodichè (se questo è positivo) verifica che sia anche minore di 6. Se entrambi le condizioni sono soddisfatte (dico entrambi in quanto questi due test sono legati tra loro dall'operatore AND rappresentato dal costrutto &&) restituisce true altrimenti se solamente una delle due fosse falsa restituirebbe false.
Va notato, inoltre, che per esprimere un'uguaglianza non va utilizzato l'operatore =, ma bensì ==. Questo perchè se la prima riga avessimo scritto:
if(voto_scolastico = 0)
il compilatore C avrebbe interpretato la riga di codice nel seguente modo:
assegno il valore 0 alla variabile voto_scolastico dopodichè eseguo il test --> if(voto_scolastico). Essendo voto_scolastico uguale a zero perchè glielo abbiamo appena assegnato, questo è l'equivalente del valore false quindi l'intera condizione sarebbe stata giudicata false.
Tutto questo ragionamento può sembrare corretto a prima vista ma ci sono delle incongruenze:
1) Dopo il primo test voto_scolastico non vale più 8 bensì 0 e continuando nei test l'unica condizione che lo soddisferebbe sarebbe l'ultima
2) Pensate se voto_scolastico valesse davvero 0 prima dell'inizio dei test: la conseguenza sarebbe comunque identica al caso precedente....Eccellente!