Programmazione e analisi di dati Modulo A: Programmazione in Java
Paolo Milazzo
Dipartimento di Informatica, Universit`a di Pisa http://www.di.unipi.it/∼milazzo
milazzo di.unipi.it
Corso di Laurea Magistrale in Informatica Umanistica
A.A. 2013/2014
Sommario
1
Istruzioni condizionali
2
Espressioni booleane
3
Il comando Switch
4
Errori tipici
In un programma spesso c’e’ bisogno di scegliere tra operazioni diverse Per questo esiste l’istruzione condizionale if-else
Un esempio:
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s S a l d o {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
d o u b l e s a l d o ;
// c h i e d o il s a l d o del c o n t o c o r r e n t e
S y s t e m . out . p r i n t l n (" I n s e r i s c i il s a l d o del tuo c o n t o ");
s a l d o = i n p u t . n e x t D o u b l e ();
if ( saldo > = 0 ) // se il s a l d o e ’ p o s i t i v o S y s t e m . out . p r i n t l n (" Il s a l d o e ’ p o s i t i v o ! ");
e l s e // a l t r i m e n t i
S y s t e m . out . p r i n t l n (" Il s a l d o e ’ n e g a t i v o ! ");
S y s t e m . out . p r i n t l n (" G r a z i e per a v e r u s a t o il n o s t r o s e r v i z i o ");
Istruzioni condizionali (2)
Un’istruzione condizionale if-else ha questa forma:
if (...condizione...) ...comando... else ...comando...
dove:
La condizione ` e detta anche guardia dell’if La guardia pu` o essere vera (true) o falsa (false) I due comandi alternativi sono detti anche rami Il ramo else ` e opzionale (vedremo)
Esempi di guardie “semplici”: le espressioni di confronto
x==10 (la variabile x ` e uguale a 10) – ATTENZ. ==, non = x!=10 (la variabile x ` e diverso da 10)
x<y (la variabile x ` e minore della variabile y)
(x/2)<=10 (l’espressione x/2 ` e minore o uguale a 10)
x>(10/y) (la variabile x ` e maggiore di 10/y)
Istruzioni condizionali (4)
Se in un ramo c’e’ pi` u di una istruzione ci vuole un blocco Sequenza di comandi racchiusi tra parentesi graffe {...}
if ( saldo > = 0 ) {
S y s t e m . out . p r i n t l n (" S a l d o p o s i t i v o ");
d o u b l e i n t e r e s s e A t t i v o = s a l d o * t a s s o A t t i v o ; s a l d o = s a l d o + i n t e r e s s e A t t i v o ;
} e l s e {
S y s t e m . out . p r i n t l n (" S a l d o n e g a t i v o ");
d o u b l e i n t e r e s s e P a s s i v o = s a l d o * t a s s o P a s s i v o ; s a l d o = saldo - i n t e r e s s e P a s s i v o ;
}
S y s t e m . out . p r i n t (" N u o v o s a l d o : ");
S y s t e m . out . p r i n t l n ( s a l d o );
I comandi if-else possono essere annidati
Si pu` o inserire un if-else in un ramo di un altro if-else
if ( saldo > = 0 ) if ( saldo >0)
S y s t e m . out . p r i n t l n (" S a l d o p o s i t i v o ! ");
e l s e
S y s t e m . out . p r i n t l n (" S a l d o z e r o ! ");
e l s e
S y s t e m . out . p r i n t l n (" S a l d o n e g a t i v o ! ");
Note:
non servono le parentesi perch` e if-else ` e un unico comando
ATTENZIONE: ogni else fa riferimento all’if a lui pi` u vicino
L’uso attento di spazi e “a capo” nel programma (indentazione)
semplifica la lettura e la comprensione del codice
Istruzioni condizionali (6)
Un caso particolare di if-else annidati sono gli if-else concatenati il ramo else ` e costituito da un altro if
la guardia del secondo if considera un caso alternativo a quello considerato dalla guardia del primo if
if ( saldo >0)
S y s t e m . out . p r i n t l n (" S a l d o p o s i t i v o ! ");
e l s e if ( s a l d o = = 0 )
S y s t e m . out . p r i n t l n (" S a l d o z e r o ! ");
e l s e
S y s t e m . out . p r i n t l n (" S a l d o n e g a t i v o ! ");
Notare l’indentazione:
Di solito si scrive else if nella stessa riga
Istruzioni condizionali (8)
Il ramo else ` e opzionale
if ( saldo > = 0 )
S y s t e m . out . p r i n t l n (" S a l d o p o s i t i v o ! ");
S y s t e m . out . p r i n t l n (" G r a z i e per a v e r u s a t o il n o s t r o s e r v i z i o ");
Ma quando si annida un if in un if-else bisogna fare attenzione possono servire le parentesi graffe...
if ( saldo > = 0 ) { if ( saldo >0)
s a l d o = s a l d o + i n t e r e s s e ; }
e l s e
s a l d o = saldo - p e n a l e ;
In quale caso la penale viene applicata se togliamo le parentesi graffe?
Esempio d’uso
Per controllare valori ricevuti in input dall’utente
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s D i v i s i o n e {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
int num1 , n u m 2 ;
S y s t e m . out . p r i n t l n (" I n s e r i s c i due n u m e r i i n t e r i : ");
n u m 1 = i n p u t . n e x t I n t ();
n u m 2 = i n p u t . n e x t I n t ();
// c o n t r o l l a che n u m 2 sia d i v e r s o da z e r o // p r i m a di c a l c o l a r e n u m 1 / n u m 2
if ( n u m 2 = = 0 ) {
S y s t e m . out . p r i n t l n (" E R R O R E : d i v i s i o n e per z e r o ");
} e l s e {
S y s t e m . out . p r i n t (" Q u o z i e n t e : ");
S y s t e m . out . p r i n t l n ( n u m 1 / n u m 2 );
S y s t e m . out . p r i n t (" R e s t o : ");
S y s t e m . out . p r i n t l n ( n u m 1 % n u m 2 );
} } }
1
Istruzioni condizionali
2
Espressioni booleane
3
Il comando Switch
4
Errori tipici
Guardie complesse (1)
Abbiamo visto che possiamo esprimere la guardia di un comando if tramite delle semplici espressioni di confronto:
saldo>0, x==y, ecc...
E se dobbiamo esprimere condizioni pi` u complesse?
Esempio:
Scrivere un programma che chiede all’utente di inserire due numeri interi (ore e minuti) e stampa "E’ un orario" se le due cifre rappresentano un orario corretto, oppure stampa
"Non e’ un orario" altrimenti.
Input: 15 27 Output: E’ un orario
Input: 37 97 Output: Non e’ un orario
Primo modo: if concatenati
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s O r a r i o {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
int ore , m i n u t i ;
S y s t e m . out . p r i n t l n (" I n s e r i r e ore e m i n u t i : ");
ore = i n p u t . n e x t I n t ();
m i n u t i = i n p u t . n e x t I n t ();
if ( ore <0)
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
e l s e if ( ore > 2 3 )
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
e l s e if ( minuti <0)
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
e l s e if ( minuti > 5 9 )
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
e l s e
S y s t e m . out . p r i n t l n (" E ’ un o r a r i o ");
Guardie complesse (3)
Secondo modo: operatore logico || (OR)
Combina condizioni delle quali almeno una deve essere vera
if ( ( ore <0) || ( ore > 2 3 ) || ( minuti <0) || ( minuti > 5 9 ) ) S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
e l s e
S y s t e m . out . p r i n t l n (" E ’ un o r a r i o ");
Terzo modo: operatore logico && (AND)
Combina condizioni che devono essere tutte vere
if ( ( ore > = 0 ) && ( ore < 2 4 ) && ( minuti > = 0 ) && ( minuti < 6 0 ) ) S y s t e m . out . p r i n t l n (" E ’ un o r a r i o ");
e l s e
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
Quarto modo: variabili di tipo boolean
Memorizzano il risultato di una espressione booleana
b o o l e a n o r e _ o k = ( ore > = 0 ) && ( ore < 2 4 ) ;
b o o l e a n m i n u t i _ o k = ( minuti > = 0 ) && ( minuti < 6 0 ) ; if ( o r e _ o k && m i n u t i _ o k )
S y s t e m . out . p r i n t l n (" E ’ un o r a r i o ");
e l s e
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
Quinto modo: operatore logico ! (NOT)
Nega l’espressione booleana seguente (trasforma true in false e viceversa)
b o o l e a n o r e _ o k = ( ore > = 0 ) && ( ore < 2 4 ) ;
b o o l e a n m i n u t i _ o k = ( minuti > = 0 ) && ( minuti < 6 0 ) ; if ( ! o r e _ o k || ! m i n u t i _ o k )
S y s t e m . out . p r i n t l n (" Non e ’ un o r a r i o ");
e l s e
S y s t e m . out . p r i n t l n (" E ’ un o r a r i o ");
Espressioni booleane
Riassumendo, un’espressione booleana pu` o consistere di:
Letterali:
I
true
I
false
Variabili booleane (tipo boolean):
I
isOk, trovato, x,....
Confronti:
I
x==0
I
num1<num2
I
(x%2)==0
I
((lordo-netto)/lordo)<(sconto_max/lordo)
I
...
Operazioni logiche (dove eb1 e eb2 sono espressioni booleane):
I
eb1 || eb2
I
eb1 && eb2
I
!eb1
Il risultato delle operazioni logiche ` e riassunto dalle seguenti tavole di verit` a A||B A true A false
B true true true
B false true false
A&&B A true A false
B true true false
B false false false
A !A
true false
false true
Esempi
Assumendo
int i = 1 0 ;
b o o l e a n b1 =t r u e; b o o l e a n b2 = i <5;
quali delle seguenti sono espressioni booleane sintatticamente corrette?
5 f a l s e i ==7 b2 ||( i >7)
( b2 ==t r u e) | | ( i >7) ( 3 + 2 ) & & ( 7 - 4 )
! b1
( b1 && b2 ) | | ( ( i +2) >11)
Tra quelle corrette, quali sono vere?
Un programma che controlla temperatura corporea e battito cardiaco
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s S a l u t e {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
S y s t e m . out . p r i n t l n (" I n s e r i s c i il la t e m p e r a t u r a c o r p o r e a ");
d o u b l e f e b b r e = i n p u t . n e x t D o u b l e ();
S y s t e m . out . p r i n t l n (" I n s e r i s c i i b a t t i t i c a r d i a c i al m i n u t o ");
int b a t t i t o = i n p u t . n e x t I n t ();
b o o l e a n f e b b r e N o , f e b b r e B a s s a , f e b b r e A l t a ; b o o l e a n b a t t i t o O K , b a t t i t o A c c e l e r a t o ; f e b b r e N o = febbre < 3 7 . 0 ;
f e b b r e B a s s a = ( febbre > = 3 7 ) & & ( febbre < 3 8 ) ; f e b b r e A l t a = febbre > = 3 8 ;
b a t t i t o O K = battito < 8 0 ;
b a t t i t o A c c e l e r a t o = battito > = 8 0 ;
Esempio d’uso (2)
. . . . c o n t i n u a . . . . .
if ( f e b b r e N o && b a t t i t o O K )
S y s t e m . out . p r i n t l n (" T u t t o OK ");
e l s e if (( f e b b r e B a s s a && b a t t i t o A c c e l e r a t o ) | | ( f e b b r e A l t a )) S y s t e m . out . p r i n t l n (" S t a t o f e b b r i l e ");
e l s e
S y s t e m . out . p r i n t l n (" S t a t o f e b b r i l e l i e v e ");
} }
In quali casi stampa "Stato febbrile lieve" ?
1
Istruzioni condizionali
2
Espressioni booleane
3
Il comando Switch
4
Errori tipici
Quanti if...
In alcuni casi un comando if pu` o diventare un po’ lungo da scrivere:
Esempio: un programma che legge un numero e lo trasforma in un giorno
i m p o r t j a v a . u t i l . S c a n n e r ; p u b l i c c l a s s G i o r n o {
p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) { S c a n n e r i n p u t = new S c a n n e r ( S y s t e m . in );
S y s t e m . out . p r i n t l n (" I n s e r i s c i un n u m e r o [1 -7] ");
int g i o r n o = i n p u t . n e x t I n t ();
if ( g i o r n o = = 1 ) S y s t e m . out . p r i n t l n (" L u n e d i ");
e l s e if ( g i o r n o = = 2 ) S y s t e m . out . p r i n t l n (" M a r t e d i ");
e l s e if ( g i o r n o = = 3 ) S y s t e m . out . p r i n t l n (" M e r c o l e d i ");
e l s e if ( g i o r n o = = 4 ) S y s t e m . out . p r i n t l n (" G i o v e d i ");
e l s e if ( g i o r n o = = 5 ) S y s t e m . out . p r i n t l n (" V e n e r d i ");
e l s e if ( g i o r n o = = 6 ) S y s t e m . out . p r i n t l n (" S a b a t o ");
e l s e if ( g i o r n o = = 7 ) S y s t e m . out . p r i n t l n (" D o m e n i c a ");
e l s e S y s t e m . out . p r i n t l n (" N u m e r o e r r a t o ");
} }
Un if concatenato che confronta
il risultato di una espressione di tipo int o char (vedremo) con un numero di letterali alternativi (ad es. 1,2,3,...) pu` o essere sostituito da un comando switch
s w i t c h ( g i o r n o ) {
c a s e 1: S y s t e m . out . p r i n t l n (" L u n e d i "); b r e a k; c a s e 2: S y s t e m . out . p r i n t l n (" M a r t e d i "); b r e a k; c a s e 3: S y s t e m . out . p r i n t l n (" M e r c o l e d i "); b r e a k; c a s e 4: S y s t e m . out . p r i n t l n (" G i o v e d i "); b r e a k; c a s e 5: S y s t e m . out . p r i n t l n (" V e n e r d i "); b r e a k; c a s e 6: S y s t e m . out . p r i n t l n (" S a b a t o "); b r e a k; c a s e 7: S y s t e m . out . p r i n t l n (" D o m e n i c a "); b r e a k;
d e f a u l t: S y s t e m . out . p r i n t l n (" N u m e r o e r r a t o ");
}
Il comando break fa saltare l’esecuzione alla parentesi graffa chiusa Evita, ad esempio, che dopo aver eseguito il caso 3 venga eseguito anche il 4
Tra l’etichetta case N: e il comando break ci pu` o essere pi` u di un
Il comando “switch” (2)
Il comando switch consente di accorpare casi in maniera abbastanza semplice
s w i t c h ( g i o r n o ) {
c a s e 1: c a s e 2: c a s e 3: c a s e 4: c a s e 5:
S y s t e m . out . p r i n t l n (" G i o r n o l a v o r a t i v o "); b r e a k; c a s e 6:
S y s t e m . out . p r i n t l n (" G i o r n o p r e f e s t i v o "); b r e a k; c a s e 7:
S y s t e m . out . p r i n t l n (" G i o r n o f e s t i v o "); b r e a k;
d e f a u l t:
S y s t e m . out . p r i n t l n (" N u m e r o e r r a t o ");
}
1
Istruzioni condizionali
2
Espressioni booleane
3
Il comando Switch
4
Errori tipici
Istruzioni condizionali: errori tipici (1)
Vediamo alcuni errori tipici nell’uso delle istruzioni condinali:
Uso dell’operatore di assegnamento invece che di confronto
if ( x =0)
S y s t e m . out . p r i n t l n (" x v a l e 0 ");
if con comando vuoto
if ( x = = 0 ) ;
S y s t e m . out . p r i n t l n (" x v a l e 0 ")
if-else senza blocchi (parentesi graffe)
if ( x <= y ) // m a n c a { S y s t e m . out . p r i n t ( x );
S y s t e m . out . p r i n t (" e ’ m i n o r e o u g u a l e di ");
S y s t e m . out . p r i n t l n ( y );
// m a n c a } e l s e // m a n c a {
S y s t e m . out . p r i n t ( x );
S y s t e m . out . p r i n t (" e ’ m a g g i o r e di ");
S y s t e m . out . p r i n t l n ( y );
// m a n c a }
omissione di else
if ( y = = 0 )
S y s t e m . out . p r i n t l n (" D i v i s i o n e per z e r o non c o n s e n t i t a ");
// m a n c a e l s e
S y s t e m . out . p r i n t l n ( x / y );
omissione di break
s w i t c h ( g i o r n o ) {
c a s e 1: c a s e 2: c a s e 3: c a s e 4: c a s e 5:
S y s t e m . out . p r i n t l n (" G i o r n o l a v o r a t i v o "); // m a n c a b r e a k ; c a s e 6:
S y s t e m . out . p r i n t l n (" G i o r n o p r e f e s t i v o "); // m a n c a b r e a k ; c a s e 7:
S y s t e m . out . p r i n t l n (" G i o r n o f e s t i v o "); // m a n c a b r e a k ; d e f a u l t:
S y s t e m . out . p r i n t l n (" N u m e r o e r r a t o ");
}