Console 13: for (gli ultimi saranno i primi)


   Abbiamo visto varie istruzioni di controllo:

Non poteva mancare l'istruzione for. L'istruzione for funziona così:


int A = 2;
for(int i =0; i < A; i++){
//istruzione
	}


Il progamma entra nel ciclo for e legge: int i=0 (dichiara ed inizializza una variabile int i col valore 0); i < A (in questo caso A=2); i++
L'istruzione i++ merita una spiegazione tutta per se: per il momento diciamo che significa la cosa seguente: adesso il valore della variabile i è i; fai l'istruzione e, poi, metti i ad i+1 (cioè fai: i = i+1;). Cosa succedde dopo? Il programma torna all'inizio: se i+1 < A, il programma fa l'istruzione, aumenta i di 1, e, dopo, va a verificare se i+1 < A; se sì, effetua l'istruzione, altrimenti esce dal ciclo for
Facciamo un esempio:

for(int i=0; i<2;i++){
	System.out.println("i vale: "+i);
	}


L'output di questo programma è:
i vale 0
i vale 1

Si parte da i=0 ("int i=0"). Se i=0, allora la condizione i<2 è verificata, quindi il programma esegue l'istruzione: "System.out.println("i vale: "+i);"; cioè stampa: "i vale: 0"). Dopodichè il programma aumenta i di 1 (questo è l'istruzione i++). Adesso i vale 1. Il programma testa se la disuguaglianza: i < 2 è verificata. La condizione è verificata. Il programa esegue l'istruzione "System.out.println("i vale: "+i);
Sullo schermo compare: "i vale: 1" Dopodichè il programma aumenta i di 1; quindi i diventa 2.
Il programma riprende il ciclo e verifica se la condizione i < A =2 è verificata. La condizine NON è verificata: il programma esce dal ciclo for.

Vediamo adesso come utilizzare il controllo for per testare se un numero n è, o meno, un numero primo.

Ricordiamo che un numero (intero), n, è primo se e solo se i suoi unici divisori sono 1 e n stesso.

Ricordiamo anche che: "int x =n % r"
assegna ad x il resto di n nella divisione per r. Quindi x =0 se e solo se n è divisibile per r.

Si potrebbe definire un metodo E_Primo(int n) nel modo seguente:


 boolean E_Primo(int n){
	boolean b = true;
	for(int i=2; i < n; i++){
	 if(n % i == 0){
	  b = false;}  //fine if
	}  // fine for
	return b;
	}  //fine metodo


Questo metodo testa, per ogni i, 1 < i < n, se i divide n, in caso di risposta affermativa, il booleano b è impostato su false (notare che unavolta impostato su false, b non può tornare true (altrimenti ci sarebbe un bug)).

Questo metodo non è molto efficiente, per almeno due motivi:
1) Per esempio se n è pari, troviamo subito un divisore (i=2) ed è inutile andare avanti a testare gli altri i, 2 < i < n
2) Se n=ab, con a < = b, allora a < = r :=radice quadrata di n (altrimenti se a > r e b > r, allora ab > r2 = n). Quindi basta fare il test per 1 < i < = r.

Per risolvere il primo problema possiamo usare l'istruzione break (che abbiamo già incontrata con switch); questa istruzione permette di terminare un ciclo for anticipatamente. Per esempio:
 class EsBreak{

 public static void main(String[] arg){

 for(int i=0; i < 100; i++){
 if(i == 4){ break; }
 System.out.println("i : "+i);
 } // fine for
 System.out.println("Fine ciclo");
  } //fine main
 } // fine classe


L'output è:
i: 0
i: 1
i: 2
i: 3 
Fine ciclo

Detto ciò mettiamo insieme il nostro programma:


 public class EPrimo{
 
 public static void main(String[] arg){

 boolean esegui = true;

 while(esegui){
 int n = Leggi.Risposta("Inserisci un numero!");
 if(E_Primo(n) == true){
  System.out.println(" ;-) Il tuo numero e' primo!!");}
 else{
   	System.out.println(" :< Il tuo numero non e' primo");}
 int a = Leggi.Risposta("Continuare? (1) Uscire? (0)");
 if(a == 0){esegui = false;} //per uscire dal ciclo while
	}  // fine del while
 } // fine main

 static boolean E_Primo(int n){
 boolean b = true;
 int r = (int)(Math.sqrt(n));
 for(int i=2; i <= r; i++){
	if(n % i == 0){
	 b = false;
	 break;}
  } // fine for
 return b;
 } // fine metodo
} // fine classe


Osservare che il metodo E_Primo è stato dichiarato static perchè chiamato poi nel main che è static. Come al solito, abbiamo inserito il tutto in un ciclo while, dando all'utente la possibilità di scegliere se continuare od uscire dopo l'esecuzione del programma.