Nella precedente lezione ci eravamo lasciati parlando di operatori logici e relazionali e vi avevo detto che avremmo fatto qualche esempio di utilizzo nella prossima lezione, ed eccoci qui.
Il motivo per cui non ho scritto alcun esempio basato su questi operatori è che ancora non abbiamo imparato come far prendere delle decisioni ai nostri programmi, quindi valutare se una variabile è vera o falsa senza poi saper prendere delle decisioni a riguardo è praticamente inutile.
if…else
Il costrutto if…else (traduzione: se…altrimenti) è sicuramente il costrutto decisionale più utilizzato, spesso viene citato semplicemente come costrutto if.
Un linguaggio di programmazione che non abbia la possibilità di prendere una decisione praticamente non è un linguaggio di programmazione.
Ricordate l’algoritmo per preparare il tè visto nella seconda lezione? Quel rombo al centro è proprio il simbolo del costrutto decisionale, se è vera una data condizione il programma esegue delle operazioni, se invece è falsa allora ne esegue delle altre.
la sintassi del costrutto if è la seguente:
if (espressione) {
istruzioni...
istruzioni...
...
}
else {
istruzioni...
istruzioni...
...
}
Come si può facilente intuire il costrutto if valuta l’espressione tra parentesi e se questa risulta essere vera esegue le istruzioni immediatamente successive, se invece l’espressione è falsa allora esegue le istruzioni contentute nel blocco che segue la parola else.
Ma cosa può essere inserito come espressione? Può essere inserito tutto quello che in qualche modo restituisce un valore vero/falso, siano esse singole istruzioni o combinazioni di istruzioni.
Facciamo qualche esempio:
int anni = 42;
if (anni < 100 ) {
printf("Hei, sei ancora un giovanotto!\n");
}
else {
printf("Quanto spendi in candeline??\n");
}
oppure
int saldoconto = 1000;
int speseOrdinarie = 100;
int speseStraordinarie = 300;
if ((speseOrdinarie + speseStraordinarie) <= saldoconto ) {
printf("Non sei ancora sul lastrico\n");
}
else {
printf("Meglio cercare di rudurre le spese!!\n");
}
In questo secondo esempio ho utilizzato una combinazione di istruzioni, ed ho utilizzato delle parentesi, anche se non erano necessarie visto che l’operatore “+” ha una maggiore priorità rispetto al “<=", per facilitare la comprensione del codice.
Vediamo un altro esempio:
int temperatura = 38;
if ((temperatura >= 38) && (temperatura <= 40)) {
printf("Hai la febbre, dovresti prendere qualcosa!");
}
if ((temperatura >= 36) && (temperatura < 38)) {
printf("Temperatura nella norma");
}
if (temperatura > 40) {
printf("Febbre alta! chiama il medico");
}
if (temperatura < 36) {
prinf("Ipotermia??");
}
}
In questo esempio ho invece utilizzato l’operatore logico AND (&&) per assicurarmi che le due condizioni siano entrambe vere, inoltre all’interno del blocco di codice else ho utilizzato altri costrutti if, creando quelli che si chiamano if annidati.
Attenti alle insidie
Un errore molto comune che capita davvero spesso è il seguente:
int temperatura = 25;
if (temperatura = 0)
{
printf("Freddissimo! ci sono %d gradi",temperatura);
}
else {
printf("Non ci sono zero gradi, ma %d gradi",temperatura);
}
Leggendo il codice precedente potremmo pensare che l’output di questo codice sia “Freddissimo! ci sono 25 gradi” visto che la temperatura è stata inizializzata a 25 e sicuramente 25 non è uguale a 0. Però se proviamo a compilare questo codice il messaggio è uno strano “Non ci sono zero gradi, ma 0 gradi” che cosa è successo? Purtroppo abbiamo confuso l’operatore logico “==” con l’operatore di assegnamento “=” (vi avevo avvisato nella precedente lezione! Avreste dovuto notarlo!) L’operatore di assegnamento in C da come valore di ritorno il valore assegnato (link), quindi in realtà l’espressione prima assegna a temperatura il valore 0, poi ritorna zero perché è il valore assegnato quindi una volta analizzata l’espressione il costrutto if diventa
int temperatura = 25;
if (0)
{
printf("Freddissimo! ci sono %d gradi",temperatura);
}
else {
printf("Non ci sono zero gradi, ma %d gradi",temperatura);
}
Come abbiamo visto il valore 0 in C identifica il FALSO, quindi vengono eseguite le istruzioni contenute all’interno del blocco di codice else.
Adesso che avete capito l’errore provate ad esaminare questo codice:
int t = 0;
if (t = 25) {
printf("Temperatura gradevole, ci sono %d gradi",t);
}
else {
printf("Non ci sono certo 25 gradi! ce ne sono %d",t);
}
e provate a spiegare perché questa volta, invece, il messaggio di output è “Temperatura gradevole, ci sono 25 gradi”
Varianti di if…else
Quella che abbiamo esaminato fino ad ora è la struttura standard del costrutto if, ma esisono alcune piccole varianti, le varianti non sono indispensabili, qualsiasi programma può essere scritto utilizzando solo la versione base del costrutto if, queste ultime, però, aiutano a scrivere codice più comprensibile.
if con una sola istruzione
Se il vostro blocco di codice è composto da una singola istruzione le parentesi graffe possono essere omesse. Ad esempio la seguente sintassi è perfettamente ammessa:
if (credito > 0)
printf("Puoi ancora telefonare");
else
printf("Hai esaurito il credito");
if senza else
ll costrutto else è opzionale, non sempre è necessario fare qualcosa se il risultato dell’espressione è falso. In questo caso è lecito scrivere:
int numerofattura = 1000;
if (numerofattura == 1000)
printf("Sei il cliente num. 1000!!!");
...altre istruzioni...
...altre istruzioni...
Da notare che questa sintassi si presta a molti possibili fraintendimenti perché solo l’indentazione chiarisce qual’è l’istruizione che sta “dentro” l’if e quali invece vengono eseguite indipendentemente dal risultato dell’espressione. Qualcuno per questo motivo preferisce scrivere il codice precedente tutto su una riga:
int numerofattura = 1000;
if( numerofattura == 1000) printf("Sei il cliente num. 1000!!!");
...altre istruzioni...
...altre istruzioni...
ma non è uno stile che io gradisco, io di solito aggiungo lo stesso le parentesi graffe, anche quando potrebbero essere omesse, in questo modo:
int numerofattura = 1000;
if (numerofattura == 1000) {
printf("Sei il cliente num. 1000!!!");
}
...altre istruzioni...
...altre istruzioni...
if…else if…else
In alcuni casi si può avere la necessità di distinguere tra più di due valori, in questo caso si può utilizzare il costrutto if…else if…else la sua sintassi è la seguente:
if (espressione) {
...istruzioni...
...istruzioni...
}
else if (espressione) {
...istruzioni...
...istruzioni...
}
else {
...istruzioni...
...istruzioni...
}
Vengono valutate le espressioni dall’alto verso il basso e quando la prima espressione risulta vera il programma esegue le istruzioni contenute nel blocco di codice corrispondente. Terminato il blocco di istruzioni salta direttamente alla prima istruzione che segue il blocco if…else if…else (non esegue mai due blocchi di codice anche se le relative espressioni risultano entrambe vere). Se nessuna espressione risulta vera viene eseguito infine il codice all’interno del blocco else. Il blocco else è però facoltativo.
Con questa sintassi l’esempio precedente sulla temperatura corporea potrebbe essere riscritto in questo modo:
if (temperatura < 36) {
printf("Sei in ipotermia");
}
else if ( (temperatura >= 36) && (temperatura < 38) ) {
printf("Temperatura normale");
}
else if ( (temperatura >= 37) && (temperatura <= 40) ){
printf("Hai la febbre, dovresti prendere qualcosa");
else if (temperatura > 40) {
printf("Hai la febbre alta, chiama un medico");
}
Costrutto switch-case-default
Un secondo costrutto decisionale è il costrutto switch-case-default, non è un costrutto indispensabile, può essere simulato con una serie di if annidati, ma alle volte può essere comodo e rendere il codice più leggibile. La sua sintassi è la seguente
switch (variabile)
{
case valore1:
...istruzione...
break;
case valore2:
...istruzione...
break;
case valore3:
...istruzione...
break;
default:
...istruzioni...
}
Quello che fa è esaminare il valore di una variabile e, a seconda del valore, eseguire le istruzioni corrispondenti. Attenzione all’istruzione break: è indispensabile, se omessa il codice eseguirà anche le istruzioni contenute negli altri blocchi (si, lo so è un comportamento anomalo, infatti non amo molto questo costrutto). Se nessun case corrisponde al valore della variabile viene eseguito il codice all’interno del blocco default, blocco che è facoltativo.
Operatore ternario
L’operatore ternario ha la stessa funzione del costrutto if…else, ma è più sintetico e potete utilizzarlo quando dovete eseguire una sola operazione. La sua sintassi è la seguente
espressione ? ..istruzione se vera : ..istruzione se falsa
In pratica valuta l’espressione e se risulta vera esegue l’istruzione immadiatamente successiva, viceversa esegue l’istruzione che segue i due punti. È equivalente a:
if (espressione)
istruzione;
else
istruzione;
Vediamo questo costrutto in un esempio pratico:
int a = 10;
int b = 5;
int massimo;
massimo = (a > b) ? a : b;
Prossimamente
Nella prossima lezione parleremo dei costrutti iterativi for, while e until.
Letture consigliate:
Il linguaggio C. Principi di programmazione e manuale di riferimento (Accademica)
Brian W. Kernighan – Dennis M. Ritchie
Editore: Pearson | Lingua: Italiano | Brossura: 313 pagine
Prezzo Listino: EUR 27,00
Prezzo Promozione: EUR 22,95 con Spedizione gratuita
C. Corso completo di programmazione
Paul J. Deitel – Harvey M. Deitel
Editore: Apogeo | Lingua: Italiano | Brossura: 640 pagine
Prezzo Listino: EUR 39,00
Prezzo Promozione: EUR 33,15 con Spedizione gratuita











32 Responses to “8. Costrutti decisionali”
15 Aprile 2011
TuxQuando ci sarà la prossima lezione?
15 Aprile 2011
Ignaziocazz che ingordi!! 🙂
15 Aprile 2011
TuxÈ troppo bello il C devi capirci!
15 Aprile 2011
FabioMa io conosco c++, quali sono le differenze sostanziali?
15 Aprile 2011
L4kyErrore negli esempi “Attenti alle insidie”: negli if ci vanno due = non uno solo.
Anche nell esempio della temperatura = 25
Per il resto lezione perfetta.
15 Aprile 2011
SpartanMa quanto è bello il C ? Io sono ai vettori.. forza Ignazio.. 😀
15 Aprile 2011
Bonfisto cercando di compire il mio primo programma ma il conpilaore(minGW) mi da questi errori
1.c:3:1: error: initializer element is not constant
1.c:5:1: error: expected identifier or ‘(‘ before ‘if’
1.c:6:1: error: expected identifier or ‘(‘ before ‘{‘ token
1.c:10:1: error: expected identifier or ‘(‘ before ‘else’
1.c:11:1: error: expected identifier or ‘(‘ before ‘{‘ token
ecco il codice
int annonascita = 1987;
int eta = (2011 – annonascita);
if (annonascita 1993);
{
printf(“Sei maggiorenne.Hai o compierai quest’anno %d anni.\n”,eta);
15 Aprile 2011
DarioIl corso di C più completo e chiaro di tutto il web.. 😀
ho una domanda…
non capisco esattamente la differenza tra il costrutto con if annidati e il costrutto if…else if…else , cambia solo la sintassi ma il risultato è lo stesso oppure no???
15 Aprile 2011
ignaziocè un errore voluto, se leggi il testo vedi che lo sto spiegando!
15 Aprile 2011
ignaziocil codice così non può essere compilato. devi scrivere
[code]
int main() {
int annodinascita = 1987;
int eta = (2011 – annonascita);
if (annonascita == 1993) {
printf(“Sei maggiorenne. Hai o compierai quest’anno %d anni.\n”,eta);
}
}
15 Aprile 2011
ignaziocgrazie!
per quel che riguarda la domanda tutto dipende dalle condizioni che utilizzi, diciamo che in genere puoi riuscire ad ottenere lo stesso effetto con entrambi i costrutti.
resta l’idea che gli if annidati significano “se è vero questo, ed è vero anche questo…e poi è vero anche questo..”
mentre un if…else if significa “se è vero questo, oppure se è vero quest’altro, oppure se è vero quest’altro ancora”…
15 Aprile 2011
ignazioca me il C !non piace. 😀 😀
15 Aprile 2011
alefl’esempio del codice giusto funziona perchè abbiamo cambiato il valore di t scrivendo un =, quindi è vera e ci da il nuovo risultato.
Se avessimo scritto due =, ci avrebbe detto “Non ci sono certo 25 gradi! ce ne sono 0”.. giusto???
15 Aprile 2011
EnricoAhahahahah[risata malvagia]
Mi sento potente a capirci qualcosa:-)
nn vedo l’ora di poter fare la mia prima app!!! ( ke sara na cagata ma va bene lo stesso)
Grazie ancora prof;)
15 Aprile 2011
Spartan😀
16 Aprile 2011
Andrea96cacchio , io programmo Pascal da un annetto e devo dire che il C è molto più semplice (per ora: manca ancora la UI)
17 Aprile 2011
ignaziocla tua risposta è giusta in parte, nel senso che io non definirei quel codice “corretto”, certo l’output sembra corretto ma l’assegnazione dentro l’if è una cosa molto rischiosa, e se proprio vogliamo farla deve essere commentata
Si, se avessimo utilizzato come condizione “if (t == 25)” l’output sarebbe stato quello che hai detto.
17 Aprile 2011
ignaziocMi dispiace deluderti ma il “C” non permette in maniera nativa la gestione delle interfacce grafiche quindi non credo che le tratterò. Parlare di interfacce grafiche significherebbe parlare di toolkit come le GTK o le QT (per linux per windows non ho idea di che cosa esista) che avrebbero poco a che fare con il linguaggio.
Magari se viene richiesto da più utenti possiamo fare qualche piccolo tutorial… 🙂
17 Aprile 2011
feffeE’ veramente fantastico il modo in cui spieghi i concetti di programmazione, veramente complimenti.
vorrei sapere se alla fine del corso è prevista la possibilità di scaricare tutte le lezioni assieme o se mi devo preoccupare di raccoglierle man mano. Io ho poco tempo per visionarle sul web e visto che è fatto così bene, vorrei usare il tuo corso come riferimento.
19 Aprile 2011
MacMomoNel primo esempio con le temperature c’è qualcosa che non quadra.
Dato che usi un int, le prime due espressioni non saranno mai vere.
Un numero intero infatti non può essere maggiore di 38 e minore di 39 nello stesso momento.
Lo stesso vale per 36 e 37.
Probabilmente la soluzione più logica è modificare l’operatore aggiungendo un ‘=’.
19 Aprile 2011
ignazioccolpito! hai perfettamente ragione, modifico il codice appena ho un attimo.
grazie per la segnalazione
19 Aprile 2011
ignaziocVedremo, secondo me un bell’archivio in pdf si può fare!
19 Aprile 2011
Gran GiullareComplimenti per il tuo corso, magnifico!
Mi sono pero’ un momento perso. Nell’esempio della temperatura corporea non dovrebbe esserci == 36 e == 40 invece del semplice = ?. Inoltre non capisco il senso del codice. Sbaglio o non dovrebbe dare nessun output?
Nell’esempio dei 25 gradi invece, io mi aspetterei (non notando l’uso dell’=) che l’output fosse “Non ci sono zero gradi ma 25 gradi”. Sbaglio?
19 Aprile 2011
Ignazioccacchiarola..ho capito il problema..non sono io che sono rinco quando scrivo i codice..ma è wordpress che elimina i segni di “”…devo scriverli nel codice con < e > se voglio che non vengano cancellati…porca miseria mi dispiace un sacco!!
Nell’esempio dei gradi invece l’output è proprio “non ci sono zero gradi ma 0 gradi” perché al posto dell’ == è stato utilizzato (errore voluto) un solo =
20 Aprile 2011
Gran GiullareScusa non mi sono spiegato.
Nel testo tu dici: Leggendo il codice precedente potremmo pensare che l’output di questo codice sia “Freddissimo! ci sono 25 gradi”
Ma in realtà chi non si accorge dell’errore si aspetta “Non ci sono zero gradi ma 25 gradi”. Come dici tu la temperatura è inizializzata a 25 e quindi quando viene confrontato con 0 il risultato è “false”… o sono rinco? Scusami ma sono alle prime armi. 😉
20 Aprile 2011
IgnaziocIl problema è proprio che non viene effettuato nessun confronto con il valore 0, quella è una assegnazione, non un confronto. e poiché l’assegnazione restituisce il valore assegnato quell’assegnazione restituisce 0, che per il C equivale al falso.
Lo so che è un ragionamento un pò difficile, ma il succo della questione è “attenzione ad utilizzare sempre == quanto volete confrontare un valore”.
ps: c’è una sezione del forum apposta, ne possiamo parlare lì.
28 Aprile 2011
LeoNel terzo codice di esempio credo manchi un “else {“…
Altrimenti l’ultima parentesi è di troppo!
Comunque complimenti per il corso! Davvero ben fatto.
16 Agosto 2011
Osv94Una domanda, ho copiato il codice:
int anni = 42;
if (anni < 100 ) {
printf("Hei, sei ancora un giovanotto!\n");
}
else {
printf("Quanto spendi in candeline??\n");
}
quando vado a compilarlo, però, sul prompt dei comandi esce scritto: error: expected identifier or "(" before "if"
error: expected identifier or "(" before "else".
Come mai?
16 Agosto 2011
Ignaziocposta tutto il contenuto del programma che vediamo.
23 Settembre 2011
FrancescoBuonasera a tutti!
qualcuno potrebbe suggerirmi dove sbaglio scrivendo il codice del programmino sulla temperatura corporea?Lo posto di seguito:
include
int main(int argc,int **argv)
{
int temperatura = 38;
if (temperatura = 36) && (temperatura = 37 ) && (temperatura 40) {
printf(“Hai la febbre alta, chiama un medico!”);
}
return 0;
}
sul compilatore mi segnala il seguente errore:
ifelseif.c:1:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘
<' token
l'errore è uguale sia che usi == o =…
grazie mille!
23 Settembre 2011
Francescoinclude
int main(int argc,int **argv)
{
int temperatura = 38;
if (temperatura = 36) && (temperatura = 37 ) && (temperatura 40) {
printf(“Hai la febbre alta, chiama un medico!”);
}
return 0;
}
QUESTO è tutto il codice!
24 Settembre 2011
Ignazioi confronti si fanno con ” == ” e non con ” = ” inoltre nell’ultimo non hai messo proprio nulla hai scritto (temperatura 40)