Uscita forzata da un ciclo

Nel programma di verifica di esistenza di valori negativi, si può fare una osservazione riguardo al numero di istruzioni che vengono effettivamente eseguite. Supponiamo che la funzione sia positiva per x che va da 0 a 34, sia negativa per x=35. Simulando l'esecuzione del programma, si esegue il contenuto del ciclo una prima volta per x che vale 0, e qui la f risulta positiva, e quindi la condizione f<0 è falsa, e la variabile positivo non cambia valore. Lo stesso avviene per x=1, x=2, .... , x=34. Quando si arriva al valore 35, la funzione diventa negativa, per cui la condizione f<0 è verificata, per cui la variabile positivo diventa 0.

Cosa succede sulle successive esecuzioni con x=36,...,100? Se ci sono altri valori di x per i quali la f assume valori negativi, si esegue ancora la istruzione positivo=0, ma la variabile aveva già valore 0. Per i valori positivi, non succede niente. In altre parole, i valori successivi di x non possono cambiare più niente.

In questo caso, una volta raggiunto il primo valore in cui la funzione è negativa, non è necessario controllare i valori successivi. In effetti, il problema di verifica dei valori negativi si può riformulare come: per ogni valore di x, controlla se f(x) è negativa: se lo è, fermati e stampa che la funzione assume valori negativi.

La istruzione break è stata introdotta per permettere di uscire dai cicli senza aspettare che l'ultimo valore sia stato raggiunto. L'uso della istruzione è molto semplice: ogni volta che ci si trova all'interno di un ciclo, se si raggiunge una istruzione break si interrompe il ciclo e si passa direttamente alla prima istruzione che segue il ciclo. Nel caso della verifica di valori negativi, il break si può usare come nel programma SottoZeroBreak.java.

/*
  Dice se una funzione assume valori negativi in un
  certo intervallo
*/

class SottoZeroBreak {
  public static void main(String[] args) {
    int x;
    int f;
    int positivo;

    positivo=1;

    for(x=0; x<=100; x=x+1) {
      f=-x*x+90*x;
      if( f<0 ) {
        positivo=0;
        break;
      }
    }

    if( positivo==1 ) {
      System.out.println("La funzione e' positiva nell'intervallo");
    }
    else {
      System.out.println("La funzione ha valori negativi");
    }
  }
}

L'unica cosa che cambia rispetto al programma precedente SottoZero.java è l'istruzione break all'interno della istruzione condizionale dentro il ciclo. L'effetto di questa istruzione è che si esce dal ciclo se la istruzione viene eseguita, ossia il ciclo si interrompe se la condizione f<0 è verificata.

Possiamo considerare due casi:

  1. la funzione è sempre positiva;
  2. la funzione ha valori negativi.

Nel primo caso, si procede alla valutazione per x che assume valori crescenti da 0 a 100, nei quali la condizione f<0 è sempre falsa, per cui la variabile positivo non cambia mai valore, e la istruzione break non viene mai eseguita (questo fa sí che il ciclo proceda come al solito).

Nel secondo caso, si parte sempre con x=0 e, finchè la funzione è positiva, si procede come al solito. Non appena la x assume un valore per cui f<0, si esegue positivo=0;, e si arriva alla istruzione break; Questa istruzione fa sí che il ciclo venga interrotto sul momento, ossia non si incrementa nuovamente la variabile x, ma si passa direttamente ad eseguire la prima istruzione dopo il ciclo, ossia if( positivo==1 ) ... . Questo è esattamente il comportamento voluto: quando si trova un valore negativo, si esce dal ciclo senza terminare il controllo sui rimanenti valori di x.

Esempio

Stampare il più piccolo valore intero di x nell'intervallo [-100,250] in cui la funzione f(x)=x2-20x assume un valore nullo.

Questo problema si può riformulare come segue: per ogni valore di x che va da -100 a +250, se la funzione vale 0, si stampi il valore di x e si esca dal ciclo. Se la funzione non vale 0, si continua la esecuzione del ciclo. Il programma Zero.java usa un ciclo in cui a seconda del valore di f si decide se uscire dal ciclo oppure no.

/*
  Trova il primo valore di x nell'intervallo [-100,250]
  in cui f(x)=xx-20x+2 vale 0.
*/

class Zero {
  public static void main(String[] args) {
    int x,f;

    for(x=-100; x<=250; x=x+1) {
      f=x*x+20*x;
      if( f==0 ) {
        System.out.println("La funzione vale 0 quando x vale "+x);
        break;
      }
    }
  }
}

In altre parole, si esegue un ciclo con x che va da -100 a +250. Se per un qualche valore si trova che la funzione vale 0, si stampa il valore di x che ha reso nulla la funzione e si esce dal ciclo. Si noti che il break in questo caso è necessario: si veda per esempio il programma ZeroNoBrk.java che è uguale al precedente tranne che per la assenza del break. Compilando ed eseguendo questo secondo programma, si vede che il messaggio viene stampato per tutti i valori di x per i quali la funzione vale zero, e non solo per il primo, come era specificato.