6.    Programmi

6.1. La programmazione

Un programma è un insieme di istruzioni eseguite dalla CPU, esse trasformano le informazioni, presenti su un supporto accessibile da un calcolatore, e le registrano sullo stesso supporto o su un altro eventualmente accessibile ai sensi dell'utilizzatore: carta, video audio. Spesso si parla anche di algoritmo: di fatto un programma è la realizzazione di un algoritmo.

In modo più concreto: un programma è l'automazione di una procedura di elaborazione di informazioni: l'emissione di una fattura, di una ricevuta, la prenotazione di un esame, ecc..

Sui primi calcolatori chi realizzava un programma era più impegnato nel come fare un programma più che  su cosa fare: la semplice operazione di calcolare uno sconto, veniva realizzata con diverse istruzioni in linguaggio macchina. Nel tempo la programmazione è diventata più semplice, sia per l'evoluzione dei linguaggi utilizzati, che per l'affinamento delle tecniche e degli stili di programmazione.

Alla base della realizzazione di un programma c'è la la descrizione accurata dei dati che esso tratta, di come li tratta e di quali dati vengono prodotti. Il punto cruciale è comunque come vengono trattati i dati, ed una delle tecniche per facilitare la programmazione, consiste nel descrivere il comportamento del programma individuando macroattività, da suddividere eventualmente in sottoattività, fino a giungere al dettaglio voluto (analisi top down).  Ciò permette di  realizzazare dei programmi modulari o in componenti distinte, la cui stesura e messa a punto è facilitata dalle dimensioni più ridotte; inoltre alcuni moduli possono essere utilizzati anche da altri programmi.

Ad esempio una richiesta di analisi di laboratorio:

·                                            Richiesta dei dati anagrafici

·                                            Controllo del codice fiscale

·                                            Richiesta degli esami

·                                            Assegnazione delle disponibiltà

·                                            Calcolo del contributo

Il controllo del codice fiscale può essere utilizzato da altri programmi.

I programmi si classificano sotto diversi aspetti, in funzione di ciò che fanno, o di come interagiscono con l'utilizzatore; per questo aspetto si parla di programmi batch o interattivi. Nel primo caso il programma esegue una elaborazione autonoma e si arresta quando essa è finita, ad esempio la stampa degli stipendi o delle fatture. Nel secondo caso c'è una continua interazione con l'utilizzatore: il programma si attiva in funzione delle scelte fatte e dei dati immessi.

6.1.1.   Strutture di base della programmazione

Il comportamento di un programma può essere descritto graficamente, mediante dei diagrammi di flusso (flow chart), in cui si specificano le operazioni da eseguire, l'ordine con cui devono essere eseguite e le alternative in funzione dei dati di elaborazione.

E' stato dimostrato[1] che si può scrivere un programma con solo due strutture: assegnazione e mentre; in forma di diagrammi sono:

Assignazione (Let): ad una variabile viene assegnato il valore di un'altra variabile o il risultato di un calcolo.

 

 

 

 

 

 

 

 

 

 


mentre (while condizione do comandi): fintanto che la condizione è vera, esegue comandi.

 

 

 

 

 

 

 

 

 

 

 

 


I diagrammi di flusso di destra, dell'assegnazione e del mentre, sono il diagramma di flusso della divisione fra numeri interi.

La seguente struttura, anche se la teoria dice che è ridondante, è tuttavia molto utile: 

se allora altrimenti (If condizione then comandi else comandi)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Qui di seguito c'è un esempio di diagramma, cioè un disegno di una semplice elaborazione batch.

Tabella 61


 

6.1.2.   Il teorema di Bohm-Jacopini

Il teorema di Bohm-Jacopini afferma che è possibile trasformare un diagramma di flusso qualsiasi in un diagramma di flusso "strutturato", contenente cioè solamente le strutture assegnazione e mentre. Nella dimostrazione qui accennata sarà utilizzato anche if then else, uno degli esercizi proposti fornirà la prova dell'eliminabilità di quest'ultima struttura.

