Primi elementi:
diagrammi di flusso, algoritmi, programmi ...
(Aggiornamento dell'articolo al 16/02/2011)
Fino ad ora ho scritto alcuni articoli su aspetti e temi
riguardanti l’informatica ma non sono partito dal principio e
forse direi anche di averlo fatto a ragion veduta cercando prima
di interessarvi un po’ all’argomento.
In genere, prima di descrivere come è fatta una automobile nei
suoi più intimi particolari, è sempre bene far provare un po’
l’ebbrezza della velocità, l’utilità del mezzo, come si guida ed
infine elencare le possibili future evoluzioni. Allo stesso modo
qui, dopo avervi descritto alcuni aspetti e, allo stesso tempo
consapevole di quello che sapete già sull’uso e sulla praticità
dell’elaboratore, inizierò a parlarvi del suo funzionamento e
del modo con il quale noi diamo ad esso insiemi di istruzioni (i
programmi) per far eseguire a lui operazioni complesse. Vi
insegnerò un po’ alla volta a programmare facendo in modo che
voi possiate far eseguire alla macchina istruzioni da voi
progettate; vedrete che a poco alla volta vi sentirete voi i
padroni del mezzo e, come dice il sottotitolo di questo sito,
non vi spaventerete più di fronte ai diversi problemi che per
gran parte di voi, per ora solo utilizzatori, a volte potrebbero
sembrare grossi e limitativi. Insomma voglio dire cioè che se vi
si incepperà “la macchina”, non tirerete più giù “le madonne”,
ma opererete in modo opportuno per risolvere via, via i vari
problemi.
Prima di iniziare a parlare sull’argomento, vi descriverò in
modo schematico e sommario attraverso un disegno come è fatto un
elaboratore. In genere dobbiamo dire che i dati
vengono immessi attraverso una unità di entrata: “input”
(tastiera), elaborati da una unità di elaborazione attraverso un
programma che risiede in memoria poi, finita l’elaborazione, i
dati vengono inviati ad una unità di uscita: “output” (monitor,
stampante ecc.).
Nella realtà un vero elaboratore è molto più
complesso ed è forse troppo limitativo descriverlo solo con
questo disegno. Devo ricordare che accanto ad elementi di input
e output vi sono anche elementi di imput/output cioè che
svolgono contemporaneamente entrambe le funzioni cioè i dischi
esterni ( Dvd e CD riscrivibili, pen-drive ecc. ecc.) o interni
(hard disk). Come elementi di solo input dobbiamo includere il
mouse e il joistik dove presente ecc. ecc. L’unità di
elaborazione è rappresentata dal microprocessore, anche se unità
aggiuntive sono quasi sempre presenti: coprocessori grafici e
matematici ecc. ecc. Lo schema esposto nell’illustrazione
dovrebbe comunque dare una indicazione precisa del funzionamento
della macchina.
E’ comunque evidente dallo schema, che un computer è la prima
macchina non progettata per eseguire un’unica funzione (ad
esempio una tenaglia, un martello, un televisore, una
automobile) ma infinite funzioni; basta caricare in memoria un
programma, ad esempio word, per scrivere, o paint per disegnare,
media player per sentire musica o vedere filmati, photoshop per
elaborare fotografie ecc. ecc.
E’ quindi chiaro che un programma è una sequenza di istruzioni
elementari, a volte anche notevolmente complessa, eseguibili
dalla macchina per trasformare i dati iniziali di input in
risultati finali di output. Quando noi carichiamo in memoria e
facciamo eseguire un programma (ad esempio word), quest’ultimo
si mette in attesa di un input (immissione di caratteri), lo
elabora (ad esempio una formattazione) e lo presenta in uscita
con un output (stampa a video o su carta).
Lo scopo di questi articoli, non è quello di insegnarvi ad usare
word o photoshop, ma di mettervi in grado di progettare voi
stessi semplici programmi da far eseguire alla macchina.
I processi (insieme in sequenza di istruzioni) sono
rappresentati e descritti utilizzando un linguaggio di
programmazione e l’insieme combinato di più processi
costituiscono il programma. I processi la cui esecuzione
richiede un tempo finito, vengono detti algoritmi.
Un algoritmo deve ubbidire a tre proprietà fondamentali:
1° ogni istruzione deve essere ben definita nei suoi effetti
cioè senza ambiguità;
2° ogni istruzione rappresenta una azione elementare eseguibile
in un intervallo di tempo finito;
3° il processo descritto dal programma deve terminare dopo un
numero finito di passi.
Gli algoritmi qui descritti sono pensati per un particolare
esecutore : l’elaboratore elettronico. Per semplicità gli
algoritmi vengono descritti con i così detti schemi a blocchi o
diagrammi di flusso. E’ più facile in questo modo poi
trasformare tali schemi in istruzioni rappresentate e descritte
da uno specifico linguaggio di programmazione.
Per non considerare la programmazione solo connessa con una
macchina (elaboratore) consideriamo come primo esempio un
algoritmo pensato per l’esecutore umano (figura 4). Si deve progettare un
particolare algoritmo che, attraverso una descrizione a parole,
descrivi il funzionamento di un distributore automatico di
sigarette dal costo di euro 1,50 al pacchetto che deve essere
alimentato da 8 monete da euro 0,20.
Ormai, e siamo nel 2010, non si trovano quasi più distributori
di sigarette, oggigiorno è più facile trovare distributori di
preservativi, ma vi assicuro che il funzionamento della macchina
è lo stesso, cambia solo il prodotto. Il riferimento alle
sigarette, è dovuto essenzialmente al fatto che ahimè nel
lontano [19 (…) :-)] quando studiavo io questi esempi, il
riferimento era proprio questo.
Il modo per rappresentare il processo è questo:
1° inserire le 8 monete
2° tirare il cassetto corrispondente alla marca di sigarette
desiderato
3° estrarre il pacchetto
4° richiudere il cassetto
5° ritirare il resto di euro 0,10.
Questa sequenza di istruzioni gode delle 3 proprietà elencate
più sopra, e pertanto costituisce un algoritmo. Il diagramma di
flusso corrispondente è quello della figura qui a destra
rappresentata.
L’algoritmo può tuttavia essere migliorato e completato
inserendo un test iniziale sul funzionamento della macchina; se
quest’ultima è guasta oppure se il serbatoio contenente le
sigarette della marca desiderata è vuoto è meglio rivolgersi al
tabaccaio più vicino.
Le istruzioni di test vengono negli schemi a blocchi
rappresentati da rombi con due uscite: “si” e “no”
corrispondenti alle risposte (senza ambiguità) alle domande dei
test. A noi sembrerà una limitazione questa mancanza di
ambiguità, ma vi assicuro che si può ovviare a ciò aumentando in
cascata il numero dei test arrivando via, via ad un risultato
sempre più preciso:
Il blocco “inserire le monete” si può ulteriormente dettagliare
con una combinazione di un blocco e di un test.
Tale insieme di istruzioni viene chiamato iterazione o loop.
L’insieme delle operazioni viene ripetuto fino a quando il test
viene completato e verificato.
Passiamo ora ad un altro esempio, questa volta però pensato per un esecutore diverso (un elaboratore). Si voglia progettare un programma in grado di rappresentare un processo di moltiplicazione di due numeri interi positivi w e y e il risultato denotato con z. Si supponga che l’elaboratore possa eseguire solo somme e sottrazioni su due operandi e di fornire all’esterno valori interi. Lascio a voi il compito di seguire mentalmente il diagramma. La trasformazione del flusso in un linguaggio di programmazione potrebbe essere il seguente:
avvio | |
leggi W | |
leggi y | |
Z = 0 | |
U = Y | |
prodotto | Z = Z + W |
U = U - 1 | |
se U ≠ 0 salta a prodotto | |
scrivi Z | |
arresto |
/*Programmino moltiplicazione scritto da Carlo Sala
26/03/2010*/
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
double W;
double Y;
double Z;
double U;
do
{
cout << "\nInserisci un numero intero
positivo (piu' invio) : ";
cin >> W;
cout << "\nMoltiplicato per (piu' invio) : ";
cin >> Y;
}
while (W < 0 or Y < 0);
Z = 0;
U = Y;
while (U > 0)
{
Z = Z + W;
U = U - 1;
}
cout << "\nIl risultato e' : " << Z << endl << endl;
system ("PAUSE");
return EXIT_SUCCESS;
}
Naturalmente i veri linguaggi di programmazione sono differenti
ma solo nei termini e nella sintassi, ma non nella logica !!
Ad esempio in C++ sarà: (vedi anche
qui ....)
Il programma così appunto si scrive e come vedete sono state
aggiunte in testa e in coda alcune istruzioni per inizializzare la
macchina. Vi esorto per comprendere il codice sopra evidenziato a comprare dei semplici manuali del
linguaggio per imparare e approfondire l’argomento. (ai miei
tempi c'erano i "Bigini". Ci sono ancora ??)
Queste semplici righe di codice verranno poi compilate da un
programma apposito (il compilatore) che crea un file eseguibile
dall’elaboratore. Nella sezione manuali e software di questo
sito potete scaricare gratuitamente uno dei tanti compilatori
C++ sul mercato. Qui invece potete scaricare l’esempio che è già
stato da me compilato ed è eseguibile dopo averlo però
scompattato. Il programmino non è però completo, se tenterete di
inserire numeri non interi o negativi, si fermerà segnalandovi l’errore
o dandovi risultati non coerenti. A
breve il seguito …
Il programma per estrema semplificazione non ha la solita
interfaccia grafica tipica di windows ma quella dell'ormai datato
MS-dos. Dopo aver inserito i dati premere invio per confermarli !
[ Ma non era più semplice con
una macchinetta per i calcoli o usare la calcolatrice di windows
...? Forse sì ma dove stava la poesia ..... Avreste potuto poi dire:
"L'ho fatto io !" ? No, no !!
(Beh ..), ma per ora l'ha fatto il Carlo ]
Ma si andrà sempre più sul difficile ...!!
(Aggiunta del 05/03/2024)
Ottima playlist su YouTube del professore Fabrizio Camuso riguardante le strutture dati.