Corso di Laurea Ingegneria Informatica Fondamenti di Informatica Dispensa 11 Istruzioni Ripetitive Carla Limongelli Novembre 2011 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Contenuti Istruzioni ripetitive Istruzione while Istruzione for Istruzione do-while http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Prerequisiti Questo capitolo presuppone la conoscenza degli argomenti già trattati nelle precedenti lezioni di questo corso con particolare riferimento a: Sintassi e semantica dei linguaggi Metalinguaggi per la descrizione della sintassi (EBNF) Espressioni logiche e predicati http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Una classificazione delle principali istruzioni di Java istruzione o dichiarazione variabile locale istruzione semplice strutturata espressione return assegnazione invocazione di metodo di incremento o decremento creazione di oggetto ripetitiva condizionale blocco if-else if for while do-while break continue vuota http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Istruzioni di controllo che permettono di eseguire una istruzione in modo ripetuto ciascuna istruzione ripetitiva è composta almeno da una istruzione che deve essere eseguita ripetutamente (il corpo dell’istruzione ripetitiva) una condizione che permette di determinare se il corpo dell’istruzione ripetitiva deve essere ancora eseguito Istruzione ripetitiva while Istruzione ripetitiva for Istruzione ripetitiva do-while http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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 si puo’ sottrarre b da a */ q = 0; while (a>=b) { a = a-b; q = q+1; } ... il quoziente è q ... http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzione while: sintassi while ( <espressione> ) <istruzione> <espressione> ::= <espressione-booleana> <istruzione> ::= <istruzione-semplice> | <istruzione-strutturata> condizione corpo http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzione while: semantica La semantica dell’istruzione while è la seguente: Esegui ripetutamente e in sequenza i seguenti passi valuta la condizione dell’istruzione while se la condizione è vera, esegui il corpo dell’istruzione while se la condizione è falsa, smetti di eseguire questi passi l’esecuzione dell’istruzione while è cioè considerata terminata http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive … semantica true false istruzione while condizione corpo http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Osservazioni In una esecuzione di una istruzione while il corpo dell’istruzione while può venire eseguito diverse volte è possibile che il corpo dell’istruzione while non venga mai eseguito l’esecuzione dell’istruzione while potrebbe non terminare Se il corpo dell’istruzione while viene eseguito N volte la condizione dell’istruzione while viene valutata N+1 volte le prime N volte risulta verificata l’N+1-esima volta risulta falsa http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esercizi Calcolare per sottrazioni successive il quoziente di 23 diviso 7 23 diviso 47 3 diviso 0 Descrivere l’esecuzione del seguente frammento di codice int n; n = 4; while (n>0) { System.out.println(n + " "); n = n-5; n = n+3; } Nel secondo esercizio il commento era: “il valore della condizione non è significativo durante le esecuzioni del corpo” http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive … Esercizi Si consideri il seguente frammento di codice su cui, purtroppo, è caduto del caffè se si assume che l’esecuzione dell’istruzione while termina normalmente, è possibile dire che cosa viene stampato? perché? int n, k; n = 19; k = 3; while (n!=7) { n += k; n++; n /= k; } System.out.println(n); http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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 ... http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzione for: sintassi for ( <inizializzazione> ; < espressione > ; <aggiornamento> ) <istruzione> <inizializzazione> ::= <istruzione-assegnazione> | <istruzione-invocazione-metodo> <espressione> ::= <espressione-booleana> <aggiornamento> ::= <istruzione-incremento> | <istruzione-decremento> | <istruzione-invocazione-metodo> <istruzione> ::= <istruzione-semplice> | <istruzione-strutturata> corpo http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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 ovvero, l’esecuzione dell’istruzione for è terminata http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive … semantica true false Semantica istruzione for condizione inizializzazione aggiornamento corpo http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive 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 la condizione del for viene valutata N+1 volte l’aggiornamento viene eseguito N volte http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esercizi Calcolare il fattoriale di 0, 1, 7. Che cosa stampa il seguente frammento di codice supponendo che a n venga assegnato un numero naturale N int i; int n; n = ... ; for (i=0; i<n; i++) System.out.print(i + " "); System.out.println(); 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 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Uso tipico del for L’istruzione for si usa quando un’istruzione deve essere iterata un fissato numero di volte Ad esempio for (i=1; i<=n; i++) f = f*i; http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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++) for (i=n; i>0; i--) for (i=n-1; i>=0; i--) http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Esempio: accesso posizionale ai caratteri di una stringa Calcola le occorrenze del carattere car nella stringa s ovvero, quanti elementi di s sono uguali a car ... 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 ... http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esercizi Calcola la somma dei primi N numeri interi dispari in almeno tre diversi modi Quali valori vengono stampati dal seguente frammento di codice? Quali porzioni di codice si comprendono senza farne una traccia? int a, b; for (a=0; a<10; a++) { System.out.print(a + " "); a = a*a; } /* quanto vale ora a? */ for (b=0; a>0; System.out.println(a + " ")) a = a/3 -1; http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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 ... http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzione do-while: sintassi do <istruzione> while ( <espressione> ) <espressione> ::= <espressione-booleana> <istruzione> ::= <istruzione-semplice> | <istruzione-strutturata> corpo condizione http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzione 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 ovvero, l’esecuzione dell’istruzione do-while è terminata http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive … semantica true false istruzione do-while condizione corpo http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Osservazioni 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 Nell’esempio della scansione di una sequenza di caratteri letti dalla tastiera che succede se la sequenza in ingresso è ##abc ? abc ? http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Confronto tra istruzioni ripetitive Le istruzioni for e while sono semanticamente equivalenti Una istruzione for può essere espressa in termini di una while e viceversa f = 1; for (i=1; i<=n; i++) f = f*i; diventa i = 1; while ( i<=n ) { i++; } http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Uso dell’istruzione ripetitiva for L’istruzione for viene in genere utilizzata per eseguire ripetutamente una istruzione mentre una variabile assume valori in una sequenza prefissata in cui i valori della sequenza sono noti a priori (ovvero, già immediatamente prima di iniziare a eseguire l’istruzione ripetitiva) http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Uso dell’istruzione ripetitiva while L’istruzione while viene solitamente utilizzata per eseguire ripetutamente una istruzione un numero imprecisato di volte (ma non necessariamente almeno una volta) per imprecisato si intende imprecisato a priori, ovvero non determinabile in modo elementare già immediatamente prima di iniziare a eseguire l’istruzione ripetitiva http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Uso dell’istruzione ripetitiva do-while L’istruzione do-while viene solitamente utilizzata per eseguire ripetutamente una istruzione almeno una volta e un numero imprecisato di volte http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esempio 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 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive … Esempio 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 non diventa zero { n = n/10; c++; } ... il numero di cifre è c ... http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esempio Scelta dell’istruzione ripetitiva do-while – il corpo deve essere eseguito almeno una volta 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 ... Attenzione scelte diverse se inizialmente a c viene assegnato il valore 1 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esercizi Scrivere un frammento di codice per calcolare il massimo comun divisore di due numeri interi positivi N e M dati, basato sul seguente algoritmo finché N è diverso da M se N è maggiore di M, sostituisci a N il valore di N-M se M è maggiore di N, sostituisci a M il valore di M-N il risultato è N Scrivere un frammento di codice che, dato un numero naturale N, calcola la radice quadrata intera R di N, eventualmente approssimata per difetto R è il più grande numero naturale il cui quadrato è minore o uguale a N http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esercizi Scrivere un frammento di codice che, dato un numero naturale N, calcola e visualizza i primi N numeri di Fibonacci i primi due numeri di Fibonacci valgono 1 ciascun altro numero di Fibonacci è dato dalla somma dei due numeri di Fibonacci che lo precedono i primi numeri di Fibonacci sono 1, 1, 2, 3, 5, 8, 13, 21, … Scrivere un frammento di codice che, dato un numero naturale N, calcola e visualizza i numeri di Fibonacci il cui valore è minore o uguale a N http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Esercizio: alto-basso Scrivere una applicazione AltoBasso che realizza il gioco “indovina che numero ho pensato”, descritto come segue inizialmente, l’applicazione sceglie un numero casuale intero compreso tra 1 e 100, e poi chiede all’utente di indovinare il numero scelto dopo ciascun tentativo, l’applicazione deve segnalare se la risposta data dall’utente è giusta, oppure è maggiore (alto!) oppure è minore (basso!) rispetto al numero scelto l’applicazione deve continuare a chiedere numeri all’utente fino a che questi non abbia dato la risposta corretta, oppure abbia scelto di rinunciare ad indovinare (digitando il numero 0) se l’utente indovina il numero scelto, l’applicazione deve congratularsi con l’utente, visualizzando anche il numero di tentativi fatti dall’utente … http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive … alto-basso Ad esempio, se il numero scelto dal calcolatore fosse 31, l’interazione tra applicazione e utente potrebbe essere la seguente Ho pensato un numero intero compreso tra 1 e 100. Indovina che numero ho pensato: 40 40 è troppo alto. Indovina che numero ho pensato: 30 30 è troppo basso. Indovina che numero ho pensato: 32 32 è troppo alto. Indovina che numero ho pensato: 31 Bravo! Hai indovinato facendo 4 tentativi! http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Errori comuni Ciclo infinito Per ciclo infinito si intende l’esecuzione di una istruzione ripetitiva che non termina sono possibili due casi le variabili controllate nella condizione dell’istruzione ripetitiva non vengono modificate o vengono modificate male è sbagliata la condizione dell’istruzione ripetitiva Errore di uno il corpo di una istruzione ripetitiva viene eseguito una volta di più o una volta di meno http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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 } while (i<n) i++; // non appartiene al corpo del while soluzione: bisogna definire un blocco while (i<n); { i++; c’è l’istruzione vuota http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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; } in teoria, non termina se n è pari oppure è minore di zero nelle condizioni delle istruzioni ripetitive si consiglia di usare gli operatori di uguaglianza == e != solo con molta attenzione è preferibile usare gli altri operatori relazionali while (i<n) { i = i+2; } http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive 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 tipicamente avviene per la prima o l’ultima ripetizione ad esempio, nei seguenti frammenti di codice il corpo dell’istruzione ripetitiva dovrebbe essere eseguito 10 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 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive 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 for (i=0; i<=s.length(); i++) http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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(); http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive annidate Complessivamente ... visualizza un rettangolo di base b e altezza h ... int i; // per scandire le linee del rettangolo int j; // per scandire gli asterischi di una linea for (i=0; i<h; i++) { /* visualizza una linea di b asterischi */ for (j=0; j<b; j++) System.out.print(“*”); System.out.println(); } abbiamo usato due istruzioni ripetitive annidate una più esterna – al variare i una più interna – al variare j http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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, j=0 i=0, j=1 i=0, j=2 i=0, j=3 i=1, j=0 i=1, j=1 i=1, j=2 i=1, j=3 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive annidate int i; int j; for (i=0; i<2; i++) for (j=0; j<4; j++) System.out.println("i=" + i + ", j=" + j); la variabile i associata all’istruzione ripetitiva più esterna varia nell’insieme {0,1} la variabile j associata all’istruzione ripetitiva più interna varia nell’insieme {0,1,2,3} la variabile i associata all’istruzione ripetitiva più esterna varia più lentamente della variabile j associata all’istruzione ripetitiva più interna http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
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, j=0 i=2, j=0 i=2, j=1 i=3, j=0 i=3, j=1 i=3, j=2 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esempio Visualizza un triangolo di altezza h ad esempio, h vale 4 * ** *** **** ... visualizza un triangolo di altezza h ... int i; // per scandire le linee del triangolo int j; // per scandire gli asterischi di una linea for (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(); } http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Esercizi Che cosa fa il seguente frammento di codice? for (i=0; i<4; i++) for (j=i; j<4; j++) System.out.println("i=" + i + ", j=" + j); Scrivere un frammento di codice che, dato un numero naturale h, visualizza una montagna di asterischi di altezza h ad esempio, altezza 4 ** **** ****** ******** http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Interruzione forzata: istruzioni non strutturate Java fornisce alcune istruzioni che permettono di forzare la terminazione dell’esecuzione di una istruzione ripetitiva oppure una esecuzione del suo corpo istruzioni break, continue L’istruzione break, scritta nel corpo di una istruzione ripetitiva, quando viene eseguita causa la terminazione dell’esecuzione dell’istruzione ripetitiva che la contiene L’istruzione continue, scritta nel corpo di una istruzione ripetitiva, quando viene eseguita causa la terminazione dell’esecuzione del corpo dell’istruzione ripetitiva che la contiene http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Uso delle istruzioni break e continue L’uso delle istruzioni break e continue può essere sempre evitato introducendo delle opportune istruzioni condizionali e/o modificando la struttura dell’istruzione ripetitiva Per questo motivo, viene adottata la convenzione di non utilizzare le istruzioni break e continue http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Istruzioni ripetitive Cosa abbiamo imparato Sintassi e semantica delle istruzioni ripetitive while, for, do-while Ogni istruzione può contenere nel suo “corpo” ogni altra istruzione Esistenza di istruzioni che possono terminare in modo “anomalo” l’esecuzione di un ciclo http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive
Riferimenti al libro di testo Per lo studio di questi argomenti si fa riferimento al libro di testo, e in particolare al Capitolo 14 http://www.dia.uniroma3.it/~java/fondinf/ Istruzioni ripetitive