Il programma da trasformare abbia un solo ingresso ed una sola uscita:

 

 

 

 

 

 


I componenti di base di un diagramma sono nodi ed archi, i nodi corrispondono ai simboli condizionali ed alle giunzioni, gli archi sono le istruzioni di assegnazione. Qui di seguito sono visualizzati i casi possibili con  (disegno a sinistra) e la relativa trasformazione (disegno a destra). Dopo ogni trasformazione la o le parti da trasformare hanno un numero di componenti non superiore al numero delle componenti di quello di partenza.

I caso: istruzione di assegnazione

 

 

 

 


non ci sono trasformazioni da effettuare

Pgm1

 

 

 

 

 

 


II caso: istruzione condizionale

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Pgm2 è l'insieme di tutti i nodi e tutti i sentieri raggiunti dal lato sinistro della condizione, e analogamente Pgm3 per il lato destro. Si noti che con questo schema Pgm2 e Pgm3 possono avere parti in comune, è una ridondanza che si può evitare, scorporando la parte comune che va posta in fondo al diagramma (la parte tratteggiata). Il risultato dell'operazione è if  c then Pgm2 else Pgm3.


III caso: un nodo formato da un rinvio all'interno di Pgm1 (una istruzione goto), prima di una assegnazione.

 

 

 

 

 

 

 

 

 

 

 

 

 


Questa trasformazione non semplifica, anzi aggiunge della ridondanza, serve per giungere al IV caso.

IV caso: un nodo di collegamento prima di un condizionale.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


In questa trasformazione è stata aggiunta una variabile ausiliaria, la trasformazione da luogo al diagramma (macrostrutturato):

v-aus ← vero

while v-aus = vero do

{

  if c then

  {

    Pgm2

    ...

    v-aus ← falso

  Else

    Pgm3

    ...

    v-aus ← falso

  }

}

6.1.3.   Funzioni e procedure

I moduli o sottoprogrammi di un programma svolgono delle operazioni delimitate su una parte dei dati. E' buona norma che un sottoprogramma abbia accesso ai soli dati che deve elaborare, e che, oltre a separare i dati usati nel calcolo da quelli prodotti dal calcolo, i primi non siano modificabili. Tuttavia le buone norme possono avere eccezioni.

I modi di mettere a disposizione i dati sono essenzialmente due:

§      aree condivise: non è, in genere,  una buona tecnica

§         liste di dati: in genere liste di indirizzi dei dati

§      pila di dati perlopiù nei linguaggi di basso livello

Il modo per "proteggere"  i dati in lettura, è di passare al sottoprogramma delle copie (passaggio di dati per valore),[2] metodo costoso se i dati sono migliaia di caratteri. Passare ad un sottoprogramma l'indirizzo del dato (passaggio di dati per referenza), rende il dato modificabile.

I sottoprogrammi si differenziano ancora in:

§      funzioni: le funzioni ricevono una lista di parametri, e restituiscono un valore

§      procedure: le procedure ricevono una lista di parametri

6.1.4.   Librerie di sottoprogrammi

Le librerie sono collezioni di funzioni in genere relative ad uno stessso dominio di dati, ad esempio: funzioni statistiche, funzioni per la grafica, funzioni del Sistema Operativo, ecc…. Molte funzioni dei sistemi operativi sono contenute in librerie, dette librerie di sistema, e sono accessibili agli sviluppatori di programmi; le principali librerie sono relative alla gestione della grafica video, all'accesso ai dischi, al collegamento con altri calcolatori, ecc.. In genere per queste librerie si utilizza invece del termine funzione, il termine API (Application Program Interface). Nei Sistemi Operativi Microsoft i file di libreria hanno estensione DLL.

 



[1] C. Bohm & G. Jacopini, "Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules," Communications of the ACM, vol. 9(5), May 1966, pp. 366-371.

[2] E' possibile anche una protezione del SO, ad esempio se programma e sottoprogramma appartengono a processi distinti, in quanto ogni processo, in genere, non può accedere in scrittura a memorie assegnate ad altri processi.