Istruzioni iterative

Spesso un algoritmo per la risoluzione di un problema richiede di eseguire piu' volte una sequenza di passi elementari (si pensi ad esempio al calcolo del fattoriale di un numero fornito in input dall'utente).

Le istruzioni iterative (ripetizioni) consentono di ripetere una sequenza di istruzioni in base a certe condizioni o per un numero definito di volte.

In particolare Java, fornisce le seguenti istruzioni composte:

  • while
  • for
  • do-while
L'istruzione while viene usata quando uno o piu' comandi devono essere ripetuti ciclicamente fino a quando una certa condizione non risulta falsa.
L'istruzione for viene usata, di norma, quando uno o piu' comandi devono essere ripetuti un numero prefissato di volte.
L'istruzione do-while  viene usata al posto del while quando i comandi devono essere eseguiti almeno una volta.



Il comando while: Sintassi

while ( <condizione> )
    <corpo>

dove:

  • <condizione> è un'espressione di tipo boolean, chiamata anche la guardia
  • <corpo>  può essere:
  • un' istruzione semplice
  • un'istruzione composta
  • un blocco di istruzioni



Il comando while: Significato

while ( <condizione> )
    <corpo>

L'istruzione while valuta inizialmente l'espressione booleana <condizione>.

  • Se la valutazione ritorna il valore true viene eseguito il <corpo>, al termine del quale si ri-esegue tutto il comando while.
  • Se la valutazione ritorna il valore false l'esecuzione passa all'istruzione successiva al while.

Normalmente, la guardia del while controlla il valore di una o piu' variabili, chiamate variabili di controllo del ciclo. Le variabili di controllo vanno inizializzate opportunamete prima del while, e devono essere aggiornate nel corpo per garantire la terminazione del ciclo.

Le istruzioni while possono essere annidate.





Comando while: Esempi

Il seguente programma calcola quanti anni ci vogliono per raddoppiare un certo capitale C applicando gli interessi composti ad un tasso T. Sia C che T sono forniti dall'utente.
 
public class RaddoppioInv
{  public static void main(String[] args)
   {
      // creo un oggetto ConsoleReader.
      ConsoleReader console = new ConsoleReader(System.in);

      System.out.println("Tasso di interesse:");
      // leggo un numero in virgola mobile
      double tasso = console.readDouble();

      System.out.println("Saldo iniziale:");
      // leggo un numero in virgola mobile
      double saldoIniziale = console.readDouble();

      int anno = 0;

      double saldo = saldoIniziale;

      // accumula progressivamente gli interessi
      // fino a quando il saldo si raddoppia

      while (saldo < 2 * saldoIniziale)
      { anno++;
        double interesse = saldo * tasso/100;
        saldo = saldo + interesse;
      }

      System.out.println("L'investimento si raddoppia" +
            + " dopo " + anno + " anni.");
   }
}





Il comando for: Sintassi

for ( <inizializzazione>;<condizione>;<aggiornamento> )
    <corpo>

dove:

  • <inizializzazione> è di solito un comando di assegnamento, che assegna un valore iniziale alla variabile di controllo. La variable può essere dichiarata prima del for, o in <inizializzazione>.
  • <condizione> è un'espressione di tipo boolean
  • <aggiornamento> è di solito un comando che aggiorna la variabile di controllo (ad esempio, la incrementa di 1).
  • <corpo>  può essere:
  • un'istruzione semplice
  • un'istruzione composta
  • un blocco di istruzioni
Sia <inizializzazione> che <aggiornamento> possono essere, in generale, liste di istruzioni separate da virgole

 



Il comando for: Significato


for ( <inizializzazione>;<condizione>;<aggiornamento> )
    <corpo>
  1.   L'istruzione for esegue inizialmente i comandi <inizializzazione>, dove solitamente sono inizializzate le variabili di controllo.
  2.   Successivamente valuta l'espressione booleana <condizione> che di solito contiene condizioni sulle variabili di ciclo.
    •   Se  <condizione> ha valore true  viene eseguito il comando <corpo>.  Quindi si eseguono i comandi <aggiornamento> che di solito modificano le variabili di controllo; si torna poi al passo 2.
    • Se <condizione> ritorna il valore false, l'esecuzione passa all'istruzione successiva al for



