I paradigmi di programmazione

Nel linguaggio comune un paradigma è un modello di riferimento, un termine di paragone. In informatica il paradigma è uno stile di programmazione che influisce sull’approccio seguito nell’affrontare e risolvere un problema. Ogni linguaggio di programmazione è generalmente ispirato (e riconducibile) a un particolare paradigma di programmazione. Alcuni linguaggi di programmazione sono influenzati da molteplici paradigmi. In molti casi un nuovo paradigma nasce come evoluzione di un altro, aggiungendo nuovi concetti ma mantenendo anche quelli fondamentali del precedente (ponendoli eventualmente in una prospettiva nuova o modificandone l'importanza relativa). Talvolta questo "salto evolutivo" consiste nel rendere obbligatoria e/o supportare esplicitamente quella che nei paradigmi precedenti si era affermata come regola di buona programmazione. Per esempio, la programmazione strutturata ha introdotto strutture di controllo standard (sequenze, cicli e alternative) e ha vietato l'uso dell'istruzione di goto, della quale si era dimostrata la non indispensabilità (teorema di Böhm-Jacopini). Quando questo avvenne, i rischi legati all'uso indiscriminato dell'istruzione di salto incondizionato goto erano già noti a molti programmatori, ed erano diffuse regole di stile che suggerivano di restringere l'uso del goto in modi che si potessero far sostanzialmente corrispondere alle strutture di controllo della programmazione strutturata. Nel seguito saranno descritti alcuni di questi paradigmi.

Programmazione imperativa
Nella programmazione imperativa un programma è una sequenza di dati e istruzioni. Le caratteristiche essenziali della programmazione imperativa sono strettamente legate all’architettura di Von Neumann. I linguaggi sviluppati per la programmazione imperativa, nati più per la manipolazione numerica che per quella simbolica, adottano uno stile prescrittivo, ovvero uno stile in cui tutte le operazioni da compiere sono già state previste in anticipo. L'ordine di esecuzione è sequenziale (con l'eccezione delle strutture di controllo che possono frammentare l'azione). Un programma è strutturato in:  una sezione dichiarazioni in cui si dichiarano tutte le variabili del programma;  una sezione istruzioni che descrive l’algoritmo risolutivo mediante istruzioni del linguaggio. Le istruzioni possono essere:  istruzioni di lettura e scrittura (scrittura a video, scrittura su disco, lettura da tastiera, ...);  istruzioni di assegnamento (astrazione di cella di memoria);  istruzioni di controllo (if, while, for, foreach, try, catch, ...).

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

1

L'approccio imperativo è stato in seguito adottato da molti altri paradigmi, compreso quello orientato agli oggetti. Esso si contrappone a quello dichiarativo, in cui un programma consiste in un insieme di "affermazioni" (non "istruzioni") che definiscono l’obiettivo da raggiungere (cosa fare) senza specificare un algoritmo (come fare).

Esempio: Area di un quadrato (approccio imperativo)
Fase 1: individuazione dei dati ID lato area Descr lato quadrato area quadrato I/O/L input output TIPO double double VAL. INIZ. -

Fase 2: individuazione dell’algoritmo risolutivo
Start

input (lato)

area = lato * lato

output (lato)

End

Fase 3: scrittura del programma in Java import javax.swing.*; class Quadrato { public static void main(String[] args) { //Dichiarazione variabili double lato, area; //Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); //Calcolo area area = Math.pow(lato,2); //Output JoptionPane.showMessageDialog(null,”Area = “+area); } }

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

2

Programmazione procedurale
Nella programmazione procedurale un programma è costituito da blocchi di codice, identificati da un nome, detti sottoprogrammi. Questi blocchi possono essere dotati di parametri, cioè variabili locali i cui valori vengono forniti dall'esterno del blocco di codice. Un sottoprogramma ha una struttura simile a quella di un programma è può restituire o meno un valore. Nel primo caso si parla di funzioni, nel secondo caso di procedure.

Esempio: Area di un quadrato (approccio procedurale)
Fase 1: individuazione dei blocchi o sottoprogrammi Sottoprogramma calcolaArea: calcola l’area di un quadrato di cui sia noto il lato. Fase 2: individuazione dei dati e dell’algoritmo del programma principale ID lato area
Start

Descr lato quadrato area quadrato

I/O/L input output

TIPO double double

VAL. INIZ. -

input (lato)

calcolaArea

output (lato)

End

Fase 3: Applicazione dell’approccio imperativo per la risoluzione di ciascun sottoprogramma Algoritmo risolutivo per calcolaArea
Start

area = lato * lato

End

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

3

Fase 4: scrittura del programma in Java import javax.swing.*; class Quadrato { //Dichiarazione variabili di classe private static double lato; private static double area; //Sottoprogramma che calcola l'area public static void calcolaArea() { area= Math.pow(lato,2); } //Programma principale public static void main(String[] args) { //Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); //Calcolo area calcolaArea(); //Output JoptionPane.showMessageDialog(null,”Area = “+area); } } Una versione di calcolaArea che utilizza i parametri: import javax.swing.*; class Quadrato { //Sottoprogramma che calcola l'area public static double calcolaArea(double l) { return Math.pow(l,2); } //Programma principale public static void main(String[] args) { //Dichiarazione di variabili double lato,area; //Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); //Calcolo area area = calcolaArea(lato); //Output JoptionPane.showMessageDialog(null,”Area = “+area); } }

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

4

Sottoprogrammi in Java
Java è un linguaggio che segue il paradigma ad oggetti e, di conseguenza, non è adatto alla scomposizione procedurale. Tuttavia, con opportuni accorgimenti è possibile adottare una scomposizione in sottoprogrammi anche con tale linguaggio (nonostante sia fortemente sconsigliato). In Java i sottoprogrammi si chiamano metodi e restituiscono sempre un risultato, eventualmente “vuoto” (void). Di conseguenza, nonostante il linguaggio fornisca solo strumenti adatti a costruire funzioni, è possibile simulare il comportamento di una procedura restituendo un risultato void. Prima di addentrarci in tale spiegazione, due parole sulla sintassi per dichiarare i metodi: <visibilità> <tipo restituito> <nome metodo> (<lista parametri>) { <dichiarazione di variabili> <istruzioni> } Esempio public static double calcolaArea(double l) { return Math.pow(l,2); } Per il momento tralasciamo lo specificatore static e andiamo a descrivere le varie componenti di un metodo. • VISIBILITÀ Indica il livello di visibilità di un metodo (public, protected, private), caratteristica che approfondiremo in seguito. • TIPO RESTITUITO Indica il tipo del valore restituito dal metodo, che può essere uno qualsiasi dei tipi primitivi o riferimento visti nelle precedenti lezioni. Se una funzione non restituisce un valore, occorre specificare void. • NOME METODO E’ un identificatore liberamente scelto dall’utente, la cui lettera iniziale è convenzionalmente minuscola. • LISTA PARAMETRI La lista dei parametri contiene un elenco di dichiarazioni di variabili, dette parametri formali, separate da virgole. Per ogni parametro occorre indicare <tipo parametro> <nome parametro> I parametri di un metodo sono opzionali ma le parentesi () devono sempre essere presenti, anche se il loro contenuto è vuoto.

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

5

• DICHIARAZIONE DI VARIABILI Le variabili definite all’interno di un metodo sono opzionali: saranno presenti solo se necessarie. • ISTRUZIONI Le istruzioni, create utilizzando i costrutti di base del linguaggio, possono comprendere anche chiamate ad altri metodi e devono includere una particolare istruzione la cui sintassi è: return <valore>; L’istruzione return può essere inserita in qualunque punto della sezione istruzioni del metodo; essa ne causa la terminazione restituendo il valore specificato. Solitamente è l’ultima istruzione del metodo. Se il tipo restituito è void, l’istruzione assume la forma: return; e, nel caso sia posta al termine della sezione istruzioni, diventa superflua.

Esecuzione di sottoprogrammi in Java
Riprendiamo il codice visto in precedenza: import javax.swing.*; class Quadrato { //Dichiarazione variabili di classe private static double lato; private static double area; //Sottoprogramma che calcola l'area public static void calcolaArea() { area= Math.pow(lato,2); } //Programma principale public static void main(String[] args) { //Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); //Calcolo area calcolaArea(); //Output JoptionPane.showMessageDialog(null,”Area = “+area); } } Potete osservare che i 2 metodi definiti all’interno della classe presentano la parola chiave static nella dichiarazione. Osservate, inoltre, che anche le variabili lato e area sono static e sono dichiarate esternamente ai metodi. Il motivo è che entrambi i metodi devono potervi accedere per leggere/scrivere valori e quindi, dichiarandole all’interno di un metodo non sarebbero accessibili dall’altro.
Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

6

Le variabili dichiarate esternamente ai metodi e contrassegnate dalla parola chiave static si chiamano variabili di classe. I metodi static possono essere utilizzati senza necessariamente creare un oggetto, consentendo così di applicare una scomposizione procedurale. La parola chiave private, invece, ha una funzione completamente differente, che sarà chiarita affrontando il paradigma a oggetti. L’esecuzione del programma inizia dalla prima istruzione del metodo main: lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); Essa consente all’utente di inserire un valore del lato mediante una finestra di dialogo. L’istruzione calcolaArea(); effettua una chiamata al metodo calcolaArea. Il metodo main diviene quindi il chiamante, mentre il metodo calcolaArea è il chiamato. Il chiamato può restituire un valore al chiamante. Questo è il motivo per cui la chiamata di un metodo viene realizzata solitamente mediante una assegnazione ad una variabile. La variabile dovrà essere dello stesso tipo del valore restituito dal metodo. Fanno eccezione i metodi che restituiscono void, che possono essere chiamati senza utilizzare un’assegnazione ma semplicemente scrivendo il loro nome, come nel nostro esempio. La chiamata a calcolaArea() determina la sua esecuzione: il controllo passa al chiamato e viene eseguita la prima (e in questo caso unica) istruzione area= Math.pow(lato,2); Terminata l’esecuzione del metodo, il controllo torna al chiamante e viene eseguita l’istruzione successiva a quella che ha determinato la chiamata del metodo. JoptionPane.showMessageDialog(null,”Area = “+area); Si veda la simulazione del precedente programma nella dispensa dal titolo Simulazione 1.

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

7

Variabili globali e locali
Dalla simulazione si evince che le variabili lato e area, una volta allocate in memoria centrale, vi rimangono per tutta la durata dell’esecuzione; inoltre, esse sono visibili a tutti i metodi della classe, i quali possono accedervi sia in lettura sia in scrittura. Le variabili che presentano le predette caratteristiche sono dette, in generale, variabili globali. In Java, come si è già detto, sono chiamate variabili di classe, anche se i due concettti non sono completamente coincidenti. Le variabili definite all’interno di un sottoprogramma o presenti nella lista di parametri formali, sono dette variabili locali. Le variabili locali hanno un tempo di vita pari al tempo di esecuzione del sottoprogramma stesso e, a differenza delle variabili globali, sono visibili solo all’interno del sottoprogramma in cui sono dichiarate. Le procedure per poter produrre un qualche effetto, visto che non restituiscono alcun valore, devono modificare almeno una variabile globale; in altre parole esse producono degli effetti collaterali (side effect). La modifica di una variabile globale da parte di sottoprogrammi diversi è potenzialmente un’azione pericolosa, che può portare a comportamenti indesiderati del programma. In generale, quindi, è consigliabile utilizzare il minor numero possibile di variabili globali. Nel seguito vedremo una soluzione che consente di ridurre il numero di variabili globali, grazie all’uso di funzioni.

Utilizzo di funzioni al posto di procedure
Consideriamo il codice seguente: import javax.swing.*; class Quadrato { //Dichiarazione variabili di classe private static double lato; //Sottoprogramma che calcola l'area public static double calcolaArea() { return Math.pow(lato,2); } //Programma principale public static void main(String[] args) { //Dichiarazione di variabili double area; //Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); //Calcolo area area = calcolaArea(); //Output JoptionPane.showMessageDialog(null,”Area = “+area); } }

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

8

Osservate che la variabile area è definita all’interno del metodo main e che il metodo calcolaArea restituisce un valore double. Questo codice è migliore del precedente perché consente di utilizzare una sola variabile di classe. Si veda la dispensa Simulazione 2. L’ideale sarebbe eliminare tutte le variabili globali. Ma è possibile? Sì, attraverso l’uso di sottoprogrammi parametrici.

Sottoprogrammi parametrici
Analizziamo il codice seguente: import javax.swing.*; class Quadrato { //Sottoprogramma che calcola l'area public static double calcolaArea(double l) { return Math.pow(l,2); } //Programma principale public static void main(String[] args) { //Dichiarazione di variabili double lato,area; //Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog (“Immettere la misura del lato”)); //Calcolo area area = calcolaArea(lato); //Output JoptionPane.showMessageDialog(null,”Area = “+area); } } In questo codice non sono presenti variabili di classe ma compaiono dei parametri. I parametri sono di due tipi: formali e attuali. I parametri formali compaiono nell’intestazione di un metodo come una sequenza di dichiarazioni di variabili separate da virgole: public static double calcolaArea(double l) I parametri attuali sono specificati all’atto della chiamata del metodo e consistono in una sequenza di valori, separati da virgola: area = calcolaArea(lato); Alla chiamata del metodo il valore contenuto nel parametro attuale viene copiato nel parametro formale corrispondente. I parametri formali devono concordare in numero, posizione e tipo con i parametri attuali.

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

9

Quando termina l’esecuzione del metodo, tutti i parametri formali allocati in precedenza vengono deallocati. Di conseguenza il parametro formale l non dura per tutta l’esecuzione del programma ma solo per il tempo necessario all’esecuzione della funzione calcolaArea, dopodiché rilascia l’area di memoria occupata. L’assegnazione ad un parametro formale del corrispondente valore del parametro attuale è detto passaggio di parametri per valore. Il linguaggio Java utilizza solo questo tipo di passaggio di parametri. Tuttavia, esistono anche altri metodi per passare i parametri, adottati da altri linguaggi, come il passaggio di parametri per riferimento. Esso consiste nell’assegnare al parametro formale l’indirizzo del parametro attuale e non il suo valore. Si veda la Simulazione 3 per comprendere meglio i meccanismi descritti.

Riferimenti e approfondimenti
Wikipedia, Paradigmi di programmazione, url: http://it.wikipedia.org/wiki/Paradigma_di_programmazione Wikipedia, Programmazione imperativa url: http://it.wikipedia.org/wiki/Programmazione_imperativa Wikipedia, Programmazione procedurale url: http://it.wikipedia.org/wiki/Programmazione_procedurale

Quest'opera è stata rilasciata con licenza Creative Commons Attribution-ShareAlike 3.0 Unported. Per leggere una copia della licenza visita il sito web http://creativecommons.org/licenses/bysa/3.0/ o spedisci una lettera a Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Autore: Cinzia Bocchi Ultimo aggiornamento: 08/08/2011

10

Sign up to vote on this title
UsefulNot useful