Struttura condizionale - MathUniPDlaurap/didattica/Fondamenti-2... · 2007-10-16 · Struttura...
Transcript of Struttura condizionale - MathUniPDlaurap/didattica/Fondamenti-2... · 2007-10-16 · Struttura...
1
Struttura
condizionale
Struttura condizionale
• Struttura condizionale o decisione o scelta.
• Sia P un predicato; P viene valutato e sarà o vero o falso. Si vuole eseguire <istruzione1> nel caso in cui P sia vero e <istruzione2> nel caso in cui P sia falso.
• Come possiamo esprimere in un costrutto questa scelta?
se P
allora istruzione1
altrimenti istruzione2
fine scelta
Struttura condizionale
• Può anche accadere che non dobbiamo fare nulla nel caso in cui P sia falso; allora possiamo schematizzare questa scelta in modo seguente:
se P allora istruzione
fine scelta • L’ingresso alla struttura è la valutazione del predicato
P, l’uscita è la fine della scelta (istruzione successiva o fine algoritmo).
Struttura condizionale
• Esempio.• Dati due numeri reali a e b, determinare il più
grande dei due.• Analisi.• Tra le operazioni elementari sui numeri non
c’è il calcolo del massimo, quindi dobbiamo utilizzare una struttura condizionale: il predicato sarà rappresentato dal confronto tra i due numeri; il confronto è una operazione elementare.
Struttura condizionale
• Progetto.Algoritmo massimotradue
variabili a, b, max di tipo reale
acquisire i dati per a e b e stamparli
se a>b
allora max ←←←← a
altrimenti max ←←←← b
//fine scelta
stampare il valore di max
//fine algoritmo
Struttura condizionale
• L’enunciato if (par. 5.1). Sia P un predicato (condizione), la sintassi è:
if(P)
istruzione;
if(P){//blocco di istruzioni
………
istruzione;
………
}
se P
allora istruzione
fine scelta
2
Struttura condizionale
• L’unica istruzione, o il blocco di istruzioni
individuato dalla coppia di parentesi graffe, viene eseguita solo nel caso in cui il predicato P risulti vero.
• Esempio.int a, b;
//assegnare valori ad a e b
if(a>b)
System.out.println(""""a e' maggiore di b"""");
Struttura condizionale
• Sintassi con le due alternative; sia P la condizione:if (P)
istruzione;
else
istruzione;
if(p){//blocco
istruzione;
}
else{//blocco
istruzione;
}
se P
allora istruzione
altrimenti istruzione
fine scelta
Struttura condizionale
• Attenzione al ;• Dopo la parentesi graffa (prima di else) non ci deve
essere il simbolo ;• Se si mette il ; l’istruzione if termina e il
compilatore segnala che c’è una else senza ifif(x>0){
System.out.print(""""x = """" + x);
System.out.println(""""e’ positivo"""");
};
else ...
il compilatore segnala:’else’ without ‘if’
Struttura condizionale• Traduciamo l’algoritmo massimotradue
public class Massimo2{
public static void main (String[] arg){
double a,b, max;
a=10; b=27;
if (a>b)
max = a; //P vero
else
max = b; // P falso
System.out.println(""""max = """" + max);
}//fine main
}//fine classe
Struttura condizionale
• Possiamo eseguire due istruzioni, quindi usare un blocco:
if (a>b) {max = a; //P vero
System.out.println(""""a > b"""");}else {// P falsomax = b;
System.out.println(""""b >= a"""");}
System.out.println(" " " " max = """" + max);
Struttura condizionale
• L’istruzione System.out.println("""" max = """" + max);
• viene eseguita con qualunque valore di P (vero, falso) e rappresenta il punto di prosecuzione dell’esecuzione dell’algoritmo.
• Ma se abbiamo più scelte come possiamo scriverle? In sequenza o annidate?
3
Struttura condizionale
• Scelte multiple. Siano P e Q due predicati:if (P)
istruzione; //if in sequenza
if(Q)
istruzione;
. . . . . . . . . . . . . . . . .
if(P) //if annidate
istruzione;
else if(Q) // if(Q) si valuta
istruzione; //quando P è falso
Struttura condizionale
• Nella sequenza il predicato Q viene valutato in ogni caso: P vero e P falso; nel caso di ifannidate, il predicato Q viene valutato solo se P è falso.
• Quale delle due strutture scegliere dipende da ciò che si vuole realizzare nell’algoritmo. L’ordine con cui si effettuano le scelte può essere fondamentale per l’algoritmo: un ordine diverso può dare un algoritmo errato.
Struttura condizionale
• Esempio. Supponiamo di voler stampare una stringa che esprima la ricchezza o meno di una persona in base al suo saldo bancario (par. 5.3).
povero medio ricco straricco
0 1000 50000 200000
• Dopo aver acquisito il valore del saldo (double) eseguiremo i vari confronti con i valori che individuano gli intervalli di minore o maggiore ricchezza stabilendo un valore da stampare (String).
Struttura condizionale
String s; double saldo;
if(saldo >= 200000)
s=“straricco”;
else if(saldo >= 50000)
s=“ricco”;
else if(saldo >= 1000)
s=“medio”;
else if(saldo >=0)
s=“povero”;
else s=“valore non valido”;
System.out.println(s);
Struttura condizionale
• Casi di prova.• Per essere sicuri che la struttura funzioni bene
dobbiamo provare tutte le alternative, provando diversi valori per saldo:-2 900 1000 1200 51000 200000 250000
• In corrispondenza a questi valori ci aspettiamo un valore per s: non valido, povero, medio, medio, ricco, straricco, straricco.• Se nel predicato si mette > invece di >= il secondo e il quarto valore di s cambiano.
Struttura condizionale
• Proviamo ad invertire l’ordine delle scelte:
if(saldo >= 1000)s=“medio”;
else if(saldo >= 0)s=“povero”;
else if(saldo >= 50000)s=“ricco”;
else if(saldo >=200000)s=“straricco”;
else s=“valore non valido”;
• Per saldo = 1200 si ha s= “medio” e le altre scelte non vengono eseguite; cosa accade per saldo = 51000?
4
Struttura condizionale
• Se mettiamo le if in sequenza otteniamo:if(saldo >= 200000)
s=“straricco”;if(saldo >= 50000)
s=“ricco”;if(saldo >= 1000)
s=“medio”;if(saldo >=0)
s=“povero”;//else s=“valore non valido”;System.out.println(s);
• Viene, però, sempre stampato l’ultimo valore perché le assegnazioni sono in sequenza .
Struttura condizionale
• Esercizio. Scriviamo delle istruzioni che autorizzano il prelievo da un conto corrente solo se l’ammontare del prelievo è inferiore al saldo:
double saldo = 10000; //saldo iniziale
double prelievo = 200;
if (prelievo <= saldo )
saldo = saldo - prelievo;
System.out.println(""""restano """" + saldo +
"""" euro"""");
Struttura condizionale
• E se il prelievo è superiore? Il programma deve dare una risposta anche nel caso in cui il prelievo sia superiore al saldo e …. impedirlo: il saldo non può essere negativo.
if (prelievo <= saldo )
saldo = saldo - prelievo;
if (prelievo > saldo)
System.out.println(“impossibile: conto
scoperto”);
• In questo algoritmo c’è un errore logico.
Struttura condizionale
• Se il prelievo viene eseguito ma supera la metà del saldo la seconda if viene eseguita e stamperà“impossibile”, perché il saldo è stato modificato. Pertanto eseguiamo le istruzioni in alternativa:
if (prelievo <= saldo )
saldo = saldo - prelievo;
else
System.out.println(""""impossibile: conto
scoperto"""");
Struttura condizionale
• If annidate e il problema dell’else sospeso (Errori comuni 5.2).
• Siano P e Q due predicati; non essendoci un costrutto “endif” si pone il seguente problema:
if(P)
if(Q)
istruzione1;
else istruzione2;
• La else a quale delle due if si riferisce?
Struttura condizionale
• Esempio.int a,b,c;
a=9; b=7; c=4;
if (a>b) //vero
if(b<c) //falso
b=b+1;
else b=b-1;
System.out.println("""" b = """" + b);
• Quale valore viene stampato per b? 6 o 7? • La else si riferisce alla prima if o alla seconda?
5
Struttura condizionale
• La regola del linguaggio è la seguente:
• La else si riferisce alla if più vicina (interna) quindi b=6.
• Si può alterare la regola inserendo della parentesi graffe:int a,b,c; a=9; b=7; c=4;
if (a>b){
if(b<c)
b=b+1;}
else b=b-1;//si riferisce alla prima if
System.out.println("""" b = """" + b); //7
Un po’ di stile
• Quando scriviamo una struttura è bene utilizzare una modalità di scrittura che faciliti la lettura dell’algoritmo, rientrando di alcuni spazi a sinistra le istruzioni che si riferiscono al vero e al falso, ed incolonnando le else sotto la parola if.
• Però questo stile non risolve l’attribuzione della else in caso di più strutture condizionali, che si ottiene con l’inserimento (o meno) della coppia di parentesi graffe.
Operatori di
confronto
Operatori di confronto
• Abbiamo visto con i tipi numerici degli operatori di relazione con i quali si potevano effettuare confronti (par. 5.2):
< > <= >= == !=
• Nel caso di operatori composti con due
simboli non si devono introdurre spazi.
• Errore frequente: confondere= (assegnazione) a = 3;
== (confronto di uguaglianza) if (a == 3)
Operatori logici
Operatori logici
• I predicati si possono comporre con degli operatori (connettivi) logici (par. 5.4.3) :
&& (and) || (or) ! (not)
• Sia P un predicato, e sia D il sottoinsieme di A per il quale P(x) è vero:
P : A → B B B B D = { x | P(x)}
6
Operatori logici
• Congiunzione: and && e
• Siano P e Q due predicati e siano A e B gli insiemi associati al vero.
• P e Q è vero ⇔⇔⇔⇔ sono entrambi veri
P Q P e Q
V V V
V F FF V F A ∩∩∩∩ B intersezione
F F F
Operatori logici
• Disgiunzione: or || o
• Siano P e Q due predicati e siano A e B gli insiemi associati al vero.
• P o Q è falso ⇔⇔⇔⇔ sono entrambi falsiP Q P o QV V VV F VF V V A ∪∪∪∪ B unione
F F F
Operatori logici
• Negazione: not ! non
• Sia P un predicato e sia A l’insieme associato al vero.
• P vero ⇒⇒⇒⇒ non P falso e viceversa
P non P
V F
F V A complementare
Operatori logici
• Nella logica classica si considerano anche altri operatori:
• nand (not and) complementare dell’intersezione
P Q P nand QV V FV F VF V V A ∩∩∩∩ B
F F V
Operatori logici
• nor (not or) complementare dell’unione
P Q P nor Q
V V F
V F FF V F A ∪∪∪∪ B
F F V
Operatori logici
• xor (or esclusivo) differenza simmetrica
P Q P xor Q
V V F
V F VF V V (A ∪∪∪∪ B) - (A ∩∩∩∩ B)
F F F
7
Operatori logici
• Leggi di De Morgan
A ∪∪∪∪ B = A ∩∩∩∩ B
A ∩∩∩∩ B = A ∪∪∪∪ B• L’algebra booleana, che considera solo i valori vero e
falso, ha trovato applicazione nella progettazione dei circuiti elettronici: F(a1, a2, … an) funzione con n≥ 1 ingressi rappresenta una porta logica: dispositivo che produce l’uscita 0 o 1 a seconda della funzione logica che rappresenta. Ad esempio una “porta and” avràin uscita 1 se e solo se tutti gli ingressi sono 1.
Operatori logici
• In tale modo si costruiscono gli “addizionatori di bit”per realizzare circuiti (più porte logiche collegate tra loro) per eseguire la somma; ad esempio consideriamo due possibili ingressi
0 + 0 = 00 + 1 = 11 + 0 = 11 + 1 = 0 e riporto 1
primo secondo bit in uscita ingresso ingresso
S. Congiu: Calcolatori elettronici
Porte logiche: not or and
S. Congiu: Calcolatori elettronici
Porte logiche: nand
Uso di and e or
• Problema. Dati tre numeri reali a, b, c stabilire se sono i lati di un triangolo e di quale triangolo si tratta.
• Analisi.1. Per essere delle misure di segmenti devono essere
tutti e tre positivi.2. Per essere i lati di un triangolo, ciascuno deve essere
minore della somma degli altri due3. Per essere un triangolo equilatero tutti e tre i lati
devono essere uguali4. Per essere isoscele due lati sono uguali (si hanno tre
possibili coppie)5. Se il triangolo non è né equilatero né isoscele allora
è scaleno
Uso di and e or
1. Per essere delle misure di segmenti devono essere tutti e tre positivi, pertanto and:
a>0 e b>0 e c>0(a> 0) && (b>0) && (c>0)
2. Per essere lati di un triangolo, ciascuno deve essere minore della somma degli altri due, pertanto and:
a<b+c e b<a+c e c<a+b(a<b+c) && (b<a+c) && (c<a+b)
8
Uso di and e or
3. Per essere equilatero tutti e tre i lati devono essere uguali:
a = b e b = c (a == b) && (b == c)
• Attenzione: non si scrive a==b==c
• Analogamente: la scrittura matematica 0 ≤ x ≤ 1
• si scrive componendo con and due predicati:(0 <= x) && (x <= 1)
Uso di and e or
4. Per essere isoscele due lati devono essere uguali e si hanno tre possibili coppie, pertanto or:
a=b o b=c o a=c
(a == b) || (b == c) || (a == c)
5. La condizione è in alternativa alle condizioni 3. e 4. .
Confronto di numeri
in virgola mobile
Confronto di numeri in virgola
mobile
• I numeri reali sono rappresentati con un numero finito di cifre (precisione limitata) e pertanto eseguendo i calcoli possiamo introdurre errori. Dobbiamo perciò porre molta attenzione all’uso di predicati che coinvolgono numeri reali.
double r = Math.sqrt(2);double d = r * r - 2;if (d == 0)
System.out.println("OK");else System.out.println("come mai?");
Confronto di numeri in virgola
mobile• Espressioni che nell’algebra dei numeri reali
sono esatte, possono non esserlo in una rappresentazione in virgola mobile (d dovrebbe essere uguale a 0).
• Può non avere senso chiedersi se due numeri reali che provengono da calcoli diversi siano o no uguali.
• Dovendo rappresentare una condizione di uguaglianza, l’andremo a sostituire con un confronto con un valore di riferimento (tolleranza).
Confronto di numeri in virgola
mobile
• Andiamo a sostituire la condizione d == 0 con la seguente:
if (Math.abs(d) <= tolleranza)
• dove il valore di tolleranza viene deciso in base alla precisione voluta: ad esempio
double tolleranza = 1.E-9 //10-9
• Vogliamo che d sia “abbastanza vicino” a 0.• Se usassimo un float la tolleranza non dovrebbe essere
meno di 10-6.
9
Precedenza degli
operatori
Precedenza degli operatori
• Operatori logici e booleani seguono delle regole di precedenza in espressioni senza le parentesi (Appendice E). A parità di precedenza la valutazione viene fatta da sinistra a destra. L’operatore not precede gli operatori aritmetici, seguono poi gli operatori di confronto, l’operatore and ed infine all’operatore or.
• Altri linguaggi utilizzano precedenze diverse; nei casi dubbi è consigliabile utilizzare le parentesi.
Precedenza degli operatori
• Valutazione pigra dei predicati.• In una espressione booleana composta da due
o più predicati, la valutazione si ferma non appena si può decidere il valore di veritàdell’espressione. Ad esempio:
if((x>5 && x<10) || (y<7))
• Nel caso x=8, il predicato y<7 non verrà valutato, essendo vera la prima parte. E bene però non approfittare di tale regola: il predicato composto non è più simmetrico.
Precedenza degli operatori
• Introducendo le parentesi rotonde possiamo modificare la precedenza nella valutazione:if (!(x < 0 || x > 10))
// vero se 0≤≤≤≤ x ≤≤≤≤10 : 0<=x and x<=10 :
// non(0>x or x>10) leggi di De Morgan
if (!(x < 0) || x > 10)
// vero se x ≥≥≥≥ 0 oppure se x>10: non(x<0)
Errori con gli operatori
• Espressioni matematiche del tipo:
0 ≤≤≤≤ x ≤≤≤≤ 10 0<=x<=10 //NO
x e y ≤≤≤≤ 0 x && y <=0 //NO
• devono essere scritte componendo due
predicati:1. x>=0 && x<=10
2. x<=0 && y<=0
• perché il compilatore segnala errore?
Errori con gli operatori
• Caso 1. Il compilatore analizza l’espressione logica e trova due operatori di confronto, quindi esamina il primo confronto (x<=0) da sinistra stabilendo che il risultato sarà un valore booleano; successivamente esamina il secondo operatore relazionale (<=10): dei due operandi, il primo è di tipo boolean, mentre il secondo è di tipo int e segnala un errore:operator <= cannot be applied toboolean,int
10
Errori con gli operatori
• Caso 2. Il compilatore analizza l’espressione logica e trova un operatore di confronto <= che ha la precedenza sull’operatore booleano &&, il risultato del confronto sarà un valore di tipo boolean e si troverà ad applicare l’operatore && ad un operando di tipo int (x) ed uno di tipo boolean, segnalando:operator && cannot be applied to
int,boolean
Leggere dati in
ingresso
Leggere dati in ingresso
• Nei programmi visti finora abbiamo dato un valore iniziale ai dati eseguendo delle assegnazioni: in tale modo avremo sempre la stessa elaborazione ad ogni esecuzione:• massimo tra due numeri, acronimo, trapezio, …
• Se vogliamo eseguire il programma su altri dati, è necessario modificare il codice sorgente (in particolare, le inizializzazioni delle variabili) e compilarlo di nuovo, prima di eseguirlo (par. 4.7).
Leggere dati in ingresso
• Per poter scrivere programmi generali, dobbiamo permettere all’utente di inserire dei propri dati: i programmi devono perciò ricevere dati in ingresso.
• Lo scambio di informazioni tra l’utente e il programma e viceversa è rappresentato da un flusso di dati.
• Quando l’ingresso è rappresentato dalla tastiera si dice che il programma viene eseguito in maniera interattiva: durante l’esecuzione il programma si ferma in “attesa”di ricevere i dati (input).
Leggere dati in ingresso
• Il flusso di dati per l’uscita è un oggetto di nome System.out; il flusso di dati in ingresso è un oggetto di nome System.in. Per Sytsem.out è disponibile un metodo print che trasmette le informazioni (stringhe, numeri).
• Il flusso di dati per l’ingresso è un oggetto di nome System.in, ma le cose sono più complicate:• Ciò che viene inserito da tastiera viene codificato in
binario e successivamente ricostruito prima come gruppo di caratteri (stringa) e poi interpretato come valore di una variabile di un certo tipo:
Leggere dati in ingresso
• Esempio.3 3 intero7.5 7.5 realeciao 0100110…01 ciao stringatrue true booleano
• La classe Scanner che rende abbastanza agevole la lettura dei dati, fornendo una comoda interfaccia all’oggetto System.in .
• Il flusso di dati di ingresso System.in viene utilizzato per costruire un oggetto “scansionatore” di tipo Scanner sul quale possono agire metodi per leggere il “successivo” intero, reale, stringa, booleano.
11
Leggere dati in ingresso
Scanner in = new
Scanner(System.in);
• Si è così definito un oggetto in con il quale si possono invocare i metodi nextDouble, nextInt, nextBoolean, next per acquisire rispettivamente il prossimo numero in virgola mobile, il prossimo numero intero, il prossimo valore logico e la prossima stringa. Gli elementi sono separati da spazi, fine riga o tabulazioni.
• Si può anche leggere tutta una riga come stringa utilizzando il metodo nextLine.
Leggere dati in ingresso
• I metodi precedenti restituiscono rispettivamente un valore double, int, boolean e String.
• Dal momento che il programma “resta in attesa” dei dati, per chiarirne il comportamento può essere utile inserire delle “stampe” che indichino cosa si deve inserire.
• Questo non è l’unico modo per inserire dati: vedremo in seguito come inserire i dati memorizzati in un file.
Leggere dati in ingresso
• Esempio.System.out.println(""""inserire un
numero reale, un intero, un
booleano e una stringa"""");
double a = in.nextDouble();
int b = in.nextInt();
boolean c = in.nextBoolean();
String d = in.next();
Leggere dati in ingresso
• La classe Scanner fa parte del pacchetto java.util che deve essere importato:
import java.util.Scanner;
• Mentre l’output standard è rappresentato dall’oggetto System.out, di tipo PrintStream, definito nella classe System, e utilizza il metodo print, l’input standard è rappresentato da un oggetto System.in di tipo InputStream la cui classe nonpossiede metodi comodi per la ricezione di dati numerici e stringhe. La classe InputStream ha un metodo in grado di leggere un byte alla volta, oppure sequenze di byte, ma non altri dati.
Leggere dati in ingresso
• I progettisti della classe Scanner hanno usato la localizzazione:
• Significa che il comportamento del programma è legato alla configurazione del sistema su cui viene fatto eseguire.
• A seconda della configurazione (anglosassone o italiana) un valore di tipo double dovrà essere inserito nella forma: • parteIntera.parteDecimale � ad esempio 4.35• parteIntera,parteDecimale � ad esempio 4,35
Leggere dati in ingresso
• Per uniformità con quello che avviene in altri linguaggi (si possono voler usare gli stessi dati in programmi scritti in linguaggi diversi), conviene inserire i dati reali con il punto decimale. Per questo si deve esplicitamente richiedere la localizzazione anglosassone:
import java.util.Locale;
e nel programma:in.useLocale(Locale.US);
12
Leggere dati in ingresso
• È importante non confondere i metodi next e nextLine: entrambi restituiscono una stringa, ma il primo restituisce come stringa il gruppo di caratteri che termina con uno spazio, o fine riga o tabulazione, mentre nextLine restituisce l’intera riga (fine riga: la pressione del tasto Invio), che può essere composta da un gruppo di parole separate da spazi: String citta = in.nextLine();
// La Spezia
String stato = in.next();
// Italia
Struttura iterativa
Struttura iterativa
• Consideriamo un predicato P e valutiamo se èvero: nel caso vero vogliamo eseguire ripetutamente un gruppo di istruzioni; questo gruppo di istruzioni, però, non dovrà più essere eseguito nel caso in cui P sia falso. Possiamo rappresentare questo ciclo scrivendo che:
fintantoché P eseguire <istruzioni> //P vero
//fine ciclo// ora P è falso
Struttura iterativa
• Individuiamo così una struttura con un unico punto di ingresso (la valutazione di P) ed un unico punto di uscita (ciò che segue dopo la fine della struttura).
• Esempio.
• Stampare i primi cinque numeri naturali in ordine decrescente.
• Analisi. Dobbiamo:
1. individuare il predicato P
2. individuare le istruzioni da ripetere.
Struttura iterativa
• Quali sono i numeri da stampare?• 1, 2, 3, 4, 5 ma nell’ordine inverso:
5, 4, 3, 2, 1• Possiamo pensare di partire dal più grande (5) e ad
ogni iterazione calare di una unità, quindi l’iterazione sarà:
stampa numeroesegui numero-1
• Quando ci fermiamo? Lo 0 non è compreso, quindi fintantoché numero è maggiore di zero, ripetiamo le istruzioni.
Struttura iterativa
• Progetto.algoritmo stamparovescia
variabili a intero
a ←←←← 5
finché a > 0 eseguire
stampa a
a ←←←← a-1
//fine struttura
• Questa struttura termina?
13
Struttura iterativa
• Scriviamo i valori che la variabile a assume durante il funzionamento dell’algoritmo:
valore predicato stampaa > 0
a = 5 V 5a = 4 V 4a = 3 V 3a = 2 V 2a = 1 V 1a = 0 F il ciclo termina
Struttura iterativa
• Osserviamo che il ciclo è stato eseguito 5 volte e che il predicato è stato valutato 6 volte:
5 vero + 1 falso
• Qual è il comportamento di un ciclo?
• Un ciclo:• può non essere mai eseguito
• può essere eseguito una o più volte
• deve terminare.
Struttura iterativa
• Cosa cambia se iniziamo con a = -5 ?• Il predicato a > 0 è falso e quindi il ciclo non viene mai
eseguito. Se quello che volevamo era la stampa dei numeri, questo è un errore logico: il compilatore non segnaleràerrore ma il programma non eseguirà le operazioni richieste.
• Cosa cambia se scriviamo a ← a+1?• I valori da a saranno: 5, 6, 7, … il predicato sarà sempre
vero e il ciclo non termina. Questo è un errore logicograve.
• Nell’iterazione ci deve sempre essere una istruzione che modifica il predicato e che può renderlo falso.
Struttura iterativa
• L’enunciato while (par. 6.1).• Sia P un predicato, la sintassi è:
while (P)
istruzione;
while (P){//blocco
. . . . .
istruzione;
. . . .
}
finché P eseguire
iterazione
fine ciclo
Struttura iterativa
• Esempio. Scrivere un algoritmo per stampare i numeri dispari compresi tra 1 e 10.
//inizio algoritmo
int i = 1;
while(i <= 10) {
System.out.println(i);
i = i+2;
}
Verifica: i assume i valori 1, 3, 5, 7, 9, con predicato vero; quando i = 11 il predicato è falso e il ciclo termina.
Struttura iterativa
• Il ciclo precedente è del tipo:
indice = inizio;
while(indice <= fine){
//iterazione;
indice = indice + passo;
}
• Questo ciclo è governato da un’unica variabile (indice) che descrive un intervallo di valori e che èincrementata di una quantità fissa (passo).
14
Struttura iterativa
L’enunciato for (par. 6.2).
La sintassi è:
for (inizializzazione; controllo;
incremento)
iterazione;
Oppure:
{//blocco di istruzioni
}
Struttura iterativa
• Nel caso precedente il ciclo while si trasforma in:
for (indice = inizio; indice <= fine;
indice = indice + passo)
iterazione;
• Oppure se ci sono più istruzioni da eseguire:
{//blocco di istruzioni
}
Struttura iterativa
• Nella sezione di inizializzazione si può anche inserire la definizione della variabile, che risulta “visibile” solo all’interno della struttura.int n = 10;
for (int i = 1; i <= n; i = i+2)
System.out.println(i);
• L’indicazione dell’incremento della variabile i
appartiene all’intestazione della struttura e non deve più essere scritta all’interno della iterazione.
Struttura iterativa
• In entrambe queste strutture (while e for) la condizione viene verificata all’inizio: entrambi questi cicli possono non essere mai eseguiti.
• Nel ciclo for l’incremento della variabile i che governa il ciclo viene fatto alla fine della iterazione: • i=1, verifica condizione (i <= n): è vera, iterazione,
incremento di i che diventa 3; verifica condizione: è vera, iterazione, … , incremento di i che diventa 11; verifica condizione: è falsa; il ciclo termina.