Corso di C con Linux

Strutture di controllo - Parte II

 

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