Blocchi IF Innestati in Fortran

I blocchi IF innestati in Fortran permettono di inserire un blocco IF all'interno di un altro, creando logiche decisionali più complesse.

Tuttavia, senza una gestione adeguata, possono rendere il codice difficile da leggere e manutenere. In questa lezione vediamo come annidare correttamente i blocchi IF, i vantaggi di assegnare nomi ai costrutti e come evitare errori comuni nella gestione del flusso di controllo.

Blocchi IF innestati

Un Blocco IF in Fortran è molto flessibile. Deve contenere almeno:

  • Un'istruzione IF (...) THEN
  • Un'istruzione END IF

Tra queste istruzioni, esso può includere un numero qualsiasi di clausole ELSE IF e, opzionalmente, una clausola ELSE.

Grazie a questa combinazione, è possibile implementare qualsiasi logica di controllo del flusso.

I blocchi IF possono essere annidati all'interno di altri blocchi IF.

Si parla di IF innestati quando un blocco IF è completamente contenuto all'interno del blocco di un'altro IF.

Esempio di blocchi IF innestati correttamente:

outer: IF (x > 0.) THEN
    ...
    inner: IF (y < 0.) THEN
        ...
    END IF inner
    ...
END IF outer

In questo caso:

  • L'IF interno (inner) è completamente contenuto nel blocco dell'IF esterno (outer).
  • Il codice è più leggibile grazie all'uso di nomi per i blocchi IF.

Blocchi IF Annidati Senza Nome e con Nome

Nella lezione precedente abbiamo visto che i blocchi IF possono avere un'etichetta per migliorare la leggibilità del codice. Il vantaggio di usare un'etichetta diventa altrettanto importante quando si annidano blocchi IF.

Quando si usano blocchi IF annidati, assegnare un nome aiuta a:

  • Identificare chiaramente a quale IF appartiene un END IF.
  • Evitare errori di annidamento, specialmente nei programmi lunghi.
  • Rendere il codice più leggibile, chiarendo la struttura logica del programma.

Esempio di codice problematico senza nomi:

PROGRAM complesso
    ...
    IF (test1) THEN
        ...
        IF (test2) THEN
            ...
            IF (test3) THEN
                ...
            END IF
            ...
        END IF
        ...
    END IF
END PROGRAM complesso

Questo programma, sebbene correttamente valido, presenta alcuni problemi.

Infatti, se il primo END IF viene accidentalmente cancellato, il compilatore:

  • Associerà automaticamente END IF al blocco IF più interno (test3).
  • Associerà il secondo END IF a test2.
  • Alla fine del programma, rileverà che test1 non è stato chiuso, generando un errore di compilazione.

Tuttavia, il compilatore non sarà in grado di indicare dove manca l'END IF, costringendo il programmatore a cercare l'errore manualmente.

La soluzione è proprio quella di adoperare delle etichette per i blocchi IF.

Assegnando un nome a ciascun blocco, l'errore diventa immediatamente visibile:

PROGRAM complesso
    ...
    esterno: IF (test1) THEN
        ...
        centrale: IF (test2) THEN
            ...
            interno: IF (test3) THEN
                ...
            END IF interno
            ...
        END IF centrale
        ...
    END IF esterno
END PROGRAM complesso

Se ora un END IF viene accidentalmente cancellato, il compilatore:

  • Indicherà esattamente quale blocco IF non è stato chiuso.
  • Genererà un errore specifico associato al blocco mancante.
  • Permetterà di correggere il problema più rapidamente.

Clausole ELSE IF o IF Annidati?

In alcuni casi, è possibile implementare un algoritmo sia con clausole ELSE IF sia con IF annidati.

La scelta dipende dallo stile di programmazione e dalla leggibilità del codice.

L'uso di blocchi IF innestati è essenziale nei programmi complessi per organizzare il flusso di esecuzione in modo chiaro e strutturato.

Consiglio

Preferire Clausole ELSE IF rispetto a Blocchi IF Annidati

Per i casi in cui ci sono molte scelte mutualmente esclusive tra di loro, è preferibile utilizzare clausole ELSE IF per mantenere il codice più leggibile, anziché annidare molti blocchi IF.

Esempio Pratico

Supponiamo di voler scrivere un programma che legge un voto numerico e gli assegna un voto letterale in base alla seguente tabella:

Intervallo del voto Voto letterale
95 < VOTO A
86 < VOTO ≤ 95 B
76 < VOTO ≤ 86 C
66 < VOTO ≤ 76 D
0 < VOTO ≤ 66 F
Tabella 1: Tabella di traduzione dei voti numerici in lettere

Possiamo realizzare il programma di sopra utilizzando due metodi:

  • (a) Clausole ELSE IF
  • (b) Costrutti IF annidati

Nel primo caso utilizziamo le clausole ELSE IF per valutare ciascuna condizione in modo sequenziale:

! Soluzione (a)
IF ( voto > 95.0 ) THEN
    WRITE (*,*) 'Il voto è A.'
ELSE IF ( voto > 86.0 ) THEN
    WRITE (*,*) 'Il voto è B.'
ELSE IF ( voto > 76.0 ) THEN
    WRITE (*,*) 'Il voto è C.'
ELSE IF ( voto > 66.0 ) THEN
    WRITE (*,*) 'Il voto è D.'
ELSE
    WRITE (*,*) 'Il voto è F.'
END IF

Nel secondo caso, utilizziamo costrutti IF annidati per valutare ciascuna condizione in modo gerarchico:

if1: IF ( voto > 95.0 ) THEN
    WRITE (*,*) 'il voto è A.'
ELSE
    if2: IF ( voto > 86.0 ) THEN
        WRITE (*,*) 'il voto è B.'
    ELSE
        if3: IF ( voto > 76.0 ) THEN
            WRITE (*,*) 'il voto è C.'
        ELSE
            if4: IF ( voto > 66.0 ) THEN
                WRITE (*,*) 'il voto è D.'
            ELSE
                WRITE (*,*) 'il voto è F.'
            END IF if4
        END IF if3
    END IF if2
END IF if1

Dall'esempio sopra risulta chiaro che, se ci sono molte opzioni mutuamente esclusive, un costrutto IF con clausole ELSE IF sarà più semplice e leggibile rispetto a un IF annidato.

In Sintesi

In questa lezione abbiamo studiato che:

  • I blocchi IF possono essere annidati, ossia contenuti all'interno di un altro blocco IF, permettendo logiche decisionali più articolate.
  • L'uso di nomi per i blocchi IF aiuta a mantenere il codice leggibile, indicando chiaramente a quale END IF ciascun blocco appartiene.
  • Senza nomi, il compilatore associa automaticamente END IF all'IF più vicino, il che può causare errori difficili da individuare.
  • In caso di errore, i blocchi IF con nomi permettono al compilatore di indicare esattamente quale parte del codice è incompleta o errata.
  • Nei programmi complessi, assegnare un nome ai blocchi IF facilita la navigazione del codice, evitando confusione nei costrutti lunghi e nidificati.
  • È possibile scegliere tra clausole ELSE IF e blocchi IF annidati, a seconda della leggibilità e della struttura desiderata nel codice.