Strutture di controllo

Come in tutti i linguaggi di programmazione procedurali (e a differenza dei linguaggi dichiarativi) in Java il programmatore deve descrivere in modo dettagliato i passi dell'algoritmo progettato per la risoluzione di un problema.

Per controllare il flusso di esecuzione, Java fornisce:

  • istruzioni (comandi) semplici
    • assegnamento
      <variabile> = <espressione>;
    • chiamata di metodo
      <oggetto/classe>.<metodo>(<parametri>);

  • blocchi di istruzioni
    • gruppi di istruzioni racchiuse tra parentesi graffe { ... }

  • istruzioni condizionali (decisionali, di scelta)
    • if-else
    • switch

  • istruzioni iterative (cicli)
    • while
    • for
    • do-while

  • istruzioni di salto
    • break
    • continue
    • return
    • throw

Inoltre vedremo come in Java sia possibile usare metodi ricorsivi in alternativa agli altri meccanismi di iterazione (si dice che un metodo è definito ricorsivamente se tra le istruzioni che ne definiscono il corpo compaiono invocazioni al metodo stesso).



Blocchi di istruzioni

Un'istruzione Java può essere:
  • un'istruzione semplice, per esempio:
    tasso = 0.025;
    oppure
    System.out.println(tasso);
  • un'istruzione composta (iterativa, condizionale), per esempio:
    if (tasso < 0.02)
       System.out.println("Mi dispiace cambio banca!");
  • un qualsiasi insieme di istruzioni e dichiarazioni racchiuso tra parentesi graffe, che viene chiamato blocco di istruzioni (enunciati, comandi) e viene trattato come fosse un'unica istruzione, per esempio:
    { tasso = 0.025;
      System.out.println(capitale*tasso); }

Ad esempio, ricollegandoci agli esercizi sui caratteri visti in laboratorio:

public class AlfabeticoMinuscolo {

    public static void main(String[] args) {

        char  ch = Input.readChar("Immetti un carattere: ");

        if ( (ch <= 'z') && (ch >= 'a') )  
            {
                System.out.print("Il carattere ");
                System.out.print(ch);
                System.out.println(" e' minuscolo");
            }
        else 
            {
                System.out.print("Il carattere ");
                System.out.print(ch);
                System.out.println(" non  e' minuscolo");
            }
            
    }
}



Variabili locali ai blocchi

I blocchi possono essere annidati: all'interno di un blocco può esserci un altro blocco

Possiamo utilizzare un blocco per racchiudere una sequenza di istruzioni ma anche per racchiudere dichiarazioni di variabili

Le variabili dichiarate in un blocco sono visibili solo all'interno del blocco stesso (variabili locali) e non sono quindi riferibili all'esterno del blocco

Esempio:
 

public class ProvaBlocchi {

    public static void main(String[] args) {

        double a = 0; 

        {
            int b = 10;
            System.out.println(b + "/" + a + " = " + (b/a));
        } 

        {
            int b = -5;
            System.out.println(b + "/" + a + " = " + (b/a));
        } 

        {
            int b = 0;
            System.out.println(b + "/" + a + " = " + (b/a));
        } 

    }
}


I nomi (identificatori) utilizzati per tali variabili non possono essere uguali a identificatori di variabili esterne al blocco: il compilatore segnalerebbe un errore.

Esempio:
 

public class ErroriBlocchi {

    public static void main(String[] args) {

        double a = 0; 

        {
            int a = 0; // a is already defined
            int b = 10;
        } 

        System.out.println(b + "/" + a + " = " + (b/a));
        // cannot resolve symbol b
    }
}