Flusso di esecuzione=successione di esecuzione delle istruzioni.
Finora:
Ora vediamo i condizionali: fare qualcosa in base a una condizione.
Questo programma stampa a oppure un messaggio.
class PrimoCond { public static void main(String args[]) { int a; a=-3; if(a < 0) { System.out.println("Il numero e' negativo"); } else { System.out.println(a); } } }
A parole: se una condizione è vera fai una cosa, altrimenti fanne un'altra.
Parti di questa frase:
La seconda e la terza parte sono sequenze di istruzioni.
if (condizione) { istruzioni } else { istruzioni }
Esempi di condizioni:
a < b a+b/2-4 >= 9 a == 3+2
Una condizione è una espressione che può essere vera o falsa.
Condizioni elementari:
espressione1 confronto espressione2
espressione1 ed espressione2 sono espressioni
Confronti possibili:
> >= == != < <=
Note: >= si scrive con i due caratteri > ed = senza mettere spazi fra i due
== significa uguale, != significa diverso.
Una condizione può essere vera o falsa, e può dipendere dai valori delle variabili.
Attenzione! la condizione 0>1 è falsa, non è un errore!
a=0; if(a==0) ...
Differenza:
La prima è una istruzione (un comando), la seconda è una domanda.
Leggere due interi, e fare la divisione se possibile, altrimenti stampare messaggio di errore.
Forma della istruzione condizionale:
if(condizione) { istruzioni; } else { istruzioni; }
Primo: si leggono due interi.
import javax.swing.*; class Dividi { public static void main(String args[]) { int x, y; String s; s=JOptionPane.showInputDialog("Dividendo"); x=Integer.parseInt(s); s=JOptionPane.showInputDialog("Divisore"); y=Integer.parseInt(s); // qui va fatta la divisione } }
Se y vale 0 si deve solo stampare il messaggio di errore.
if(y==0) { System.out.println("Il divisore deve essere diverso da zero"); } else { System.out.println(x/y); }
import javax.swing.*; class Dividi { public static void main(String args[]) { int x, y; String s; s=JOptionPane.showInputDialog("Dividendo"); x=Integer.parseInt(s); s=JOptionPane.showInputDialog("Divisore"); y=Integer.parseInt(s); if(y==0) { System.out.println("Il divisore deve essere diverso da zero"); } else { System.out.println(x/y); } System.exit(0); } }
Si poteva anche fare:
if(y!=0) { System.out.println(x/y); } else { System.out.println("Il divisore deve essere diverso da zero"); }
Condizioni opposte:
Condizione | Opposto |
---|---|
== | != |
>= | < |
<= | > |
> non è il contrario di <
Indica il percorso delle istruzioni da eseguire.
Il blocco if (...) {...} else {...} si comporta come una unica istruzione.
Quindi, una volta finito, is passa comunque alla istruzione successiva.
La parte else {...} si può omettere.
Equivale a scrivere else { }, ossia parte else senza istruzioni.
Esempio:
if(x<0) { System.out.println("Numero negativo"); } System.out.println("Programma terminato");
Cosa viene stampato?
Se a è negativo: vengono stampate tutte e due le stringhe.
Altrimenti, viene stampata la seconda.
Se la parte else non c'è, è come se fosse vuota.
Di solito, viene più comodo disegnato cosí:
Se x<0 si esegue la prima println
Altrimenti no
In ogni caso si passa ad eseguire l'istruzione dopo tutto l'if
Scrivere un programma che prende due numeri, e stampa solo quelli positivi, e poi stampa la somma dei due comunque.
Per ogni intero letto, lo devo stampare solo se è positivo; poi stampo la somma (anche se sono negativi).
Se è negativo non lo stampo, ma passo comunque al successivo.
Posso usare due if senza else
Devo fare tre cose:
stampa il primo se positivo stampa il secondo se positivo stampa la somma
Vanno fatte in sequenza, e vanno fatte tutte e tre!
La terza di traduce direttamente
La prima is realizza con un if
if(x>=0) { System.out.println(x); }
Lo stesso per la seconda
Faccio la sequenza dei tre passi
import javax.swing.*; class DuePos { public static void main(String args[]) { String s; int x, y; s=JOptionPane.showInputDialog("Dammi un numero"); x=Integer.parseInt(s); s=JOptionPane.showInputDialog("Dammi un numero"); y=Integer.parseInt(s); if(x>=0) { System.out.println(x); } if(y>=0) { System.out.println(x); } System.out.println(x+y); System.exit(0); } }
Siamo partiti dalla sequenza:
stampa il primo se positivo stampa il secondo se positivo stampa la somma
Poi abbiamo sviluppato ognuno dei tre punti.
Per realizzare il punto 1, non ci serve sapere che ci sono anche gli altri due
Potevamo fare finta che gli altri due punti non ci fossero.
Vantaggio: ci possiamo concentrare su un sottoproblema per volta.
Costrutto, in generale:
if(condizione) istruzione1; else istruzione2;
Altra regola generale:
dove si può mettere una istruzione, si può mettere una sequenza fra graffe
Ultima regola:
dove si può mettere una istruzione, si può mettere un condizionale
Quindi, all'interno di un condizionale si può mettere un altro condizionale
In questo caso, è meglio usare le graffe (vedremo poi il perchè)
Creare una classe QuadPoint che ha le stesse componenti di Point, ma in più un metodo che ritorna 1 se il punto sta nel primo quadrante, altrimenti 0.
Il problema non è facile?
Una parte per volta!
Se x è positivo, cosa si ritorna?
Si ritorna 1 se anche y è positivo, altrimenti 0
Se x è negativo, si ritorna 0
class PointQuad { int x; int y; int quadrante() { if(this.x>=0) { if(this.y>=0) { return 1; } else { return 0; } } else { return 0; } } }
Interpretazione: ad alto livello, si tratta di un if
if(this.x>=0) { ... else { return 0; }
In cui la sequenza da eseguire in caso la condizione sia vera è un altro if:
if(this.y>=0) { return 1; } else { return 0; }
In questo programma non abbiamo usato istruzioni nuove.
Abbiamo solo composto le istruzioni già viste.
Soluzione alternativa più semplice:
class PointQuad { int x; int y; int quadrante() { if(this.x>=0) if(this.y>=0) return 1; return 0; } }
Funziona perchè:
In questo esempio: se this.x è positivo e this.y è positivo, allora fai una certa cosa.
La cosa da fare dipende da due condizioni this.x>=0 e this.y>=0
Se sia this.x>=0 che this.y>=0 sono vere si deve ritornare 1, altrimenti 0
Quando voglio fare una cosa se due condizioni sono tutte e due vere, le combino con && (and)
class PointQuad { int x; int y; int quadrante() { if( (this.x>=0) && (this.y>=0) ) return 1; else return 0; } }
Se ho due condizioni c1 e c2, allora c1 || c2 è vera se lo è almeno una delle due.
Leggere due interi, stampare la somma se almeno uno dei due è positivo.
La stampa va fatta se la condizione x>=0, ma anche se y>=0 è vera.
La condizione composta (x>=0) || (y>=0) è vera se lo è almeno una delle due condizioni che la compongono.
import javax.swing.*; class UnPos { public static void main(String args[]) { String s; int x, y; s=JOptionPane.showInputDialog("Dammi un numero"); x=Integer.parseInt(s); s=JOptionPane.showInputDialog("Dammi un numero"); y=Integer.parseInt(s); if( (x>=0) || (y>=0) ) { System.out.println(x+y); } System.exit(0); } }
Si poteva fare anche senza:
if(x>=0) { System.out.println(x+y); } if(y>=0) { System.out.println(x+y); }
La soluzione che usa || è più semplice e più facile da leggere.
if(cond) istr1; else istr2;
La seconda istruzione può essere un altro if
Cascata di istruzioni condizionali:
if(cond) istr; else if(cond) istr; else if(cond) istr; else istr;
Dato un numero intero maggiore o uguale a zero, stampare il suo valore in lettere, se è minore di cinque.
Se il numero è superiore a cinque, stampare un messaggio di errore.
Confronto il valore con 0, poi 1, ecc.
class Lettere { public static void main(String args[]) { int n=3; if(n==0) System.out.println("zero"); else if(n==1) System.out.println("uno"); else if(n==2) System.out.println("due"); else if(n==3) System.out.println("tre"); else if(n==4) System.out.println("quattro"); else if(n==5) System.out.println("cinque"); else System.out.println("non lo stampo, questo numero"); } }
Cosa significa questo programma?
if(cond1) if(cond2) istr1; else istr2;
Mettere le graffe e l'indentazione.
Due soluzioni possibili.
Prima soluzione:
if(cond1) { if(cond2) istr1; } else istr2;
Seconda soluzione:
if(cond1) { if(cond2) istr1; else istr2; }
Regola di Java: l'else si considera il ramo ``condizione falsa'' dell'ultimo if.
Quindi, istr2 viene eseguito solo se cond1 è vera ma cond2 è falsa.
Cosa stampa questo programma?
if(x>=0) if(x<=10) System.out.println("Il numero sta fra 0 e 10"); else System.out.println("Il numero e' negativo");
L'indentazione può trarre in inganno.
L'else fa parte dell'ultimo if:
if(x>=0) { if(x<=10) System.out.println("Il numero sta fra 0 e 10"); else System.out.println("Il numero e' negativo"); }
Il programma è quindi sbagliato.
Questo errore viene prima o poi commesso.
Per trovare un errore, occorre ``mettersi nei panni del computer'', ossia eseguire le istruzioni nello stesso modo in cui lo fa lui.
Dato che lui attacca l'else all'ultimo if, il programma stampa che il numero è negativo quando invece è positivo ma maggiore di dieci.
Per una persona è chiaro cosa andava fatto sulla base delle stringhe stampate.
Per il calcolatore le stringhe sono solo sequenze di caratteri. L'interpretazione delle istruzioni è meccanica.