L'assenza di un tipo booleano predefinito nel linguaggio può creare dei problemi
di leggibilità del codice, soprattutto per i programmatori alle
prime armi.
Quando occorre utilizzare una variabile come flag booleano, sovente
la si definisce come short int, assegnandole come valore
1 o 0.
Nel migliore dei casi il programmatore utilizza un accorgimento
del tipo:
#define FALSE 0
#define TRUE 1
...
short int test = TRUE;
...
curandosi di assegnare a test sempre TRUE o FALSE
piuttosto che i corrispondenti valori interi.
Comunque, questi identificatori sono già definiti nell'header
standard stdlib.h, che basta includere nei nostri sorgenti
per poter utilizzare tranquillamente TRUE e FALSE.
Nel caso in cui occorre testare il valore di un flag booleano,
si può essere tentati a scrivere un codice del tipo:
if (test == TRUE)
...
Tuttavia è più elegante, ed ha il medesimo significato del precedente,
scrivere:
if (test)
...
Infatti se test è pari a TRUE (ovvero diverso da
0), il blocco di istruzioni dell'if viene parimenti eseguito.
Accanto all'istruzione condizionale if-else esiste un operatore
condizionale, detto anche operatore ternario per via del
fatto che lavora su tre operandi, che può essere considerato come
una sorta di if-else abbreviato.
La sua forma generale è la seguente:
espressione1 ? espressione2
: espressione3
ed equivale a: “Se espressione1 è vera (cioè il suo
valore è diverso da 0), allora il valore restituito dall'operazione
è espressione2 altrimenti il valore restituito è espressione3”.
Ad es. la porzione di codice:
int i;
...
printf(“i e' %s\n”, (i >= 0) ? “positivo”
: “negativo”);
stampa a video la stringa “i e' positivo” se i è maggiore
o uguale a 0, oppure, in caso contrario, la stringa “i e'
negativo”.
L'analogo esempio con if-else:
int i;
...
printf(“i e' ”);
if (i >= 0)
printf(“positivo\n”);
else
printf(“negativo\n”);
è certamente più leggibile; tuttavia spesso si preferisce utilizzare
l'operatore condizionale quando si vuole esprimere con un solo
valore il risultato della scelta tra due situazioni mutuamente
esclusive.
Passiamo adesso ad un’altra importante struttura di controllo,
la cui utilità è innegabile quando ci si trova a dover definire
delle scelte che non sono basate su due sole alternative.
Stiamo parlando del controllo switch, la cui sintassi è
la seguente:
switch (espressione) {
case valore1:
istruzione1;
break;
case valore2:
istruzione2;
break;
.
.
.
case valoreN:
istruzioneN;
break;
case default:
istruzione;
break;
}
Questo costrutto ha lo stesso significato della seguente struttura
if:
if (espressione == valore1)
istruzione1;
else if (espressione == valore2)
istruzione2;
else
…
else if (espressione == valoreN)
istruzioneN;
else istruzione;
L’espressione che segue la parola chiave switch può
essere una qualsiasi espressione C che restituisce un valore intero
o un carattere (dal momento che i caratteri non sono altro che
valori interi particolari); tale valore viene utilizzato come
criterio di selezione delle alternative disponibili.
La parola chiave case può essere seguita da un valore intero,
da costante di tipo carattere o anche da un’espressione
costante (ad es. 2*3), che viene valutata in fase di compilazione,
ma non può essere una variabile; inoltre è indispensabile che
ogni valore (detto anche etichetta o label) sia
differente dagli altri.
Dopo ogni case può essere indicata una sola istruzione
o un blocco di istruzioni, oppure anche l’istruzione
nulla, costituita solo da un ‘;’ o addirittura
non mettendo nulla (nella prossima lezione vedremo un esempio
che ci chiarirà meglio questa soluzione).
Non appena l’esecuzione di un programma incontra l’istruzione
switch, vengono compiuti i seguenti passi:
1) viene innanzitutto valutata l’espressione intera che
segue la parola chiave switch;
2) il valore ottenuto viene via via confrontato con tutti i valori
costanti che seguono la parola chiave case;
3) quando l’uguaglianza è verificata, il programma esegue
tutte le istruzioni che seguono il case corrispondente
e tutti i case seguenti, compresa l’istruzione default;
4) se nessun confronto dà esito positivo, vengono eseguite solo
le istruzioni che seguono la parola chiave default.
Il caso default è facoltativo e viene utilizzato proprio
per individuare un’azione da compiere se nessuna etichetta
eguaglia il valore ottenuto dalla valutazione dell’espressione.
Infine, osserviamo che, a differenza di altri linguaggi, l’esecuzione
parte dal caso corrispondente e termina alla fine della struttura
di controllo.
Se si vuole terminare lo switch dopo l’esecuzione
delle istruzioni relative ad ogni singolo caso, occorre inserire
l’istruzione break.
Torna all'indice Generale del corso di Corso di C con Linux di Software Planet