Comando for : Esempi (1)

  • Calcolo di interessi maturati in 20 anni:
for (int i= 1; i<= 20; i++)
  { double interesse = saldo * tasso / 100;
    saldo = saldo + interesse;
  }
  • Il programma Numeri.java visualizza i numeri da 1 a 20 in colonna, mediante il ciclo
for  (x = 1; x <= 20; x = x +1)
     System.out.println (x);
  • Le variabili di controllo dichiarate in <inizializzazione> non sono visibili al di fuori del ciclo
for (int x = 1; x <=10; x = x +1)
    System.out.println (x);
System.out.println (x);

Errore: x non visibile!




Comando for : Esempi (2)

  • Il seguente ciclo visualizza un quadrato di 12 righe per 40 colonne di caratteri "+"
int altezza = 12, larghezza = 40;
for (int i = 0; i < altezza; i++)
    { for (int j = 0; j < larghezza; j++)
         System.out.print("+");
      System.out.println ("");
    }




Relazione tra comandi for e while (1)

Una istruzione for puo' essere vista come una istruzione while generalizzata:
    while ( <condizione> ) <istruzione>
e' del tutto equivalente a
    for ( ; <condizione> ; ) <istruzione>
Analogamente,
    while ( true ) <istruzione>
e' equivalente a
    for ( ; ; ) <istruzione>


Esempio:    InteressiF.java: Programma equivalente a Interessi.java con ciclo while sostituito da ciclo for:
 
 
class InteressiF 

   public static void main(String[] args) 
   {
      double capitale  = 17000;
      double interesse;
      double tasso = 0.07;      //tasso annuale
      for (int anni = 0;  anni < 5;  anni++ ) 
      {
                        interesse = capitale * tasso;
                        capitale += interesse;
                        System.out.println(capitale);
      }
   }
}

 
 
 



Relazione tra comandi for e while (2)

Simmetricamente, un comando for può sempre essere sostituito con un while: il comando
 

for (int i= 1; i<= 20; i++)
  { double interesse = saldo * tasso / 100;
    saldo = saldo + interesse;
  }

è equivalente a
 

int i= 1;
while (i =< 20)
  { double interesse = saldo * tasso / 100;
    saldo = saldo + interesse;
     i++;
   }

 



Relazione tra comandi for e while (3)

Poiché for e while sono equivalenti, la scelta tra i due è essenzialmente una questione di stile di programmazione. E' buona prassi scegliere
 
 
for
Se il numero di volte che bisogna ripetere il <corpo> e' conosciuto nel momento in cui inizia l'esecuzione del comando 
while
In tutti gli altri casi, ad esempio quando il numero di volte che bisogna ripetere il <corpo> dipende da un valore letto all'interno del <corpo>

 
 



Il comando do-while: Sintassi

do 
   <corpo>
while <condizione>;

dove:

  • <corpo> deve sempre essere un blocco, non puo' essere una istruzione semplice o composta. Quindi le parentesi graffe non si possono omettere, anche se c'e' solo una istruzione.

  •  
  • <condizione> è un'espressione di tipo boolean



Comando do-while : Significato

do 
   <corpo>
while <condizione>;
  1.   L'istruzione do-while esegue inizialmente le istruzioni del <corpo>.
  2.   Successivamente valuta la <condizione>.
    • Se la valutazione ritorna il valore true si torna al passo 1.
    • Se la valutazione ritorna il valore false l'esecuzione passa all'istruzione successiva al comando do-while.
Le variabili di controllo vanno inizializzate prima del do-while, e aggiornate nelle istruzioni per permettere la terminazione del ciclo.




Comando do-while : Esempi

Stampa di un intero invertendo le cifre: stampa 654321
int n = 123456;
do {
   System.out.print (n % 10);
   n = n / 10;
}  while (n > 0);
System.out.println ("");

 
 
 
Ripetizione di input finché il valore non è ammissibile
do {
   System.out.println("Inserisci un tasso d'interesse > 0");
   tasso = console.readDouble();
}  while (tasso <= 0);

Analogamente ai cicli for, un ciclo do si può sempre sostituire con un ciclo while. Il seguente è equivalente all'ultimo esempio.
 

double tasso = -1;
while (tasso <= 0) {
    System.out.println("Inserisci un tasso d'interesse > 0");
    tasso = console.readDouble;
}