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 presentanodue sole possibilità alternative. Quando lealternative siano più di due, si è costretti autilizzare più istruzioni if nidificate, ilche può ingarbugliare non poco la struttura logica delcodice e menomarne la leggibilità. 

Quando la condizione da valutare sia esprimibile medianteun'espressione restituente un int o unchar, il C rende disponibile l'istruzioneswitch, che consente di valutare un numero qualsiasidi alternative per il risultato di detta espressione. Diamosubito 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 chelegge il contenuto di un file carattere per carattere edesegue azioni diverse a seconda del carattere letto: inparticolare, la funzione fgetc() legge un caratteredal file associato al descrittore[2] inFile e lorestituisce. Tale carattere è memorizzato nellavariabile 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 dellepossibili alternative definite. Se si tratta del valoredefinito dalla costante manifesta EOF la funzionetermina; se si tratta del carattere definito come LFviene valutato quante righe sono già state scanditeper decidere se terminare o no; se si tratta di unLF o di un BLANK è incrementato uncontatore; i caratteri definiti come CR eNULL (il solito zero binario) vengono semplicementeignorati; qualsiasi altro carattere è copiato in unbuffer il cui puntatore è incrementato diconseguenza. 

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

Tra le parentesi graffe deve essere specificata almeno unacondizione: significa che la switch potrebbe essereseguita anche da una sola case o dalladefault, e che quindi possono esistere delleswitch 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 valeEOF? viene eseguito tutto ciò che segue i duepunti, cioè l'istruzione return. Questaci "catapulta" addirittura fuori dalla funzioneeseguita in quel momento, quindi della switch nonsiparla proprio più... 

Se invece c vale LF, l'esecuzionesalta alla if che segue immediatamente la secondacase. Se la condizione valutata dalla ifè vera... addio funzione; altrimenti l'esecuzioneprosegue con l'istruzione immediatamente successiva.E' molto importante sottolineare che, a differenza diquanto si potrebbe pensare, la presenza di altrecase non arresta l'esecuzione e non producel'uscita dalla switch: viene quindi incrementatala variabile cCount. Solo a questo puntol'istruzione break determina l'uscita dallaswitch

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

E' forse superfluo precisare che le break, senecessario, possono essere più di una e possonodipendere da altre condizioni valutate all'interno di unacase, ad esempio mediante una if. Inoltreuna case può contenere un'interaswitch, nella quale ne può essere annidatauna terza... tutto sta a non perdere il filo logico deicontrolli. 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 laseconda switch, al termine della quale si rientranella prima (e sempre nella parte di codice dipendente dallacase per 0). La prima switch,inoltre, non ha la default: se a non vale0, né 1, né 2l'esecuzione salta direttamente alla prima istruzione chesegue la graffa che la chiude. 

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

 



Ti potrebbe interessare anche

commenta la notizia