3 LE STRUTTURE DI CONTROLLO

3 LE STRUTTURE DI CONTROLLO

Come effettuare una scelta

Alcuni problemi possono essere risolti utilizzando un approccio sequenziale, in cui le istruzioni da eseguire vengono elencate una dopo l’altra all’interno del codice sorgente e, al momento dell’esecuzione del programma, vengono eseguite nello stesso ordine.

Molto spesso, però, l’approccio sequenziale non è sufficiente per risolvere un problema.

esempio

Lancia un dado. Se esce 6, allora hai vinto!

L’algoritmo che risolve questo problema deve valutare una condizione ponendosi la domanda “È uscito 6?” e, in base alla risposta, può dichiarare che cosa sia successo. Se vogliamo rappresentare il diagramma a blocchi dobbiamo scriverlo come nella figura a lato.

La disposizione dei blocchi introdotta nell’esempio precedente prende il nome di struttura di selezione, indicata anche come “se… allora… altrimenti…” o in inglese “if… then… else…”, o più brevemente se (o if).


La struttura di selezione consente di fare una scelta tra due possibili alternative inserendo una condizione di tipo booleano all’interno del blocco di scelta. Nel diagramma deve essere indicato come comportarsi in entrambi i casi, in fase di simulazione il valore di verità della condizione consente di scegliere e percorrere solo una delle due strade possibili.


LINGUAGGIO C
La sintassi dell’istruzione if è la seguente:
if(condizione)
{
blocco da eseguire
quando la condizione è VERA;
}
else
{
blocco da eseguire
quando la condizione è FALSA;
}
esempio

