Corso sul linguaggio Java Modulo JAVA2 2.1- Funzioni 1 Prerequisiti Programmazione elementare in Java Tecnica top-down Concetto matematico di funzione Compilazione e link di programmi Esecuzione di funzioni 2 1
Introduzione In questa lezione fissiamo l attenzione su come realizzare un programma modulare, ossia un programma scomposto in funzioni o sottoprogrammi o moduli. Attraverso la tecnica top-down, è possibile rappresentare la soluzione di un problema come composta da sottoproblemi più semplici. Una funzione deve: svolgere un solo compito essere di uso generale rappresentare la soluzione di un singolo sottoproblema 3 Informazioni generali In questa Unità didattica mettiamo in pratica la tecnica top down l importanza di suddividere un programma in parti più piccole dette sottoprogrammi o funzioni: ciò comporta un codice più leggibile una progettazione più semplice una maggior semplicità nel collaudo nella correzione di eventuali errori nella eventuale modifica del codice. Iniziamo con un esempio semplice come la somma di due numeri 4 2
Istanza di una funzione Quando il programma fa uso di funzioni, un modo import java.io.*; per comunicare i valori delle variabili tra le varie funzioni è dichiarare le variabili esternamente alle public class Semplice funzioni (variabili globali) { static int a,b,c; public static void main (String args[ ]) { lettura(); somma (); stampa(); /* fine main */ definizione delle funzioni /* fine classe */ la funzione main() contiene le istanze delle funzioni: lettura() somma() stampa(). Le funzioni vanno definite nella classe, all esterno della funzione main() come è mostrato di seguito. 5 Definizione di funzioni static void lettura() { InputStreamReader In = new InputStreamReader (System.in); BufferedReader Tastiera = new BufferedReader (In); try { a = Integer.parseInt (Tastiera.readLine()); b = Integer.parseInt (Tastiera.readLine()); /* fine try */ catch (Exception E) { System.out.println("Attenzione: catturata eccezione "); /* fine catch */ /* fine lettura */ Vedremo più avanti il significato della parola void Questo blocco di istruzioni nel riquadro si dice definizione della funzione L intestazione si dice prototipo o firma della funzione 6 3
Definizione di funzioni static void somma() { c = a + b; /* fine somma */ In modo analogo si definiscono le funzioni somma() stampa(). static void stampa() { System.out.println(a + " + " + b + " = " + c); /* fine stampa */ 7 Visibilità globale delle variabili La classe Semplice può essere rappresentata come mostrato nel disegno. Variabili globali static int a, b, c; public static void main () static void lettura () static void somma () static void stampa () Le variabili globali a, b e c: sono dichiarate all esterno del main() hanno visibilità globale, ossia possono essere utilizzate e modificate da tutte le funzioni; quando il controllo torna al programma chiamante, la variabile risulta modificata rispetto al valore originario 8 4
Visibilità locale delle variabili La visibilità di una variabile può essere limitata ad una sola funzione. In questo caso, la variabile va dichiarata all interno della funzione. static int a, b, c; // globali public static void main () { int d, e; static void f1 () static void f2 () Variabili locali al main() Le variabili locali d ed e dell esempio: sono dichiarate all interno del main() hanno visibilità locale al main() ma non sono visibili nelle altre funzioni le altre funzioni possono usare variabili locali con lo stesso nome e modificarle senza rischio di confusione. Quando il controllo torna al programma chiamante, la variabile riprende automaticamente il valore originario 9 Esempio di visibilità import java.io.*; public class VarLocaliGlobali { static int globale=1; public static void main(string args[ ]) { int a,b,c,d, locale=2; Eseguendo il programma si osservino i valori delle variabili locale e globale System.out.println("MAIN: globale= "+ globale+ locale= "+ locale); f(); System.out.println("MAIN: globale= "+ globale+ locale= "+ locale); /* fine main */ public static void f() {int locale=3; System.out.println( In f(): globale= "+globale+"locale= "+ locale); locale++; globale--; System.out.println( In f(): globale--= "+ globale+ locale++= "+ locale); /* fine classe */ 10 5
Valore di ritorno Nel programma della somma di due numeri, il calcolo della somma può essere fatto anche mediante la seguente funzione: static int somma() { return a+b; La parola chiave void viene sostituita con int, che indica il tipo del valore di ritorno della funzione somma(). La parola chiave return indica il valore del risultato calcolato dalla funzione somma(). Questo valore si dice valore di ritorno. 11 Valore di ritorno La funzione main() allora assume la forma: public class Semplice L istanza della { static int a,b,c; funzione somma() public static void main (String args[ ]) viene effettuata come { se questa fosse una. variabile. lettura(); System.out.println (a + " + " + b + " = " + somma()); ATTIVITA : scrivere una funzione che calcoli l area di un trapezio isoscele note le basi B e b e l altezza h ed una analoga funzione per il perimetro 12 6
Valore di ritorno Variabili globali: double B, b, h;. Variabili globali: double B, b, h;. static double area() { return (B + b) * h / 2 ; Il valore di ritorno è l area del trapezio. static double perimetro() { double seg_lat=(b - b) / 2; double lobliquo = Math.sqrt(Math.pow(h, 2.0) + Math.pow(seg_lat, 2.0)); return (B + b + 2 * lobliquo); Il valore di ritorno è il perimetro del trapezio. 13 Il tipo void Alcune volte la funzione non deve restituire alcun valore, ma solo eseguire certe istruzioni: in tal caso per il tipo del risultato della funzione si usa la parola chiave void e non è necessario il return. Ad esempio: void stampa (int x, int y) /* Stampa dei due valori */ { System.out.println (x + + y); /* return non serve poiché la funzione è di tipo void */ void titolo () /* Esempio di funzione di tipo void { System.out.println (TITOLO); senza argomenti */ 14 7
Parametri formali La funzione somma() static int somma() { return a+b; presenta però lo svantaggio di eseguire l operazione sempre sulle stesse variabili a e b. Se si volesse eseguire l addizione tra le variabili c e d, occorrerebbe scrivere una funzione praticamente identica, avente come valore di ritorno c+d. Come si può generalizzare la funzione somma()? 15 Parametri formali Pensiamo la funzione somma() scritta come segue: static int somma (int x, int y) { return x + y; Parametri formali nella quale le variabili x ed y servono ad indicare due ingressi generici della funzione (i valori da sommare) e prendono il nome di parametri formali. I valori di x ed y verranno stabiliti solo al momento dell esecuzione della funzione. 16 8
Parametri attuali. public static void main(string args[ ]) { int a,b,c,d;. try { System.out.print("Primo addendo: "); a=integer.parseint(tastiera.readline()); System.out.print("Secondo addendo: "); b=integer.parseint(tastiera.readline()); System.out.println("La somma e' " + somma (a,b)); /* fine try */. /* end main() */ /* end class */ Poiché i valori delle variabili sono passati alla funzione come parametro, le variabili possono essere dichiarate locali al main(). Al momento dell istanza, i valori a e b vengono passati come parametri alla funzione somma() e prendono il nome di parametri attuali o parametri effettivi 17 Scopo dei parametri Lo scopo dei parametri formali (nel prototipo) ed attuali (nell istanza) è quello di costituire una interfaccia, tra la funzione ed il programma chiamante, che consenta di istanziare la funzione con certi valori L input della funzione deve avvenire mediante i parametri e l output è il risultato che la funzione fornisce al programma chiamante mediante il return. 18 9
Utilizzo dei parametri I parametri formali: NON vanno dichiarati nella funzione main() servono a far sapere al programma chiamante il numero, l ordine ed il tipo degli ingressi della funzione (chiamati anche argomenti) Nell istanza della funzione i parametri attuali: devono essere dichiarate nel programma chiamante devono essere nello stesso numero,ordine e tipo dei parametri formali. Per ora trattiamo il solo caso di parametri passati per valore, in seguito vedremo in quali casi avviene il passaggio per indirizzo. 19 La struttura di una funzione Da quanto abbiamo detto, la struttura generale di una funzione è: tipo è il tipo del valore di ritorno della funzione (char, int, float, double, void, String) ident è il nome della funzione assegnato dal programmatore e deve richiamare lo scopo della funzione esattamente come facciamo per le variabili. La riga di intestazione prende il nome di prototipo o firma della funzione static tipo ident (lista-argomenti) { dichiarazione-variabili-locali blocco-eseguibile return (espressione); Se la funzione non è void, il suo identificatore verrà utilizzato come una variabile contenente il valore calcolato dalla funzione medesima 20 10
La struttura di una funzione Da quanto abbiamo detto, la struttura generale di una funzione è: lista-argomenti contiene l elenco dei parametri formali che passiamo alla funzione affinchè essa possa svolgere un dato compito. Ad esempio, se la funzione calcola l area di un quadrato, occorre fornire ad essa un argomento che rappresenta la misura del lato. static tipo ident (lista-argomenti) { dichiarazione-variabili-locali blocco-eseguibile return (espressione); 21 La struttura di una funzione Da quanto abbiamo detto, la struttura generale di una funzione è: static tipo ident (lista-argomenti) { dichiarazione-variabili-locali blocco-eseguibile return (espressione); La sezione dichiarazionevariabili-locali serve a dichiarare le variabili che userà la funzione. Si noti che queste variabili NON saranno utilizzabili all esterno della funzione stessa perché sono variabili locali. 22 11
La struttura di una funzione Da quanto abbiamo detto, la struttura generale di una funzione è: static tipo ident (lista-argomenti) { dichiarazione-variabili-locali blocco-eseguibile return (espressione); La sezione blocco-eseguibile conterrà tutte le istruzioni che la funzione dovrà svolgere una volta che verrà chiesta la sua esecuzione. 23 La struttura di una funzione Da quanto abbiamo detto, la struttura generale di una funzione è: espressione rappresenta il risultato prodotto dalla esecuzione della funzione. La parola chiave return indica il termine delle istruzioni ed ha il compito di assegnare espressione al nome della funzione static tipo ident (lista-argomenti) { dichiarazione-variabili-locali blocco-eseguibile return (espressione); Nel caso di funzioni void il return non viene utilizzato. 24 12
Progettare una funzione Per scrivere una funzione, dobbiamo prima definire: il prototipo nome della funzione gli eventuali parametri da passare alla funzione il tipo del valore di ritorno le istruzioni da eseguire 25 Compilazione e link di funzioni Il compilatore, nel tradurre il programma principale, opera anche sulle funzioni: controlla il tipo del valore di ritorno dalla funzione ordine, numero e tipo dei parametri alloca in memoria il codice della funzione fa intervenire il linker, un programma che: collega il codice della funzione con il programma principale genera il programma bytecode Avviene tramite il prototipo Successivamente, l istanza della funzione nel main(), avviene tramite le fasi note (sospensione del chiamante, salvataggio contesto nella pila di attivazione, esecuzione, ripristino del contesto del chiamante, ripresa del chiamante. 26 13
Argomenti Istanza di una funzione Definizione di funzioni Visibilità globale delle variabili Visibilità locale delle variabili Esempio di visibilità Valore di ritorno Il tipo void Parametri formali Parametri attuali Scopo dei parametri Utilizzo dei parametri La struttura di una funzione Progettare una funzione Compilazione e link di funzioni 27 Altre fonti di informazione P. Camagni, R.Nikolassy - Java ed. Hoepli A.Lorenzi-A.Rizzi - Il linguaggio Java - ed. ATLAS 28 14