Barninga Z
a- a+

Il flusso elaborativo: switch

switch

La if gestisce ottimamente quelle situazioni in cui, a seguito della valutazione di una condizione, si presentano due sole possibilità alternative. Quando le alternative siano più di due, si è costretti a utilizzare più istruzioni if nidificate, il che può ingarbugliare non poco la struttura logica del codice e menomarne la leggibilità. 

Quando la condizione da valutare sia esprimibile mediante un'espressione restituente un int o un char, il C rende disponibile l'istruzione switch, che consente di valutare un numero qualsiasi di alternative per il risultato di detta espressione. Diamo subito un'occhiata ad un caso pratico: 

#define EOF   -1
#define LF    10
#define CR    13
#define BLANK ' '
....
    char c;
    long ln = 0L, cCount = 0L;
    ....
    switch(c = fgetc(inFile)) {
        case EOF:
            return;
        case LF:
            if(++ln == MaxLineNum)
                return;
        case BLANK:
            cCount++;
        case NULL:
        case CR:
            break;
        default:
            *ptr++ = c;
    }

Il frammento di codice riportato fa parte di una funzione che legge il contenuto di un file carattere per carattere ed esegue azioni diverse a seconda del carattere letto: in particolare, la funzione fgetc() legge un carattere dal file associato al descrittore[2] inFile e lo restituisce. Tale carattere è memorizzato nella variabile c, dichiarata di tipo char. L'operazione di assegnamento è, in C, un'espressione che restituisce il valore assegnato, pertanto il valore memorizzato nella variabile c è valutato dalla switch, che esegue una delle possibili alternative definite. Se si tratta del valore definito dalla costante manifesta EOF la funzione termina; se si tratta del carattere definito come LF viene valutato quante righe sono già state scandite per decidere se terminare o no; se si tratta di un LF o di un BLANK è incrementato un contatore; i caratteri definiti come CR e NULL (il solito zero binario) vengono semplicemente ignorati; qualsiasi altro carattere è copiato in un buffer il cui puntatore è incrementato di conseguenza. 

E' meglio scendere in maggiori dettagli. Per prima cosa va osservato che l'espressione da valutare deve trovarsi tra parentesi tonde. Inoltre il corpo della switch, cioè l'insieme delle alternative, è racchiuso tra parentesi graffe. Ogni singola alternativa è definita dalla parola chiave case, seguita da una costante (non sono ammesse variabili o espressioni non costanti) intera (o char), a sua volta seguita dai due punti (":"). Tutto ciò che segue i due punti è il codice che viene eseguito qualora l'espressione valutata assuma proprio il valore della costante tra la case e i due punti, fino alla prima istruzione break incontrata (se incontrata!), la quale determina l'uscita dalla switch, cioè un salto alla prima istruzione che segue la graffa chiusa. La parola chiave default seguita dai due punti introduce la sezione di codice da eseguire qualora l'espressione non assuma nessuno dei valori specificati dalle diverse case. Ma non finisce qui. 

Tra le parentesi graffe deve essere specificata almeno una condizione: significa che la switch potrebbe essere seguita anche da una sola case o dalla default, e che quindi possono esistere delle switch prive di default o di case. La default, comunque, se presente è unica. Complicato? Più a parole che nei fatti... 

Torniamo all'esempio: cosa accade se c vale EOF? viene eseguito tutto ciò che segue i due punti, cioè l'istruzione return. Questa ci "catapulta" addirittura fuori dalla funzione eseguita in quel momento, quindi della switch non siparla proprio più... 

Se invece c vale LF, l'esecuzione salta alla if che segue immediatamente la seconda case. Se la condizione valutata dalla if è vera... addio funzione; altrimenti l'esecuzione prosegue con l'istruzione immediatamente successiva. E' molto importante sottolineare che, a differenza di quanto si potrebbe pensare, la presenza di altre case non arresta l'esecuzione e non produce l'uscita dalla switch: viene quindi incrementata la variabile cCount. Solo a questo punto l'istruzione break determina l'uscita dalla switch

L'incremento della cCount è invece la prima istruzione eseguita se c vale BLANK, ed è anche... l'ultima perché subito dopo si incontra la break. Se c vale CR o NULL si incontra immediatamente la break, e quindi si esce subito dalla switch. Da ciò si vede che quando in una switch è necessario trattare due possibili casi in modo identico è sufficiente accodare le due case. Infine, se in c non vi è nessuno dei caratteri esaminati, viene eseguito ciò che segue la default

E' forse superfluo precisare che le break, se necessario, possono essere più di una e possono dipendere da altre condizioni valutate all'interno di una case, ad esempio mediante una if. Inoltre una case può contenere un'intera switch, nella quale ne può essere annidata una terza... tutto sta a non perdere il filo logico dei controlli. Esempio veloce: 

switch(a) {
        case 0:
            switch(b) {
                case 25:
                    ....
                    break;
                case 30:
                case 31:
                    ....
                case 40:
                    ....
                    break;
                default:
                    ....
            }
            ....
            break;
        case 1:
            ....
            break;
        case 2:
            ....
    }

Se a è uguale a 0 viene eseguita la seconda switch, al termine della quale si rientra nella prima (e sempre nella parte di codice dipendente dalla case per 0). La prima switch, inoltre, non ha la default: se a non vale 0, né 1, né 2 l'esecuzione salta direttamente alla prima istruzione che segue la graffa che la chiude. 

I blocchi di istruzioni dipendenti da una case, negli esempi visti, non sono mai compresi tra graffe. In effetti esse non sono necessarie (ma lo sono, ripetiamolo, per aprire e chiudere la switch), però, se presenti, non guastano. In una parola: sono facoltative.

 



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Sara
Hai dubbi su questo articolo?