Data la massa m (in g) e il volume V (in cm3di un oggetto, calcoliamone la densità (d = m : V) e stabiliamo se può trattarsi di vetro (d = 2,5 g/cm3).
Scriviamo il diagramma a blocchi.

LINGUAGGIO C
La traduzione del diagramma a blocchi è:
#include <stdio.h>
int main()
{
float m, V, d;
printf("Inserisci la massa");
scanf("%f",&m);
printf("Inserisci il volume ");
scanf("%f",&V);
d = m/V;
if (d == 2.5)
{printf("Vetro");}
else
{printf("Altro");}
return 0;
}

Con il diagramma a blocchi è possibile indicare chiaramente il punto dell’algoritmo in cui avviene la valutazione della condizione e la conseguente biforcazione dello schema. Disegnando i due rami alternativi è possibile evidenziare facilmente quali istruzioni devono essere eseguite nei due diversi casi.


I linguaggi di programmazione come il C, invece, gestiscono la biforcazione effettuando dei salti nel codice. Al momento dell’esecuzione del programma se la condizione scritta all’interno delle parentesi tonde risulta essere vera, allora viene eseguito il primo blocco di istruzioni e il secondo blocco viene saltato. Se invece la condizione risulta essere falsa, allora viene eseguito il secondo blocco di istruzioni e il primo blocco viene saltato.

  ApprofondiMENTO
INDENTAZIONE E ANNIDAMENTO

Se le istruzioni vengono scritte come un elenco, il codice può risultare difficile da leggere “a colpo d’occhio”.

La leggibilità può essere migliorata usando l’indentazione, cioè inserendo nel codice dei rientri che evidenzino visivamente sia i blocchi logici contenuti nei programmi, sia l’eventuale presenza di ▶ annidamento, cioè di sotto-blocchi inseriti dentro ad altri blocchi di istruzioni. Per questi rientri (ininfluenti per il computer, ma utili al programmatore) si può scegliere qualunque stile che, però, deve essere mantenuto coerente in tutto il codice.

 >> pagina 405 

Lo “spaghetti code”

Alcuni problemi possono essere risolti in modo sequenziale.

Per esempio il problema “prepara il caffè usando la caffettiera” potrebbe essere risolto dalla sequenza di istruzioni contenute nell’algoritmo seguente.



Tuttavia, non appena il problema si complica, l’algoritmo per essere risolto potrebbe diventare piuttosto complesso e contorto.


I linguaggi di programmazione, incluso il linguaggio C, supportano la traduzione di algoritmi, come il precedente, in cui sono presenti diverse diramazioni fornendo le istruzioni di salto che possono essere di due tipi:

1. salto condizionato: eseguito o no in base che al verificarsi o meno una determinata condizione (per esempio l’istruzione if);

2. salto incondizionato: che viene eseguito comunque, essendo privo di condizione. All’interno del codice vengono inserite delle ▶ etichette, come per esempio inizio: e fine:, e un’istruzione ▶ goto, durante l’esecuzione, permette di saltare direttamente alla posizione indicata dall’etichetta.



Il codice sorgente dei programmi che contengono salti incondizionati viene definito, in modo dispregiativo, spaghetti code, facendo riferimento all’assenza di struttura che si trova in un piatto di spaghetti: un mucchio di fili (logici) intrecciati e annodati tra loro.

Lo spaghetti code, in generale, risulta difficilmente leggibile e impedisce di avere una buona percezione del susseguirsi delle istruzioni che risolvono il problema. Lo scarso controllo sulla logica risolutiva può introdurre nell’algoritmo una serie di errori logici difficili da individuare.


Negli anni Sessanta la struttura di controllo del salto incondizionato (goto) era molto diffusa. In contrapposizione a questa tendenza, nello stesso periodo, si affermò il paradigma (cioè un modello al quale fare riferimento come termine di paragone) della programmazione strutturata, che ha come obiettivo quello di migliorare la leggibilità e la qualità del codice sorgente, oltre che semplificarne la manutenzione.


Oltre ad abolire i salti incondizionati (estremamente deprecati), la programmazione strutturata stabilisce che il programma deve essere costruito utilizzando solo le strutture di controllo fondamentali, che possono anche essere composte fra di loro nel rispetto di alcune regole prestabilite.

Lo sapevi che

Il termine programmazione strutturata venne introdotto dall’informatico olandese Edsger W. Dijkstra il quale affermò, in un documento del 1968, che l’istruzione goto presente in molti linguaggi di programmazione ad alto livello è una delle principali fonti di errori di tipo logico.

 >> pagina 407 

Il teorema di Böhm-Jacopini

Il paradigma della programmazione strutturata si affermò a partire dagli anni Sessanta grazie al contributo dei due matematici e informatici italiani Corrado Böhm (1923 - 2017) e Giuseppe Jacopini (1936 - 2001) che dimostrarono, con il loro teorema (divenuto fondamentale per la programmazione), che qualsiasi programma contenente dei goto può essere riscritto utilizzando solo tre strutture di controllo fondamentali.


Il teorema di Böhm-Jacopini afferma che qualsiasi algoritmo può essere scritto utilizzando e combinando fra loro solo tre strutture di controllo:

1. sequenza;

2. selezione;

3. iterazione.


Si chiamano strutture di controllo perché servono a controllare il percorso all’interno del procedimento risolutivo, per ottenere i risultati desiderati.

Le prime due strutture sono già state introdotte nei paragrafi precedenti; ora formalizziamo i concetti che le riguardano.

 >> pagina 408 

1 la sequenza

La struttura sequenza è la più semplice e indica l’ordine in cui devono essere eseguite le istruzioni.

Le istruzioni contenute nel blocco possono essere di varia natura: assegnazioni, input, output, istruzioni di selezione, istruzioni di iterazione o combinazioni di queste.


esempio

Data la base e l’altezza, calcolare l’area del triangolo.

2 La selezione

La selezione è la struttura di controllo che consente di fare una scelta tra due possibili alternative. Per decidere come proseguire nel percorso dell’algoritmo, occorre determinare il valore di verità della condizione contenuta nel blocco di scelta. Se è vera, vengono eseguite le istruzioni del ramo vero; viceversa, se è falsa, vengono eseguite quelle del ramo falso.


Se viene eseguito il blocco di istruzioni A, allora non vengono eseguite quelle del blocco B, che si trovano sull’altro ramo, e viceversa. Le due opzioni sono in alternativa poi il diagramma si ricongiunge e prosegue verso il basso.

Solitamente il ramo vero viene disegnato sulla sinistra e quello falso sulla destra, ma nei diagrammi a blocchi è consentita anche l’eventuale inversione, di vero e falso e dei relativi blocchi. Inoltre uno dei due rami, di solito il ramo falso, può non contenere istruzioni.


esempio
Dati due numeri, visualizzare quello più piccolo.

 >> pagina 409 

3 L’iterazione

L’iterazione (o ▶ ciclo), è la ripetizione di un blocco di istruzioni che termina in base al valore di verità della condizione scritta nel blocco di scelta.

Nei diagrammi a blocchi sono valide entrambe le seguenti possibilità.



Questa struttura può essere considerata la forma più generica di iterazione:

  • può essere utilizzata sia nel caso in cui il numero di iterazioni nel ciclo sia conosciuto a priori, sia quando non è noto quante volte verranno eseguite le istruzioni contenute all’interno del ciclo;
  • il blocco contenuto nel ciclo, potrebbe anche non essere mai eseguito nel caso in cui la condizione verificasse immediatamente l’uscita dal ciclo.
LINGUAGGIO C
Il linguaggio C richede che il ramo vero sia sempre interno al loop.
In fase di esecuzione, l’istruzione while esamina la condizione e, mentre si mantiene vera, esegue le istruzioni contenute nel ciclo.
Se la condizione diventa falsa, il ciclo termina. Se invece risulta immediatamente falsa, le istruzioni nel ciclo non vengono mai eseguite.
La sintassi del while è:
while(condizione)
{
blocco da eseguire mentre
la condizione è VERA;
}
esempio

Data in input una sequenza di numeri interi che termina quando viene immesso il valore 0, calcoliamo quanti numeri sono positivi e quanti negativi, visualizzando i risultati ottenuti.

LINGUAGGIO C

#include <stdio.h>

int main() 

int N, POS, NEG; 

printf("Inserisci un numero "); 

scanf("%d",&N); 

POS = 0; 

NEG = 0; 

while (N != 0) // in C "diverso" si scrive != 

if (N>0) 

              {POS = POS + 1;} 

else 

              {NEG = NEG + 1;} 

printf("Inserisci un numero "); 

scanf("%d",&N); 

printf("positivi = %d, negativi = %d", POS, NEG); 

return 0; 

}

  prova tu

