edutecnica

Flow chart : diagrammi di flusso

    

Esistono diversi modi per scrivere e rappresentare un algoritmo, un metodo molto diffuso, è quello che utilizza i diagrammi a blocchi anche chiamati flow chart o diagrammi di flusso. La diagrammazione a blocchi è una rappresentazione grafica, di facile interpretazione per chiunque ed è molto efficace perché permette di definire in maniera visuale la struttura di un algoritmo e i suoi costrutti di programmazione.

Vengono utilizzati simboli grafici (chiamati blocchi) che contengono le istruzioni: esistono quattro tipi di blocchi aventi forme geometriche diverse per distinguere le quattro tipologie possibili di operazioni. Un diagramma di flusso che descrive un algoritmo viene disegnato usando esclusivamente questi solo quattro simboli. Le quattro tipologie di blocchi sono:

blocco di inizio/fine: è un blocco di forma ovale, cioè senza spigoli, che viene utilizzato solo come primo e ultimo blocco del diagramma; al suo interno viene scritto "start" oppure "stop"; serve per indicare il punto iniziale e finale dell'algoritmo.

blocco di trasferimento di informazione (comunicazione I/O): è un blocco a forma di parallelogramma che viene utilizzato per comunicare informazioni all'utente o per inserire dati nella procedura, cioè per eseguire operazioni di INPUT e OUTPUT; si usa indifferentemente per input da tastiera ed output a video;

serve dunque per la lettura dati, scrittura risultati, visualizzazione dati intermedi .

blocco di elaborazione: è un blocco di forma rettangolare che viene usato per contenere istruzioni che effettuano trasformazione di dati; operazioni aritmetiche, assegnazioni etc..


serve dunque all'esecuzione di calcoli e all'elaborazione.

blocco di decisionale (condizionale): è un blocco di forma romboidale, al suo interno vengono effettuate operazioni di confronto (test) che si riassumono in domande che possono avere come risultato esclusivamente due valori: true (T) oppure false (F) cioè vero oppure falso.

I blocchi vengono collegati tra di loro nei flow chart con delle linee terminanti con frecce (arco orientato), in modo da indicarne il verso di percorrenza:

In ogni diagramma deve essere presente un solo blocco di inizio e, soprattutto, un solo blocco di terminazione: anche se nel diagramma saranno presenti percorsi alternativi proprio in base ai risultati della istruzione di decisione, tutti i percorsi alternativi devono ricongiungersi prima della fine del diagramma.


Costrutto if

    

Costrutto if è la struttura di alternativa per la selezione, ed è ditato della seguente sintassi:

if(condizione){
   istruzioni-a;
} else{
   istruzioni-b;
}

