Istruzioni che si ripetono

Funzioni e procedure consentono di scrivere una sola volta delle istruzioni che normalmente andrebbero ripetute più volte nel programma. Un esempio è la valutazione della funzione di cui si vuole trovare un intervallo con uno zero nel programma Nullo.java. Nel programma ci sono ben cinque istruzioni che calcolano la stessa identica funzione x2-5x-2. Sarebbe comodo poter scrivere questa funzione una volta sola all'inizio del programma: a parte la semplificazione del lavoro di scrittura, questo riduce la probabilità di commettere errori nella scrittura della funzione, e permette di modificare più facilmente il programma se si vuole analizzare una funzione diversa.

Usare funzioni sul programma di ricerca degli zeri è piuttosto complicato da spiegare, dal momento che si utilizzano già tutte le caratteristiche delle funzioni. Per questa ragione, cominciamo con esempî più facili, e rimandiamo la modifica di Nullo.java a un momento successivo.

Supponiamo di voler modificare il programma Espressioni.java in modo che i risultati delle espressioni siano separati fra di loro da una linea composta di asterischi, preceduta e seguita da linee vuote. In altre parole, vogliamo una cosa del tipo:

Risultato della prima espressione: 1.8371900826446281

***********************************************************

Risultato della seconda espressione: 34.460000000000001

***********************************************************

Risultato della terza espressione: 0.01484119916889285

***********************************************************

Risultato della quarta espressione: 7.0408025110778389
Per stampare una linea vuota basta dare un comando del tipo System.out.println(" "), che corrisponde a stampare una linea in cui c'è solo uno spazio (la linea appare quindi vuota). Con questo trucco, è possibile scrivere il programma EspressioniSeparate.java che risolve il problema.

/*
  Alcuni esempi di espressioni
*/

class EspressioniSeparate {
  public static void main(String[] args) {
    double a=12.23,b=0.1e+2,c;

    c=(a+b)/12.1;
    System.out.println("Risultato della prima espressione: "+c);

    System.out.println(" ");
    System.out.println("***********************************************************");
    System.out.println(" ");

    c=a*2+b;
    System.out.println("Risultato della seconda espressione: "+c);

    System.out.println(" ");
    System.out.println("***********************************************************");
    System.out.println(" ");

    c=1/(a-1)/(b-4);
    System.out.println("Risultato della terza espressione: "+c);

    System.out.println(" ");
    System.out.println("***********************************************************");
    System.out.println(" ");

    c=Math.sqrt(a*a - b*b);
    System.out.println("Risultato della quarta espressione: "+c);
  }
}

Il programma funziona perfettamente. D'altra parte, è stato necessario riscrivere tre volte la stessa sequenza di istruzioni:

    System.out.println(" ");
    System.out.println("***********************************************************");
    System.out.println(" ");
Sarebbe comodo poter evitare di ripetere la scrittura di queste tre istruzioni ogni volta. Le procedure servono a questo: scrivere una sequenza di istruzioni una volta sola, anche se poi vanno ripetute più volte nel programma. In particolare, una procedura è un nome che viene assegnato a una sequenza di istruzioni. In questo modo, quando nel programma è necessario eseguire quelle istruzioni, si può utilizzare il nome invece di scrivere le istruzioni per esteso.

Per fare questo è necessario:

  1. dare un nome a una sequenza di istruzioni;
  2. scrivere il nome al posto della sequenza nei punti del programma in cui vanno eseguite le istruzioni.
Il passo 1, chiè la definizione di un nome a una sequenza di istruzioni, si chiama dichiarazione di procedura. Il formato è il seguente:

static void nome() {
  istruzione1;
  istruzione2;
  ...
}
Le istruzioni fra parentesi graffe sono quelle che si vuole ripetere più volte all'interno del programma. A questa sequenza viene assegnato il nome dato. Il nome serve a permettere di richiamare queste istruzioni: in altre parole, si usa ogni volta che è necessario eseguire la sequenza di istruzioni.

Le procedure vanno messa prima della line public stati void main.... Ogni volta che si vogliono eseguire le istruzioni che si trovano in una certa procedura, si scrive nome();. Scrivere il nome (che equivale a eseguire le istruzioni associate al nome) si dice chiamata di procedura.

Il programma che stampa il risultato di espressioni si può quindi riscrivere come segue: EspressioniSeparateProc.java

/*
  Alcuni esempi di espressioni
*/

class EspressioniSeparateProc {
  static void separa() {
    System.out.println(" ");
    System.out.println("***********************************************************");
    System.out.println(" ");
  }

  public static void main(String[] args) {
    double a=12.23,b=0.1e+2,c;

    c=(a+b)/12.1;
    System.out.println("Risultato della prima espressione: "+c);

    separa();

    c=a*2+b;
    System.out.println("Risultato della seconda espressione: "+c);

    separa();

    c=1/(a-1)/(b-4);
    System.out.println("Risultato della terza espressione: "+c);

    separa();

    c=Math.sqrt(a*a - b*b);
    System.out.println("Risultato della quarta espressione: "+c);
  }
}

Spiegazione riassuntiva: occorre ripetere una sequenza di tre istruzioni diverse volte nel codice; è quindi vantaggioso usare una procedura in cui si scrivono queste istruzioni una volta sola. La prima cosa da fare è scrivere la procedura stessa, ossia si scrive static void separa(), in cui ``separa'' è il nome che si è scelto per la procedura, seguito dalle tre istruzioni racchiuse da parentesi graffe. A questo punto esiste una procedura che si chiama separa(). Ogni volta che nel resto del programma appare la istruzione separa(), questo è equivalente ad eseguire le istruzioni che sono state messe nella procedura.