Scrivi il diagramma a blocchi.


  • Facendo riferimento al diagramma a blocchi dell’esempio e utilizzando l’input seguente, fai una simulazione dell’algoritmo seguendo il diagramma e modificando il valore delle variabili.
    I: 1 - 7 6 18 -3 2 0

 >> pagina 411 

I sottoprogrammi

I programmi che risolvono problemi nel mondo reale sono generalmente molto complessi e quindi, per essere realizzati, vengono scomposti in più sottoprogrammi, collegati logicamente fra loro e richiamati da un programma principale. Il problema viene suddiviso in sottoproblemi che vengono analizzati separatamente utilizzando una tecnica di analisi e di raffinamento successivo che prende il nome di metodo ▶ top-down.


Nella programmazione un sottoprogramma è una sequenza di istruzioni che esegue un compito specifico e può essere utilizzata nei programmi, anche più volte, ovunque occorra eseguire quel particolare compito.


esempio

Usare i sottoprogrammi introduce due principali vantaggi:

1. sintesi: lo stesso codice non viene riscritto più volte nel programma, viene solo richiamato ogni volta che occorre (riuso del codice). Il programma diventa più compatto e leggibile. La manutenzione del codice diventa più facile e i costi si riducono;

2. semplicità: suddividendo il problema in sottoproblemi, sviluppare il codice diventa più semplice e meno costoso, si riducono le possibilità di introdurre errori e la qualità del software migliora.


In generale nei sottoprogrammi possono essere definite delle variabili locali, cioè delle variabili che possono essere viste solo dal sottoprogramma. Le variabili visibili da tutti i sottoprogrammi e dal programma principale prendono il nome di variabili globali.

LINGUAGGIO C
I sottoprogrammi vengono implementati dalle funzioni.
Lo sapevi che

Il metodo top-down individua le problematiche più complesse e le suddivide via via in sottoproblemi più semplici. L’approccio top-down è opposto al metodo ▶ bottom-upche partendo dal basso procede verso l’alto.

Clic!
Clic!
Tecnologie informatiche per il primo biennio