Se la condizione assume valore logico vero sarà eseguito il blocco di istruzioni-a (o il blocco di istruzioni corrispondenti all'if); nel caso la condizione assume valore logico falso, se è presente il ramo else verrà eseguito il blocco di istruzioni corrispondente (istruzioni-b). Si deve osservare che l'esecuzione di una delle due parti esclude l'altra.

La clausola else è opzionale, in tal caso non esiste un eventuale ramo else da eseguire.

if(condizione){
   istruzioni-a;
}


Costrutto if-else-if

    

E' un'istruzione comune nella programmazione ed è costituito da una serie di if-else-if riuniti a formare una struttura a scala:

if(condizione-a){istruzioni-a;}
else if(condizione-b){istruzioni-b;}
else if(condizione-c){istruzioni-c;}
...
else {istruzioni-n;}

il calcolatore inizia la valutazione delle espressioni condizionali dall'alto verso il basso, esegue la prima istruzione corrispondente al verificarsi di una condizione e abbandona la catena di if. Se non si verifica nessuna condizione viene eseguito l'else finale che ha il significato concettuale di condizione di default. Se non è presente l'else finale, qualora non si sia verificata nessuna delle condizioni non viene intrapresa alcuna azione.


Espressioni condizionali

    

Le espressioni condizionali possono essere facilmente formulate più genericamente con la sintassi

(condizione) ? ramoIf : ramoElse;

Viene dapprima valutata la condizione logica, se è vera viene eseguito il blocco di istruzioni costituito dal ramoIf altrimenti viene eseguito il ramoElse. Ad esempio l'espressione

(a>b) ? max=a : max=b;

determina il massimo tra i valori delle due variabili a e b assegnandolo alla variabile max.

Nelle espressioni condizionali non si è vincolati ad usare espressioni operatori relazionali e logici, è richiesto soltanto che la valutazione dell’espressione condizionale porti soltanto ad un valore uguale a zero (falso) o diverso da zero (vero). Ad.es. nel seguente programma si esegue la divisione fra due interi e si usa un’espressione if per evitare la divisione per zero:

main(){
int a=3, b=2;
if(b) cout<<a/b;
else cout<<"impossibile";
}

Bisogna quindi considerare che l'espressione come if(b) equivale all'espressione if(b!=0) e l'espressione if(!b) equivale a if(b==0).


Costrutto switch

    

Nonostante if-else-if consenta di realizzare dei test multipli è da considerare una struttura poco elegante e di difficile lettura.
L'istruzione ufficiale per eseguire un test multiplo è lo switch. In tal caso il valore di una variabile viene confrontato con una lista di costanti che possono essere di di tipo intero o char, quando si verifica l'uguaglianza si esegue il blocco di istruzioni corrispondenti. Sintassi:

switch(variabile){
   case costante1:istruzioni-1;break;
   case costante2:istruzioni-2; break;
   ...
   case costante-n:istruzioni-n; break;
   default:istruzioni;
}

La parte default è opzionale, se è presente viene eseguita nel caso in cui non si verifichi alcuna corrispondenza. Se non è presente la clausola di default e non ci sono corrispondenze, non viene eseguita alcuna azione. Quando viene trovata una corrispondenza sono esegute le istruzioni associate al case fino all'istruzione break che causa un'uscita forzata dal costrutto. E' bene specificare quanto segue:

1  I test eseguiti nello switch possono verificare solo uguaglianze, a differenza di quelli eseguiti nell'if-else-if che possono verificare condizioni di qualsiasi tipo.
2  Non possono esserci due case con lo stesso valore di costante nello stesso switch. Possono invece avere lo stesso valore due case collocati in due switch diversi.
Un tipico esempio dell'uso di switch lo abbiamo nelle operazioni gestite tramite un bancomat.

char ch;
cout<<"1.prelievo\n";
cout<<"2.lista movimenti\n";
cout<<"3.saldo\n";
cin>>ch;
switch(ch){
   case '1':prelievo();break;
   case '2':lista();break;
   case '3':saldo();break;
   default:cout<<"nessuna opzione selezionata";
}//end switch


Ciclo for

    

Il ciclo for è un costrutto presente in tutti i linguaggi di programmazione procedurale. La sua forma generale è la seguente:

for(inizializzazione; condizione; incremento){
istruzioni;
}



l'inizializzazione è, nella sua forma più semplice un istruzione di assegnamento con la quale il compilatore posiziona il valore iniziale della variabile di controllo del ciclo.
La condizione è una espressione relazionale usata per valutare la variabile di controllo al fine di determinare il momento di uscita dal ciclo; l'esecuzione prosegue fintanto che la condizione è vera, mentre quando diviene falsa l'esecuzione del programma continua dall'istruzione successiva al for.
L'incremento definisce il modo in cui la variabile di controllo cambia il suo valore ad ogni ripetizione del ciclo. Queste tre parti devono essere separate da un punto e virgola. le istruzioni da eseguire in modo iterativo possono anche essere più di una.
In presenza di più istruzioni è necessario racchiuderle tra una coppia di parentesi graffe. Negli esempi seguenti i è la variabile di controllo (sempre di tipo int).

l'esempio seguente scrive i numeri dall' 1 al 10 sullo schermo:

int i;
for(i=1;i<=10;i++) cout<<i;

il programma pone la variabile i a 1 chiama l'istruzione cout fino a quando i rimane minore o uguale a 10; questa operazione si ripete sino a quando i non diventa maggiore di 10, momento in cui il ciclo ha fine.In questo caso le parentesi graffe non sono indispensabili in quanto il corpo del ciclo è costituito da un unica istruzione.

int x;
for(int i=0;i<10;i++) {
   cout<<"inserisci un numero:";
   cin>>x;
}


Uscita prematura da un ciclo for

      

Le considerazioni precedenti non implicano che un dato ciclo debba eseguire necessariamente le sue n iterazioni previste, questo perchè l'istruzione break ne provoca la terminazione forzata

char ch;
for(int i=0;i<10;i++) {
   cout<<"inserisci una lettera:";
   cin>>ch;
   if(ch=='Z') break;
}

il programma accetterà l'inserimento di 10 lettere da tastiera, ma non ci saranno necessariamente 10 iterazioni, infatti, se venisse inserita la lettera 'Z' il ciclo terminerebbe istantaneamente senza necessariamente eseguire 10 acquisizioni.


Ciclo while

       

Un ciclo con ripetizione precondizionale prevede il controllo iniziale della condizione; esso si rappresenta con l'istruzione while

while(condizione){
   istruzioni;
}


Interessante notare come il listato seguente  stampi tutti i numeri da 10 a 20;

int x=9;
while(x<20){
x++;
cout<<" "<<x;
}//fine while

mentre il listato seguente stampa solo 50:

int x=50;
while(x<20){
x++;
cout<<" "<<x;
}//fine while

il ciclo while non viene eseguito neanche una volta. In tal caso la variabile di controllo non soddisfi sin da subito la condizione logica del while.


Ciclo do-while

       

Il costrutto di ripetizione condizionale si rappresenta con il ciclo do-while:

do{
   istruzioni;
}while(condizione);

la sequenza di istruzioni compresa tra il do e il while viene ripetuta tante volte mentre la condizione scritta dopo il while si mantiene vera; in altre parole la ripetizione termina quando la condizione diventa falsa.
A differenza dei cicli for e while che verificano la condizione all'inizio del ciclo, il do-while la verifica alla fine, con la conseguenza che il do-while viene eseguito almeno sempre una volta.

Il listato seguente, stampa la serie di numeri da 10 a 20.

int x=9;
do{
   x++;
   cout<<" "<<x;
}while(x<20);

Il listato seguente stampa 51 a dimostrazione del fatto che il ciclo do-while viene eseguito, comunque, almeno una volta

int x=50;
do{
   x++;
   cout<<" "<<x;
}while(x<20);