6 - Blocchi e cicli
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. 2014/2015
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 1 / 30
Sommario
1 Blocchi e visibilita’ delle variabili
2 Comandi iterativi (cicli) Il comando while Il comando for
Blocchi (1)
Abbiamo visto che se in un ramo di un if devono essere eseguiti pi`u comandi ci vuole un blocco
Unblocco`e una sequenza di comandi racchiusa 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 ;
}
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 3 / 30
Blocchi (2)
Il corpo del metodomain `e un altro esempio di blocco
s t a t i c p u b l i c v o i d m a i n ( S t r i n g [] a r g s ) { . . . . .
}
Un blocco pu`o essere inserito tra gli altri comandi del programma
S y s t e m . out . p r i n t l n (" P r i m a del b l o c c o ");
{
S y s t e m . out . p r i n t l n (" D e n t r o ... ");
S y s t e m . out . p r i n t l n (" ... al b l o c c o ");
}
S y s t e m . out . p r i n t l n (" F u o r i del b l o c c o ");
Inoltre, i blocchi possono essere annidati (uno dentro l’altro)
S y s t e m . out . p r i n t l n (" F u o r i dai b l o c c h i ");
{
S y s t e m . out . p r i n t l n (" Nel p r i m o b l o c c o ");
{
S y s t e m . out . p r i n t l n (" Nel s e c o n d o ... ");
S y s t e m . out . p r i n t l n (" ... b l o c c o ");
}
S y s t e m . out . p r i n t l n (" Di n u o v o nel p r i m o b l o c c o ");
}
S y s t e m . out . p r i n t l n (" F u o r i dai b l o c c h i ");
Variabili locali
Una propriet`a importante dei blocchi `e la seguente:
le variabili dichiarate in un blocco sonolocali al bloccoe, quindi, scompaiono dopo l’esecuzione del blocco
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 = s a l d o * t a s s o ; s a l d o = s a l d o + i n t e r e s s e ;
}
S y s t e m . out . p r i n t l n ( i n t e r e s s e ); // E R R O R E !
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 5 / 30
Visibilit` a delle variabili (1)
Si pu`o definire una nozione di visibilit`a (oscope) di una variabile
Lavisibilit`a(oscope) di una variabile `e la porzione di programmain cui tale variabile pu`o essere utilizzata
La visibilit`a di una variabile locale(cio`e definita in un blocco) `e la porzione di programma che va dalla dichiarazione della variabile stessaalla fine del blocco che la contiene
NOTA: Anche il corpo del metodo main `e un blocco!
Le variabili usate fino ad ora erano localial metodo main
Visibilit` a delle variabili (2)
Limitare la visibilit`a di una variabile al blocco che la contiene consente di riutilizzare nomi di variabiliin parti diverse del programma
anche con tipi diversi
b o o l e a n l e g g i I n t e r o = . . . . ; if ( l e g g i I n t e r o ) {
int val = i n p u t . n e x t I n t ();
S y s t e m . out . p r i n t (" Il n u m e r o l e t t o e ’: ");
S y s t e m . out . p r i n t l n ( val );
} e l s e {
d o u b l e val = 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 (" Il n u m e r o l e t t o e ’: ");
S y s t e m . out . p r i n t l n ( val );
}
Tutto ci`o sar`a particolarmente utile nei cicli e nei programmi costituiti da pi`u classi e metodi... (vedremo)
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 7 / 30
Visibilit` a delle variabili (3)
ATTENZIONE: Le variabili dichiarate in un blocco non possono avere il nome di variabili esterne al blocco stesso
Il compilatore segnalerebbe un errore
int a =0;
{
int a =0; // E R R O R E : v a r i a b i l e gia ’ d i c h i a r a t a int b = 1 0 ;
S y s t e m . out . p r i n t l n ( a + b );
}
Sommario
1 Blocchi e visibilita’ delle variabili
2 Comandi iterativi (cicli) Il comando while Il comando for
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 9 / 30
Ripetere, ripetere, ripetere...
Tempo fa abbiamo visto il seguente programma Somma, che calcola la somma di due numeri
E se volessimo sommare un numero arbitrario di numeri (a scelta dell’utente)?
Serve un comando per poterITERARE (ripetere) pi`u volte delle operazioni
Vogliamo quindi realizzare dei CICLI
Il comando while (1)
Il comando while consente di ripetere un comando (o un blocco) fintanto che una condizione specificata `e vera
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 o m m a N u m e r i {
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 (" Q u a n t i n u m e r i v u o i s o m m a r e ? ");
int n u m e r i = i n p u t . n e x t I n t ();
int c o n t =0; // v a r i a b i l e da u s a r e c o m e c o n t a t o r e int s o m m a =0; // v a r i a b i l e da u s a r e c o m e a c c u m u l a t o r e
w h i l e ( cont < n u m e r i ) { // f i n t a n t o che c o n t e ’ m i n o r e di n u m e r i S y s t e m . out . p r i n t l n (" I n s e r i s c i il p r o s s i m o n u m e r o ");
int n = i n p u t . n e x t I n t ();
s o m m a = s o m m a + n ; // a g g i o r n a l ’ a c c u m u l a t o r e c o n t = c o n t +1; // i n c r e m e n t a il c o n t a t o r e }
S y s t e m . out . p r i n t l n ( s o m m a );
} }
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 11 / 30
Il comando while (2)
Il comando while ha la seguente forma:
while (...condizione...) ...comando....
dove:
La condizione `e detta ancheguardia del while
La guardia pu`o essere una qualunqueespressione booleana Il comando (o blocco) `e detto corpodel while
Semantica del comando:
1. La guardia viene valutata
2. Se la guardia `e vera si esegue il corpo e si ricomincia dal punto 1 3. Se la guardia `e falsa si salta il corpo e si procede con l’istruzione
successiva al while
Il comando while (3)
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 13 / 30
Comandi di assegnamento ausiliari (1)
Nel programma SommaNumeri abbiamo visto i seguenti comandi:
s o m m a = s o m m a + n ; // a g g i o r n a l ’ a c c u m u l a t o r e c o n t = c o n t +1; // i n c r e m e n t a il c o n t a t o r e
Quando si usano i cicli, questo tipo di assegnamenti diventano frequenti.
Per questo in Java esistono dei comandi di assegnamento ausiliari (abbreviazioni sintattiche) che semplificano un po’ la scrittura:
s o m m a += n ; // c o r r i s p o n d e a s o m m a = s o m m a + n c o n t ++; // c o r r i s p o n d e a c o n t = c o n t +1
In maniera analoga abbiamo
x -= y // c o r r i s p o n d e a x = x - y x *= y // c o r r i s p o n d e a x = x * y x /= y // c o r r i s p o n d e a x = x / y i - - // c o r r i s p o n d e a i = i -1
Nota: esistono anche le forme prefisse ++i e --i che hanno senso quando si usano le operazioni di assegnamento all’interno di espressioni. Questa per`o non `e in generale una
Comandi di assegnamento ausiliari (2)
Modifichiamo il programma usando i comandi di assegnamento ausiliari
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 o m m a N u m e r i 2 {
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 (" Q u a n t i n u m e r i v u o i s o m m a r e ? ");
int n u m e r i = i n p u t . n e x t I n t ();
int c o n t =0; // v a r i a b i l e da u s a r e c o m e c o n t a t o r e int s o m m a =0; // v a r i a b i l e da u s a r e c o m e a c c u m u l a t o r e
w h i l e ( cont < n u m e r i ) { // f i n t a n t o che c o n t e ’ m i n o r e di n u m e r i S y s t e m . out . p r i n t l n (" I n s e r i s c i il p r o s s i m o n u m e r o ");
int n = i n p u t . n e x t I n t ();
s o m m a += n ; // a g g i o r n a l ’ a c c u m u l a t o r e ( con +=) c o n t ++; // i n c r e m e n t a il c o n t a t o r e ( con ++) }
S y s t e m . out . p r i n t l n ( s o m m a );
} }
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 15 / 30
Esempio d’uso (1)
Negozio di Caramelle:
abbiamo 100 caramelle da vendere al prezzo di 50 cent l’una i clienti arrivano uno dopo l’altro e possono comprare quante caramelle vogliono (fino ad esaurimento)
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 C a n d y S h o p {
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 c a r a m e l l e = 1 0 0 ; // c a r a m e l l e in m a g a z z i n o
f i n a l d o u b l e P R E Z Z O = 0 . 5 ; // p r e z z o s i n g o l a c a r a m e l l a in e u r o w h i l e ( c a r a m e l l e >0) { // f i n t a n t o che non ho e s a u r i t o le c a r a m e l l e
S y s t e m . out . p r i n t (" S o n o d i s p o n i b i l i ");
S y s t e m . out . p r i n t ( c a r a m e l l e );
S y s t e m . out . p r i n t l n (" c a r a m e l l e ");
S y s t e m . out . p r i n t l n (" Q u a n t e ne v u o i c o m p r a r e ? ");
int num = i n p u t . n e x t I n t ();
. . . . c o n t i n u a . . . . .
Esempio d’uso (2)
. . . . c o n t i n u a . . . . .
if ( num <0) // c o n t r o l l a l ’ i n p u 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 ");
e l s e {
if ( num > c a r a m e l l e ) { num = c a r a m e l l e ;
S y s t e m . out . p r i n t l n (" Hai c h i e s t o t r o p p e c a r a m e l l e ");
S y s t e m . out . p r i n t (" Te ne d a r o ’ s o l t a n t o ");
S y s t e m . out . p r i n t l n ( num );
}
c a r a m e l l e -= num ; // p r e l e v a le c a r a m e l l e dal m a g a z z i n o S y s t e m . out . p r i n t (" C o s t o : ");
S y s t e m . out . p r i n t ( num * P R E Z Z O );
S y s t e m . out . p r i n t l n (" e u r o ");
} }
// a q u e s t o p u n t o il c i c l o e ’ t e r m i n a t o
// c i o e ’ le c a r a m e l l e s o n o e s a u r i t e ( c a r a m e l l e < = 0 ) S y s t e m . out . p r i n t l n (" C A R A M E L L E T E R M I N A T E ! ");
} }
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 17 / 30
I cicli do-while (1)
Quando siamo sicuri che il corpo di un ciclo deve essere eseguito almeno una volta possiamo usare un do-while
Modifichiamo l’esempio SommaNumeri in modo che continui a sommare numeri finch`e l’utente non inserisce un numero negativo
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 o m m a N u m e r i 3 {
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 s o m m a =0; // v a r i a b i l e da u s a r e c o m e a c c u m u l a t o r e int n ; // v a r i a b i l e che m e m o r i z z a i n u m e r i i n s e r i t i
/* N O T A : n d e v e e s s e r e d i c h i a r a t a qui per e s s e r e v i s i b i l e n e l l a g u a r d i a del w h i l e */
do {
S y s t e m . out . p r i n t l n (" I n s e r i s c i il p r o s s i m o n u m e r o ");
n = i n p u t . n e x t I n t ();
if ( n > = 0 ) s o m m a += n ; // a g g i o r n a l ’ a c c u m u l a t o r e se n >=0 } w h i l e ( n > = 0 ) ; // c i c l a f i n t a n t o che n non e ’ n e g a t i v o S y s t e m . out . p r i n t l n ( s o m m a );
}
I cicli do-while (2)
Il comando do-while ha la seguente forma:
do ....comando.... while (...condizione...) dove:
La condizione `e detta ancheguardia del do-while
La guardia pu`o essere una qualunqueespressione booleana Il comando (o blocco) `e detto corpodel do-while
Semantica del comando:
1. Il corpo viene eseguito 2. La guardia viene valutata
2. Se la guardia `e vera si ricomincia dal punto 1
3. Se la guardia `e falsa si procede con l’istruzione successiva al while
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 19 / 30
I cicli do-while (3)
Sommario
1 Blocchi e visibilita’ delle variabili
2 Comandi iterativi (cicli) Il comando while Il comando for
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 21 / 30
Quante iterazioni fa un ciclo?
Quando scriviamo un ciclo while, in generale potremmo non sapere quante iterazioni esso far`a
Esempio: in CandyShop il numero di iterazioni dipende da quante caramelle “compra” ad ogni passo l’utente
Iterazione indeterminata: “corro finch`e ho fiato...”
In alcuni casi, invece, il numero di iterazioni `e noto a priori
Esempio: in SommaNumeri si chiede all’utente quanti numeri voglia sommare, e il numero inserito dall’utente diventa esattamente il numero di iterazioni del ciclo.
Iterazione determinata: “corro per 10 giri di campo...”
Quando il numero di iterazioni `e noto a priori, in alternativa al while possiamo usare il comando for
I cicli for (1)
Il comando for ha la seguente forma:
for ( ..cmdIniz.. ; ..condiz.. ; ..cmdAgg.. ) ...corpo...
dove:
cmdIniz `e un comando eseguito all’inizio del ciclo condiz `e la guardiadel ciclo
La guardia pu`o essere una qualunqueespressione booleana cmdAgg un comando eseguitoad ogni iterazione (Agg sta per aggiornamento)
Il corpo pu`o essere un singolo comando o un blocco
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 23 / 30
I cicli for (2)
Un esempietto semplice:
for (int i =0; i < 1 0 ; i ++) S y s t e m . out . p r i n t l n ( i );
Questo programma stampa i valori da 0 a 9 uno dopo l’altro In altre parole:
Stampa tutti i valori di i,periche va da0a 10 (escluso) aumentando ogni volta i di 1
I cicli for (3)
for ( ..cmdIniz.. ; ..condiz.. ; ..cmdAgg.. ) ...corpo...
Semantica del comando:
1. Viene eseguito cmdIniz
2. La guardia (condiz) viene valutata 3. Se la guardia `e vera:
I si esegue il corpo
I si esegue cmdAgg
I si ricomincia da 2 (ATTENZIONE: non da 1)
4. Se la guardia `e falsa si salta il corpo e si procede con l’istruzione successiva al for
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 25 / 30
I cicli for (4)
Modifichiamo allora SommaNumeri usando un for
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 o m m a N u m e r i 4 {
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 (" Q u a n t i n u m e r i v u o i s o m m a r e ? ");
int n u m e r i = i n p u t . n e x t I n t ();
int s o m m a =0; // v a r i a b i l e da u s a r e c o m e a c c u m u l a t o r e // per i che va da 0 a n u m e r i ( e s c l u s o )
for (int i =0; i < n u m e r i ; i ++) {
S y s t e m . out . p r i n t l n (" I n s e r i s c i il p r o s s i m o n u m e r o ");
int n = i n p u t . n e x t I n t ();
s o m m a += n ; // a g g i o r n a l ’ a c c u m u l a t o r e }
S y s t e m . out . p r i n t l n ( s o m m a );
} }
I cicli for (6)
Un po’ di osservazioni:
Nel ciclo
for (int i =0; i < 1 0 ; i ++}
S y s t e m . out . p r i n t l n ( i );
la variabile i `elocale.
I la sua visiblit`a `e limitata al for
I `e buona normanon modificarei nel corpo del for
I posso riutilizzare i in un for successivo
I nomii,j,k... sono usati comunemente per le variabili-contatore dei cicli for
Si possono inserire pi`u comandi di inizializzazione e aggiornamento usando la virgola
for (int i =0 , j =0; i < 1 0 ; i ++ , j += i } { S y s t e m . out . p r i n t l n ( i );
S y s t e m . out . p r i n t l n ( j );
}
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 27 / 30
I cicli for (7)
Un ciclo for pu`o essere sempre tradottoin un ciclo while equivalente Ad esempio, l’esempietto visto prima
for (int i =0; i < 1 0 ; i ++}
S y s t e m . out . p r i n t l n ( i );
`
e equivalente al seguente blocco(nota: i nel for e’ una variabile locale)
{
int i =0;
w h i l e ( i < 1 0 ) {
S y s t e m . out . p r i n t l n ( i );
i ++;
} }
ossia:
{
... c m d I n i z ...
w h i l e ( . . . c o n d i z . . . ) { ... c o r p o ...
... c m d A g g ...
} }
Annidamento cicli (1)
Spesso nei programmi si usano cicli annidati un ciclo all’interno del corpo di un’altro ciclo
il ciclo interno viene ri-eseguito ad ogni iterazione del ciclo esterno ovviamente si possono annidare for dentro for, while dentro for, while dentro while, ....
p u b l i c c l a s s T a v o l a P i t a g o r i c a {
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 ) { for (int i =1; i < = 1 0 ; i ++) {
for (int j =1; j < = 1 0 ; j ++) { S y s t e m . out . p r i n t ( i * j );
S y s t e m . out . p r i n t (" ");
}
S y s t e m . out . p r i n t l n (); // a c a p o }
} }
Paolo Milazzo (Universit`a di Pisa) Programmazione - Blocchi e cicli A.A. 2014/2015 29 / 30
Annidamento cicli (2)
Output di TavolaPitagorica:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100