Istruzione SELECT CASE in Fortran
L'istruzione SELECT CASE in Fortran è un'alternativa chiara e strutturata ai blocchi IF-ELSE IF
, permettendo di eseguire diversi blocchi di codice in base al valore di un'espressione intera, carattere o logica.
Questo costrutto migliora la leggibilità e la manutenzione del codice, specialmente quando ci sono molte condizioni esclusive. In questa lezione vediamo la sintassi di SELECT CASE
, il suo funzionamento e alcuni esempi pratici per comprendere l'importanza dell'uso di CASE DEFAULT
.
L'istruzione SELECT CASE
L'istruzione SELECT CASE
è una forma alternativa di controllo del flusso in Fortran.
Essa permette di eseguire un blocco di codice specifico in base al valore di un'espressione numerica, carattere o logica.
La forma generale dell'istruzione CASE
è:
[nome:] SELECT CASE (espressione)
CASE (selettore_1) [nome]
Istruzione 1
Istruzione 2
...
CASE (selettore_2) [nome]
Istruzione 1
Istruzione 2
...
CASE DEFAULT [nome]
Istruzione 1
Istruzione 2
...
END SELECT [nome]
- Se il valore di
espressione
corrisponde a un intervallo specificato inselettore_1
, viene eseguito Blocco 1. - Se il valore rientra in
selettore_2
, viene eseguito Blocco 2. - Il blocco
CASE DEFAULT
viene eseguito seespressione
non corrisponde a nessun caso precedente. - Il blocco
DEFAULT
è opzionale, ma è consigliabile usarlo per gestire eventuali input non previsti.
Il diagramma di flusso dell'istruzione SELECT CASE
è mostrato nella figura seguente:
È possibile assegnare un nome a un'istruzione CASE
:
- Deve essere univoco all'interno dell'unità di programma.
- Se un nome viene assegnato a
SELECT CASE
, lo stesso deve apparire nell'END SELECT
. - L'uso dei nomi è opzionale per i singoli
CASE
, ma se presenti devono corrispondere a quello dell'END SELECT
.
Per quanto riguarda l'espressione, essa deve rispettare le seguenti regole:
espressione
può essere un numero intero, un carattere o un valore logico.- I selettori
CASE
devono essere mutuamente esclusivi, cioè un valore non può rientrare in più di un caso. - I selettori possono essere specificati come valori singoli, intervalli o liste di valori.
Per chiarire meglio come funziona l'istruzione SELECT CASE
studiamo qualche esempio.
Esempio: Controllo della Temperatura
Vediamo un esempio di istruzione CASE
che stampa un messaggio in base al valore di una temperatura espressa in gradi Celsius:
INTEGER :: temp_c ! Temperatura in gradi Celsius
...
temp: SELECT CASE (temp_c)
CASE (: -1)
! Questo caso gestisce temperature sotto lo zero
! ossia da -1 in giù
WRITE (*,*) "Oggi si congela!"
CASE (0)
! Temperatura esattamente a zero
WRITE (*,*) "Oggi siamo esattamente al punto di congelamento."
CASE (1:20)
! Temperatura tra 1 e 20 gradi
WRITE (*,*) "Oggi fa fresco."
CASE (21:33)
! Temperatura tra 21 e 33 gradi
WRITE (*,*) "Oggi fa caldo."
CASE (34:)
! Temperature superiori a 34 gradi
WRITE (*,*) "Oggi fa molto caldo!"
END SELECT temp
Esaminiamo il codice sopra:
- Il valore di
temp_c
determina quale caso viene selezionato. - Se la temperatura è minore di 0, viene stampato
"Oggi si congela!"
. - Se è 0, viene stampato
"Oggi siamo esattamente al punto di congelamento."
. - Se è tra 1 e 20, viene stampato
"Oggi fa fresco."
. - Se è tra 21 e 33, viene stampato
"Oggi fa caldo."
. - Se è maggiore di 34, viene stampato
"Oggi fa molto caldo!"
.
Da notare che abbiamo espresso i singoli casi sia come valori singoli che come intervalli.
Formati Accettati per i Selettori CASE
Dopo aver esaminato l'esempio di sopra, è importante notare che i selettori CASE
possono assumere diverse forme.
Un selettore può assumere cinque forme. Le prime quattro sono le seguenti:
valore
: Esegue il blocco seespressione == valore
valore_minimo:
: Esegue il blocco sevalore_minimo <= espressione
:valore_massimo
: Esegue il blocco seespressione <= valore_massimo
valore_minimo:valore_massimo
: Esegue il blocco sevalore_minimo <= espressione <= valore_massimo
L'ultima forma è una lista di valori separati da virgole:
valore_1, valore_2, ..., valore_n
: Esegue il blocco seespressione == valore_1
oespressione == valore_2
o ... oespressione == valore_n
Esempio: Numeri Pari e Dispari
Analizziamo un altro esempio per comprendere meglio l'istruzione SELECT CASE
.
Vogliamo realizzare un programma che determini se un numero intero compreso tra 1 e 10 è pari o dispari:
INTEGER :: value
...
SELECT CASE (value)
CASE (1,3,5,7,9)
! Caso 1: Lista dei numeri dispari
WRITE (*,*) 'Il valore è dispari.'
CASE (2,4,6,8,10)
! Caso 2: Lista dei numeri pari
WRITE (*,*) 'Il valore è pari.'
CASE (11:)
! Caso 3: Valore troppo alto
WRITE (*,*) 'Il valore è troppo alto.'
CASE DEFAULT
! Caso 4: Valore pari a zero o negativo
WRITE (*,*) 'Il valore è zero o negativo.'
END SELECT
In questo caso abbiamo adoperato il caso di default, CASE DEFAULT
, per gestire tutti i valori non previsti. In particolare, se value
è maggiore di 10, viene stampato "Il valore è troppo alto."
, mentre se è zero o negativo, viene stampato "Il valore è zero o negativo."
.
Includere sempre il blocco CASE DEFAULT
nelle istruzioni SELECT CASE
Includiamo sempre un blocco CASE DEFAULT
nelle istruzioni SELECT CASE
per gestire errori logici o input non validi.
L'istruzione SELECT CASE è un'alternativa strutturata e leggibile agli IF
annidati, ideale quando si hanno molte opzioni esclusive.
Esempio: Selezione del Giorno della Settimana
Scriviamo un programma che legge un numero intero dalla tastiera e visualizza il giorno della settimana corrispondente.
Il programma deve gestire anche il caso in cui l'utente inserisca un valore non valido.
In questo esempio:
- Chiediamo all'utente di inserire un numero intero tra 1 e 7.
- Usiamo un'istruzione SELECT CASE per assegnare il giorno della settimana corrispondente, considerando lunedì come il primo giorno della settimana.
- Aggiungiamo un
CASE DEFAULT
per gestire input non validi.
Il programma risultante è mostrato di seguito.
PROGRAM giorno_settimana
!
! Scopo:
! Questo programma mostra il giorno della settimana
! corrispondente a un valore intero inserito dall'utente.
!
IMPLICIT NONE
! Dizionario dei dati: dichiarazione delle variabili
CHARACTER(len=17) :: c_giorno ! Stringa contenente il nome del giorno
INTEGER :: i_giorno ! Numero intero del giorno della settimana
! Chiediamo all'utente di inserire un numero da 1 a 7
WRITE (*,*) 'Inserisci il numero del giorno della settimana (1-7): '
READ (*,*) i_day
! Selezioniamo il giorno corrispondente
SELECT CASE (i_giorno)
CASE (1)
c_giorno = 'Lunedì'
CASE (2)
c_giorno = 'Martedì'
CASE (3)
c_giorno = 'Mercoledì'
CASE (4)
c_giorno = 'Giovedì'
CASE (5)
c_giorno = 'Venerdì'
CASE (6)
c_giorno = 'Sabato'
CASE (7)
c_giorno = 'Domenica'
CASE DEFAULT
c_giorno = 'Giorno non valido'
END SELECT
! Visualizziamo il giorno corrispondente
WRITE (*,*) 'Giorno = ', c_giorno
END PROGRAM day_of_week
Se il programma viene compilato ed eseguito con diversi valori di input, otteniamo:
$ ./giorno_settimana
Inserisci il numero del giorno della settimana (1-7): 1
Giorno = Lunedì
$ ./giorno_settimana
Inserisci il numero del giorno della settimana (1-7): 4
Giorno = Giovedì
$ ./giorno_settimana
Inserisci il numero del giorno della settimana (1-7): 8
Giorno = Giorno non valido
In questo esempio:
- Il programma fornisce i giorni corretti per i valori validi da 1 a 7.
- Se l'utente inserisce un numero fuori intervallo, viene restituito il messaggio
"Giorno non valido"
grazie alCASE DEFAULT
. - L'uso dell'istruzione SELECT CASE rende il codice più leggibile rispetto a un blocco
IF-ELSE IF
. - Quando abbiamo dichiarato la variabile
c_giorno
abbiamo impostato come lunghezza massima 17 caratteri, in modo da poter il risultato più lungo possibile, ovvero"Giorno non valido"
.
Esempio: Determinare se un giorno è feriale o festivo
Scriviamo un programma che legge il nome di un giorno della settimana dalla tastiera e visualizza se è un giorno feriale ("Feriale"
) o un giorno festivo ("Festivo"
).
Il programma deve gestire anche l'eventualità in cui venga inserito un valore non valido.
In questo esempio:
- L'utente inserisce il nome di un giorno della settimana.
- L'istruzione SELECT CASE verifica se il giorno è feriale o festivo.
- Aggiungiamo un
CASE DEFAULT
per gestire input non validi.
Il programma risultante è mostrato di seguito.
PROGRAM feriale_festivo
!
! Scopo:
! Questo programma accetta una stringa con il nome di un giorno della settimana
! e risponde con un messaggio che indica se è un giorno feriale o festivo.
!
IMPLICIT NONE
! Dichiarazione delle variabili usate nel programma
CHARACTER(len=9) :: giorno ! Stringa contenente il nome del giorno
CHARACTER(len=17) :: tipo_giorno ! Stringa contenente il tipo di giorno
! Chiediamo all'utente di inserire un giorno della settimana
WRITE (*,*) 'Inserisci il nome del giorno: '
READ (*,*) giorno
! Determiniamo se il giorno è feriale o festivo
SELECT CASE (giorno)
CASE ('Lunedì','Martedì','Mercoledì','Giovedì','Venerdì')
tipo_giorno = 'Feriale'
CASE ('Sabato','Domenica')
tipo_giorno = 'Festivo'
CASE DEFAULT
tipo_giorno = 'Giorno non valido'
END SELECT
! Visualizziamo il risultato
WRITE (*,*) 'Tipo di giorno = ', tipo_giorno
END PROGRAM feriale_festivo
Se il programma viene compilato ed eseguito con diversi valori di input, otteniamo:
$ ./feriale_festivo
Inserisci il nome del giorno: Lunedì
Tipo di giorno = Feriale
$ ./feriale_festivo
Inserisci il nome del giorno: Domenica
Tipo di giorno = Festivo
$ ./feriale_festivo
Inserisci il nome del giorno: Festività
Tipo di giorno = Giorno non valido
Notiamo che:
- Il programma assegna correttamente la categoria
"Feriale"
ai giorni da lunedì a venerdì. - I giorni sabato e domenica sono classificati come
"Festivo"
. - Se l'utente inserisce un nome non valido, il programma risponde con
"Giorno non valido"
grazie all'uso diCASE DEFAULT
. - L'uso dell'istruzione SELECT CASE semplifica la gestione delle stringhe rispetto a un blocco
IF-ELSE IF
.
In Sintesi
In questa lezione abbiamo studiato che:
- L'istruzione
SELECT CASE
permette di eseguire blocchi di codice basati sul valore di un'espressione, migliorando la leggibilità rispetto aIF-ELSE IF
. - Il valore valutato (
espressione
) può essere un numero intero, un carattere, un valore logico oppure un'intera espressione e viene confrontato con i selettoriCASE
. - I selettori CASE devono essere mutuamente esclusivi, per evitare sovrapposizioni di condizioni.
- Il blocco
CASE DEFAULT
è essenziale per gestire valori non previsti, evitando errori logici nel programma. - I selettori CASE possono assumere diverse forme, come valori singoli, intervalli (
low:high
) o liste di valori separati da virgole. - Gli esempi pratici mostrano l'uso di
SELECT CASE
per categorizzare la temperatura e determinare se un numero è pari o dispari. - Usare
SELECT CASE
rende il codice più leggibile e strutturato, particolarmente utile quando ci sono molte condizioni esclusive.