Fondamenti di informatica
Oggetti e Java
Luca Cabibbo
Istruzioni ripetitive
Capitolo 14
febbraio 2004
1
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzioni ripetitive
Istruzioni ripetitive (o istruzioni di ciclo)
istruzioni di controllo che permettono di eseguire
ripetutamente una istruzione fintanto che una condizione è
verificata
ciascuna istruzione ripetitiva è composta almeno da
un corpo
una condizione
in Java, tre istruzioni ripetitive
2
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione ripetitiva while
Calcolare il quoziente q della divisione intera tra due numeri interi
positivi a e b dati
senza usare l’operatore /
per sottrazioni ripetute – quante volte posso sottrarre b da a?
devo continuare fintanto che a è maggiore di zero ma non
è minore di b
... calcola il quoziente di a diviso b ...
int q;
// il quoziente di a diviso b
/* conta quante volte è possibile sottrarre b da a */
q = 0;
while (a>=b) {
a = a-b;
q = q+1;
}
... il quoziente è q ...
3
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione while
while ( espressione )
istruzione
l’espressione è chiamata la condizione del while
deve essere di tipo boolean
l’istruzione è il corpo del while
Semantica:
Esegui ripetutamente e in sequenza i seguenti passi
valuta la condizione del while
se la condizione è vera, esegui il corpo del while
se invece la condizione è falsa, smetti di eseguire questi passi
l’esecuzione dell’istruzione while è cioè considerata
terminata
4
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Diagramma di flusso per l’istruzione while
condizione
false
true
corpo
istruzione while
5
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizio e osservazioni
Calcolare il quoziente di
23 diviso 7
23 diviso 47
3 diviso 0
Osservazioni
in una esecuzione di una istruzione while
il corpo del while può venire eseguito diverse volte
è possibile che il corpo del while non venga mai eseguito
l’esecuzione dell’istruzione while potrebbe non terminare
se il corpo del while viene eseguito N volte
la condizione del while viene valutata N+1 volte
le prime N volte risulta verificata
l’N+1-esima volta risulta falsa
6
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esecuzione di una operazione ripetitiva
Per esecuzione di una istruzione ripetitiva si intende
l’esecuzione dell’intera istruzione ripetitiva
che comprende zero o più esecuzioni del suo corpo
è possibile che il corpo non venga mai eseguito
è possibile che il corpo venga eseguito una sola volta
è possibile che il corpo venga eseguito più volte
7
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione ripetitiva for
Calcola il fattoriale f di un numero naturale n dato
assegna a f il valore 1
per ogni valore i compreso tra 1 e n, moltiplica f per i
... calcola il fattoriale f di n ...
int f;
// il fattoriale di n
int i;
// per iterare tra 1 e n
/* calcola il fattoriale di n */
f = 1;
/* moltiplica f per ogni numero intero i
* compreso tra 1 e n */
for (i=1; i<=n; i++)
f = f*i;
... il fattoriale di n è f ...
8
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione for
for ( inizializzazione ; espressione ; aggiornamento )
istruzione
9
l’inizializzazione del for è una espressione-istruzione
di solito è una assegnazione o l’invocazione di un metodo
l’espressione è la condizione del for
è un predicato
l’aggiornamento del for è una espressione-istruzione
di solito è una espressione di incremento o decremento
può anche essere una assegnazione o l’invocazione di un
metodo
l’istruzione che segue le parentesi è il corpo del for
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione for
Semantica:
Esegui l’inizializzazione del for
Esegui ripetutamente e in sequenza i seguenti passi
valuta la condizione del for
se la condizione è vera
esegui il corpo del for
esegui l’aggiornamento del for
se invece la condizione è falsa, smetti di eseguire questi passi
10
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Diagramma di flusso per l’istruzione for
inizializzazione
false
condizione
true
corpo
aggiornamento
istruzione for
11
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizio e osservazioni
Calcolare il fattoriale di
0
1
7
Osservazioni
in una esecuzione di una istruzione for
l’inizializzazione viene eseguita esattamente una volta
ciascuna esecuzione del corpo è preceduta da una
valutazione positiva della condizione e seguita da una
esecuzione dell’aggiornamento
è possibile che il corpo del for non venga mai eseguito,
venga eseguito uno o più volte, venga eseguito all’infinito
se il corpo del for viene eseguito N volte
l’inizializzazione viene eseguita esattamente una volta
la condizione del for viene valutata N+1 volte
l’aggiornamento viene eseguito N volte
12
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizi
Risolvere il problema della lettura e somma di dieci numeri
usando l’istruzione for
Risolvere il problema della somma dei primi N numeri interi
positivi usando l’istruzione for
13
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione for con variabile contatore
Istruzione for con variabile contatore
viene utilizzata una variabile contatore con le seguenti
modalità
l’inizializzazione del for è una assegnazione alla variabile
contatore
la condizione del for è un confronto tra la variabile
contatore e una espressione (il cui valore non viene
modificato dalle istruzioni del corpo del for)
il corpo del for accede al valore della variabile contatore
il corpo del for non modifica il valore della variabile
contatore
l’aggiornamento del for è un incremento oppure un
decremento della variabile contatore
for (i=1; i<=n; i++)
f = f*i;
14
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione for con variabile contatore
Il significato di una istruzione for con variabile contatore è
facilmente comprensibile dalla lettura dell’intestazione del for
for (i=0; i<n; i++)
... corpo del for ...
for (i=1; i<=n; i++)
... corpo del for ...
for (i=n; i>0; i--)
... corpo del for ...
for (i=n-1; i>=0; i--)
... corpo del for ...
15
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Accesso posizionale ai caratteri di una stringa
Calcola le occorrenze del carattere car nella stringa s
... calcola le occorrenze di car in s ...
int i;
// indice per scandire i caratteri di s
int occ;
// occorrenze di car in s
/* scandisce e conta i caratteri di s uguali a car */
occ = 0;
for (i=0; i<s.length(); i++)
if (s.charAt(i)==car)
occ++;
... il numero di occorrenze di car in s è occ ...
16
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione ripetitiva do-while
Nella scansione di una sequenza di caratteri letti dalla tastiera
bisogna leggere e ignorare gli spazi bianchi iniziali
leggere anche il primo carattere non spazio
ad esempio – indicando gli spazi come #
se la sequenza è ##abc
il primo carattere non spazio è la a
... legge una sequenza di caratteri
fino al primo carattere non spazio ...
char car;
// un carattere letto dalla tastiera
/* leggi e ignora gli spazi bianchi iniziali */
do {
car = Lettore.in.leggiChar();
} while (car==' ');
... il primo carattere non spazio è car ...
17
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzione do-while
do
istruzione
while ( espressione ) ;
l’espressione è chiamata la condizione del do-while
è un predicato
l’istruzione è il corpo del do-while
Semantica:
Esegui ripetutamente e in sequenza i seguenti passi
esegui il corpo del do-while
valuta la condizione del do-while
se la condizione è vera, continua a eseguire questa sequenza
di passi
se invece la condizione è falsa, smetti di eseguire questi passi
18
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Diagramma di flusso per l’istruzione do-while
corpo
condizione
true
false
istruzione do-while
19
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizio e osservazioni
Che succede se la sequenza in ingresso è
##abc
abc
Osservazioni
in una esecuzione di una istruzione do-while
il corpo del do-while viene eseguito almeno una volta
se il corpo del do-while viene eseguito N volte
la condizione del do-while viene valutata N volte
è possibile che la condizione del do-while non possa venire
valutata se il corpo non è mai stato eseguito
20
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Confronto tra istruzioni ripetitive
L’istruzione for può essere sempre espressa in termini
dell’istruzione while
f = 1;
for (i=1; i<=n; i++)
f = f*i;
diventa
f = 1;
i = 1;
while ( i<=n ) {
f = f*i;
i++;
}
21
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Confronto tra istruzioni ripetitive
L’istruzione while può essere sempre espressa in termini
dell’istruzione for
q = 0;
while (a>=b) {
a = a-b;
q = q+1;
}
diventa
q = 0;
for (dummy=0; a>=b; dummy=0) {
a = a-b;
q = q+1;
}
22
il do-while può essere espresso in termini del while e del for
usando le istruzioni condizionali, il while e il for possono
essere espressi in termini dell’istruzione do-while
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Linee guida
Per scrivere codice iterativo
descrivi il procedimento iterativo in linguaggio naturale
descrivi in modo informale il passo da eseguire
ripetutamente e la condizione che controlla la ripetizione
scrivi il corpo dell’istruzione ripetitiva
scegli il tipo di istruzione ripetitiva
scrivi la condizione dell’istruzione ripetitiva – e completa la
scrittura del codice
Verifica l’utilità di una variabile di controllo
indispensabile nel for
utile con il while e il do-while
23
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Scelta tra istruzioni ripetitive
Se una istruzione deve essere eseguita zero o più volte, e in
generale un numero imprecisato di volte
usa l’istruzione while
Se una istruzione deve essere eseguita una o più volte, e in
generale un numero imprecisato di volte
usa l’istruzione do-while
Se una istruzione deve essere eseguita zero o più volte, un
numero prefissato di volte
usa l’istruzione for con variabile contatore
24
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizio
Calcola il numero di cifre nella rappresentazione decimale di un
numero naturale n dato
bisogna contare quante volte è possibile dividere n per dieci
(divisione intera) fino ad ottenere zero
ad esempio, 13023/10 → 1302/10 → 130/10 → 13/10 →
1/10 → 0 – 13023 è formato da cinque cifre
come caso particolare, 0/10 → 0 – 0 è formato da una cifra
Descrizione informale
inizialmente il numero di cifre c vale zero
dividi n per dieci e incrementa c fino a quando n non vale
zero
25
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizio
Schema della soluzione
... calcola il numero di cifre di n ...
int c;
// numero di cifre di n
/* conta il numero di volte c
* che puoi dividere n per dieci */
c = 0;
/* dividi ripetutamente n per dieci
* finché non diventa zero */
finché n è diverso da zero {
n = n/10;
c++;
}
... il numero di cifre è c ...
26
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esercizio
Scelta dell’istruzione ripetitiva
do-while
Scrivi la condizione e completa il codice
... calcola il numero di cifre di n ...
int c;
// numero di cifre di n
/* conta il numero di volte c
* che puoi dividere n per dieci */
c = 0;
/* dividi ripetutamente n per dieci
* finché non diventa zero */
do {
n = n/10;
c++;
} while (n!=0);
... il numero di cifre è c ...
27
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzioni ripetitive e cicli
Nel contesto delle istruzioni ripetitive
la parola ciclo è usata in modo sovraccarico
Per evitare ambiguità, nel resto del testo la parola “ciclo” non sarà
usata
alla parola ciclo vengono preferiti i seguenti termini
esecuzione di una istruzione ripetitiva
esecuzione del corpo di una istruzione ripetitiva
istruzione ripetitiva
28
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Errori comuni
Errori comuni nell’uso delle istruzioni ripetitive
ciclo infinito
errore di uno
29
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ciclo infinito
Per ciclo infinito si intende l’esecuzione di una istruzione
ripetitiva che non termina
le variabili controllate nella condizione dell’istruzione ripetitiva
vengono modificate male
è sbagliata la condizione
30
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Mancata modifica della variabile di controllo
Visualizza sullo schermo i numeri naturali minori di n
i = 0;
while (i<n) {
System.out.print(i + " ");
// manca l'incremento di i
}
ad esempio
while (i<n)
System.out.print(i + " ");
i++;
// non appartiene al corpo del while
altro esempio
while (i<n);
// c’è l’istruzione vuota
{
System.out.print(i + " ");
i++;
}
31
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Errore nella condizione dell’istruzione ripetitiva
Visualizza sullo schermo i numeri naturali dispari minori di n
i = 1;
while (i!=n) {
System.out.print(i + " ");
i = i+2;
}
soluzione corretta
i = 1;
while (i<n) {
System.out.print(i + " ");
i = i+2;
}
32
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Errore di uno
Un errore di uno si verifica se il corpo dell’istruzione ripetitiva
viene eseguito una volta di più o una volta di meno del necessario
nei seguenti frammenti di codice il corpo dell’istruzione
ripetitiva dovrebbe essere eseguito dieci volte
for (i=1; i<10; i++) {
... // sbagliato, i varia tra 1 e 9
}
for (i=0; i<=10; i++) {
... // sbagliato, i varia tra 0 e 10
}
for (i=0; i<10; i++) {
... // ok, i varia tra 0 e 9
}
for (i=1; i<=10; i++) {
... // ok, i varia tra 1 e 10
}
33
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Errore di uno
Errori di questo tipo possono causare errori logici
... calcola le occorrenze di car in s ...
occ = 0;
for (i=1; i<s.length(); i++)
if (s.charAt(i)==car)
occ++;
... il numero di occorrenze di car in s è occ ...
oppure errori di semantica dinamica
... calcola le occorrenze di car in s ...
occ = 0;
for (i=0; i<=s.length(); i++)
if (s.charAt(i)==car)
occ++;
... il numero di occorrenze di car in s è occ ...
34
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzioni ripetitive annidate
Scrivere un frammento di codice che, dati due numeri naturali b e
h, visualizza un rettangolo di asterischi di base b e altezza h
ad esempio, base 8 e altezza 2
********
********
devo visualizzare h linee di asterischi
... visualizza un rettangolo di base b e altezza h ...
int i;
// per scandire le linee del rettangolo
for (i=0; i<h; i++) {
... visualizza una linea di b asterischi ...
}
come si visualizza una linea di b asterischi?
... visualizza una linea di b asterischi ...
int j;
// per scandire gli asterischi di una linea
for (j=0; j<b; j++)
System.out.print('*');
System.out.println();
35
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzioni ripetitive annidate
Complessivamente
...
int
int
for
visualizza un rettangolo di base b e altezza h ...
i;
// per scandire le linee del rettangolo
j;
// per scandire gli asterischi di una linea
(i=0; i<h; i++) {
/* visualizza una linea di b asterischi */
for (j=0; j<b; j++)
System.out.print('*');
System.out.println();
}
36
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzioni ripetitive annidate
Come vengono fatte variare le variabili i e j?
int i;
int j;
for (i=0; i<2; i++)
for (j=0; j<4; j++)
System.out.println("i=" + i + ", j=" + j);
visualizza
i=0,
i=0,
i=0,
i=0,
i=1,
i=1,
i=1,
i=1,
37
j=0
j=1
j=2
j=3
j=0
j=1
j=2
j=3
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Istruzioni ripetitive annidate
La variabile associata all’istruzione ripetitiva più interna può
variare in modo dipendente dal valore corrente della variabile
associata all’istruzione ripetitiva più esterna
for (i=0; i<4; i++)
for (j=0; j<i; j++)
System.out.println("i=" + i + ", j=" + j);
visualizza
i=1,
i=2,
i=2,
i=3,
i=3,
i=3,
38
j=0
j=0
j=1
j=0
j=1
j=2
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Esempio
Visualizza un triangolo di altezza h
ad esempio, h vale 4
*
**
***
****
...
int
int
for
visualizza un triangolo di altezza h ...
i;
// per scandire le linee del triangolo
j;
// per scandire gli asterischi di una linea
(i=0; i<h; i++) {
/* visualizza una linea di i+1 asterischi */
for (j=0; j<i+1; j++)
System.out.print('*');
System.out.println();
}
39
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Terminazione precoce
Terminazione normale di una istruzione ripetitiva
l’istruzione ripetitiva termina quando la condizione (nel
momento in cui viene valutata) non risulta più verificata
quando una istruzione ripetitiva termina in modo normale,
allora la condizione dell’istruzione ripetitiva risulta falsa
Java fornisce alcune istruzioni che permettono di interrompere in
modo precoce (ovvero, non normale) l’esecuzione di una
istruzione ripetitiva oppure una esecuzione del suo corpo
istruzioni break, continue e return
in caso di terminazione precoce di una istruzione ripetitiva, la
proprietà riportata qui sopra non risulta in genere verificata
40
Istruzioni ripetitive
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl