Algoritmi alla base della programmazione
La base della programmazione: l’algoritmo
Un linguaggio di programmazione serve, in maniera molto banale, per indicare al computer quali operazioni compiere. Un insieme di queste operazioni è detto algoritmo. Dunque un algoritmo è un insieme di istruzioni, che dettiamo al computer attraverso un linguaggio di programmazione, che servono per compiere una determinata operazione. Esempio è possibile creare un algoritmo per il calcolo del codice fiscale, un algoritmo per il calcolo delle rate di un mutuo, oppure un algoritmo per visualizzare su schermo i poligoni di un videogioco 3d.
Il computer è stupido, esegue solo le operazioni che per cui è programmato, e non è in grado di prendere alcun tipo di decisione. Tutto quello che fa è dettato da un programma e dai relativi algoritmi. Il compito del programmatore è quindi di indicare precisamente al computer la sequenza esatta delle operazioni da compiere e come comportarsi al verificarsi di alcune condizioni affinché il risultato finale sia quello desiderato, insomma è compito del programmatore dotare il computer di una intelligenza artificiale e renderlo operativo per soddisfare i bisogni dell’utente.
Facciamo un esempio banale di algoritmo: immaginiamo che il nostro computer sia un robot che deve cucinare una torta. Dobbiamo quindi dirgli di prendere gli ingredienti, mischiarli, accendere il forno e cuocere la torta.:
1: prendi ingredienti
2: prepara la torta
3: accendi il forno
4: inforna la torta
A questo punto però il nostro robot deve togliere la torta dal forno quando essa sarà cotta. Dato che esso non è in grado di pensare o decidere da solo, dobbiamo dirgli esattamente cosa deve fare:
5: aspetta 2 minuti
6: controlla la torta, se non è cotta torna al punto 5 altrimenti procedi
7: togli la torta dal forno
8: spegni il forno
9: pulisci! (così mia moglie non si arrabbia!)
Ognuno di questi passaggi può essere scomposto in altrettanti algoritmi fino ad ottenere delle istruzioni elementari. Il robot infatti non conosce il comando “prendi ingredienti”… ma possiamo definire un algoritmo a parte che dica al robot quali sono gli ingredienti da prendere e qual è la loro posizione all’interno dei mobili. A sua volta questo algoritmo sarà scomposto per far muovere i cingoli del robot per raggiungere una determinata posizione della casa e muovere le braccia per raggiungere gli scaffali. E così via fino a scomporre il problema in una serie di sotto programmi sempre più elementari.
Questa tecnica di programmazione, prevede quindi la scomposizione del problema iniziale in sottoproblemi via via più specifici e consente al nostro algoritmo di essere di più facile interpretazione per noi umani. Per il computer, infatti, non fa alcuna differenza se gli diamo le istruzioni da eseguire tutte di fila oppure se spezzettiamo il nostro algoritmo in sotto programmi… la differenza sta dal “lato nostro” perchè ci ritroveremo di fronte ad un elenco lunghissimo di operazioni perdendo di vista il comportamento generico del programma (immaginiamo poi se il nostro programma viene letto da altri che non hanno presente il problema iniziale!). Un altro importante motivo per cui è necessario spezzare il nostro programma in “funzioni” (da ora in poi chiameremo così i sotto programmi!) è il fatto che spesso la stessa operazione viene ripetuta più volte o è necessario richiamarla in diversi punti del programma. Esempio, all’interno del nostro programma “torta”, in diversi punti, il nostro robot dovrà spostarsi per raggiungere una determinata posizione nella casa. Una ipotetica funzione “VaiNelPunto X” si occuperà quindi di azionare i motori per raggiungere la posizione X richiesta. Richiameremo, quindi, la funzione ogni qualvolta si rende necessario uno spostamento del robot senza dover riscrivere ogni volta i comandi per azionare i motori, ecc.
Un algoritmo come quello descritto, è un programma di tipo “Procedurale”, dove cioè si è predisposta una serie di funzione che vengono rischiamate una dopo l’altra nel corso della nostra procedura.
Nei sistemi moderni, basati su interfaccia grafica, finestre, ecc, il concetto di base della programmazione procedurale viene un pò stravolto e trasformato in quella che è comunemente definita come programmazione ad eventi. Il sistema operativo invia al nostro programma dei messaggi mettendolo al corrente di tutto quello che interessa alla nostra applicazione. Il compito del programmatore diventa dunque quello di intercettare questi messaggi e comportarsi di conseguenza.
Per meglio comprendere quanto detto facciamo questo esempio: immaginiamo di avere un computer con un mouse. Vogliamo fare un programma che gestisca il click dell’utente su un bottone grafico per compire un’azione (esempio la chiusura del programma stesso).
Nel primo scenario, programmazione procedurale, il nostro programma dovrebbe:
1) interrogare l’hardware per leggere la posizione del mouse e lo stato del tasto sinistro dello stesso.
2) Se il mouse si trova nel rettangolo dello schermo contenente il bottone e contemporaneamente risulta premuto il tasto sinistro allora posso andare al punto 3, altrimenti devo rieseguire il punto 1.
3) Chiudi il programma.
Nel caso della programmazione ad eventi, gran parte del lavoro è gestito dal sistema operativo e noi dobbiamo soltanto gestire cosa succede in caso di pressione sul bottone:
1) Attendi messaggi dal sistema operativo
2) Se ricevi un messaggio che notifica il click sul bottone chiudi il programma altrimenti vai al punto 1
L’esempio è un po banale e forse non rende neanche tanto bene l’idea, è bene però porre attenzione sul fatto che nel secondo esempio non ci siamo dovuti preoccupare di leggere il mouse. Interrogando l’hardware, e capire se e dove l’utente ha clickato, ma è il sistema operativo stesso che ci avvisa del click all’interno del bottone lasciando al noi il solo compito di programmare cosa fare alla pressione del tasto stesso. Nei linguaggi Visual Basic, VB.NET e C#, infatti, l’attesa e l’elaborazione dei messaggi provenienti dal sistema non richiede la scrittura di alcuna riga di codice, ma sono gestiti in automatico, il nostro compito si traduce nello scrivere una funzione che verrà richiamata al verificarsi dell’evento click.
Per tornare al nostro robot è come se il robot ricevesse una notifica dal forno quando la torta è pronta. In questo caso, dopo aver infornato, il robot dovrebbe solo attendere il messaggio di “fine cottura” dal forno senza dover preoccuparsi di andare a controllare ogni volta lo stato della cottura.
Torna alla rubrica: Guida alla programmazione