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