05 3 istruzioni-selezione-iterazione-condizioni

77
Introduzione al C++ istruzioni: sequenza, selezione, iterazione, condizioni 1

description

 

Transcript of 05 3 istruzioni-selezione-iterazione-condizioni

Page 1: 05 3 istruzioni-selezione-iterazione-condizioni

Introduzione al C++

istruzioni: sequenza, selezione, iterazione, condizioni

1

Page 2: 05 3 istruzioni-selezione-iterazione-condizioni

Le istruzioni

• Istruzioni (statement): sono le azioni svolte da programma

• Differiscono dalle– Espressioni: vengono valutate e hanno un

valore– Dichiarazioni: intruducono nome e tipo

delle variabili (e delle funzioni)– Definizioni: definiscono il valore iniziale

delle variabili (e il corpo delle funzioni)

2

Page 3: 05 3 istruzioni-selezione-iterazione-condizioni

Principali istruzioni del C++

• Semplici– Istruzione espressione (expression statement)

• Composte– Blocco

• Condizionali– if, if-else, switch

• Iterative– While, for, do while

• Di salto– Break, continue, goto

3

Page 4: 05 3 istruzioni-selezione-iterazione-condizioni

4

Teorema di Böhm e Jacopini

• Tutti i programmi possono essere scritti in termini di tre strutture di controllo:

– Sequenza: istruzioni eseguite in ordine

– Selezione: istruzioni che permettono di prendere strade diverse in base a una condizione (costrutto di tipo if-then-else)

– Iterazione: istruzioni che permettono di eseguire ripetutamente un certo insieme di altre istruzioni (costrutti di tipo while, do e for)

Page 5: 05 3 istruzioni-selezione-iterazione-condizioni

5

Sequenzaint main(){ int integer1, integer2, sum; // declaration

cout << "Enter first integer" << endl; // prompt cin >> integer1; // read an integer cout << "Enter second integer" << endl; // prompt cin>> integer2; // read an integer sum = integer1 + integer2; // assignment cout << "Sum is: " << sum; // print sum

return 0; // successful end}

Page 6: 05 3 istruzioni-selezione-iterazione-condizioni

Istruzione espressione

• <espressione>; è la forma più semplice di istruzione – i+2; è un'istruzione legittima, calcola la somma

e ne butta via il valore!– cin>>i; esempio di istruzione-espressione utile– ; istruzione nulla (può servire in alcuni casi di

iterazione, ma… va sempre commentata!)// read input until end-of-file or item foundwhile (cin >> s && s != sought); // null statement, placed on purpose

• Attenzione ai ; dispersi// disaster: extra semicolon: loop body is this null statementwhile (i < 10) ; // the while body is the empty statement++i; // increment is not part of the loop

6

NB: vale la regola del corto circuito

Page 7: 05 3 istruzioni-selezione-iterazione-condizioni

• Costrutto if: if ( espressione ) istruzione

int main()

{

int n;

cout << "Inserisci un numero" << endl;

cin >> n;

if ( n > 0 )

cout << "Numero positivo ! " << endl;

cout << "Fine del programma" << endl;

return 0;

}

Istruzioni condizionali (if-then-else)

ramothen

Page 8: 05 3 istruzioni-selezione-iterazione-condizioni

8

• Costrutto if-else:if ( espressione )

istruzione1else

istruzione2int main()

{

int n;

cout << "Inserisci un numero" << endl;

cin >> n;

if ( n > 0 )

cout << "Numero positivo ! " << endl;

else

cout << "Numero negativo o nullo ! " << endl;

cout << "Fine del programma" << endl;

return 0;

}

ramothen

ramoelse

Istruzioni condizionali complesse

Page 9: 05 3 istruzioni-selezione-iterazione-condizioni

Formattazione

if (numero < 0) valass = -x; else valass = x;

•Per maggior leggibilità, è bene usare regole di incolonnamento (indentazione)

Page 10: 05 3 istruzioni-selezione-iterazione-condizioni

10

#include <iostream> // Calcolo del valore assoluto

int main ( ) { // programma principale

int numero, valass; // dichiarazione delle variabili

cout << "Calcolo Valore Assoluto" << endl <<

"Inserisci Numero Intero: ";

cin >> numero; // acquisizione valore

if (numero < 0)

valass = -numero;

if (numero >= 0)

valass = numero;

cout << "Numero: " << numero << // output

"Valore assoluto: " << valass; // output

return 0;

}

ramothen

condizione

Istruzioni condizionali(selezione singola)

Page 11: 05 3 istruzioni-selezione-iterazione-condizioni

11

#include <iostream>

using namespace std;

int main() {

int numero, valass; // dichiarazione delle variabili

cout << "Calcolo del Valore Assoluto " << "Inserisci Numero Intero: "

<< endl;

cin >> numero; // acquisizione valore

if (numero < 0)

valass = -numero;

else

valass = numero;

cout << "Numero: " << numero << // output

" Valore assoluto: " << valass <<endl; // output

return 0;

}

Istruzioni condizionali(con selezione doppia)

Page 12: 05 3 istruzioni-selezione-iterazione-condizioni

Uso degli operatori relazionali

#include <iostream>using namespace std;

int main() {int num1, num2;cout << "Enter two integers, and I will tell you" <<

"the relationship they satisfy" << endl; cin >> num1 >> num2;

if (num1 == num2)cout << num1 << " Is equal to " << num2 << endl;

if (num1 != num2)cout << num1 << " Is not equal to " << num2 << endl;

if (num1 < num2)cout << num1 << " Is less than " << num2 << endl;

if (num1 > num2)cout << num1 << " Is greater than " << num2 << endl;

if (num1 <= num2)cout << num1 << " Is less or equal to " << num2 << endl;

if (num1 >= num2) cout << num1 << " Is greater or equal to " << num2 << endl;return 0;

}

12

Page 13: 05 3 istruzioni-selezione-iterazione-condizioni

Output

13

> Enter two integers, and I will tell you > the relationships they satisfy: 3 7> 3 is not equal to 7> 3 is less than 7> 3 is less than or equal to 7

> Enter two integers, and I will tell you > the relationships they satisfy: 22 12> 22 is not equal to 12> 22 is greater than 12> 22 is greater than or equal to 12

Page 14: 05 3 istruzioni-selezione-iterazione-condizioni

Ulteriori forme di selezione

• I rami di un if o if-else possono contenere istruzioni composte: if ( espressione )

{seq.1 di istruzioni}

else

{seq.2 di istruzioni }

• Gli if possono essere annidati per esprimere decisioni articolate

14

Page 15: 05 3 istruzioni-selezione-iterazione-condizioni

15

if (i < 100)

if (i > 0)

cout << "Minore di 100 e maggiore di 0" << endl;

else

if (i == 0)

cout << "Uguale a zero"<< endl;

else

cout << "Minore di zero"<< endl;

else

if (i == 100)

cout << "Uguale a 100"<< endl;

else

cout << "Maggiore di 100"<< endl;

if-then-else annidati

Page 16: 05 3 istruzioni-selezione-iterazione-condizioni

La lettura di if annidati

• In presenza di if annidati è bene imparare a valutare rapidamente quali valori delle variabili menzionate nelle condizioni producono l'ingresso in ciascun sotto-ramo

if (i < 100)if (i > 0)

...; // quanto vale i??else if (i == 0)

...; // quanto vale i?? else...; // quanto vale i??

else if (i == 100) ...; // quanto vale i??

else ...; // quanto vale i??

16

Page 17: 05 3 istruzioni-selezione-iterazione-condizioni

Ramo else pendente (dangling)

• Potenziale ambiguità insorge quando ci sono più if che else:– if (n > 0) if (a>b) z = a; else z = b;

• Ogni else si associa all’if più vicino– l'indentazione lo rende evidente – se incerti, usare le parentesi– if (n > 0) {if (a>b) z = a;} else z = b;

if (n > 0) {if (a>b) z = a;

}else

z = b;

if (n > 0) if (a>b)

z = a; else

z = b;

Page 18: 05 3 istruzioni-selezione-iterazione-condizioni

18

• Spesso accade di voler scrivere molti if annidati (alternative multiple):

if (...)fai qualcosa1;

elseif (…)

fai qualcosa2;else

if(…)

Sequenze di if

Page 19: 05 3 istruzioni-selezione-iterazione-condizioni

Esempio

if (n % 2 == 0)cout << n " è pari" << endl;

elseif (n % 3 == 0)

cout << n " è multiplo di 3" << endl; else

if (n % 5 == 0) cout << n " è multiplo di 5" << endl;

else if (n % 7 == 0)

cout << n " è multiplo di 7" << endl; else

if (n % 11 == 0) cout << n " è multiplo di 11" << endl;

else if (n % 13 == 0)

cout << n " è multiplo di 13" << endl; else

cout << n << " non ha divisori primi< 15" << endl;

/* Se un numero n ha divisori primi <15, stampa il minimo, altrimenti stampa un messaggio che lo segnala */

Page 20: 05 3 istruzioni-selezione-iterazione-condizioni

20

/* Se un numero n ha divisori primi <15, stampa il minimo, altrimenti stampa un messaggio che lo segnala */

Una rappresentazione più leggibile

Page 21: 05 3 istruzioni-selezione-iterazione-condizioni

Iterazione a condizione iniziale

• Ciclo whilewhile (condizione)Istruzione

• Si esegue istruzione fintantoché la condizione è vera• E' detto anche ciclo a condizione iniziale

–Se alla prima valutazione la condizione è falsa, non si esegue mai Istruzione

• Istruzione di solito contiene un'espressione che cambia il valore di una variabile usata in condizione

• Condizione è condizione di permanenza nel ciclo• Si usa

–Quando si deve iterare in modo indefinito, per esempio sull'input dell'utente–Quando si vuole ispezionare il valore delle variabili di governo della condizione anche dopo la terminazione del ciclo

21

Page 22: 05 3 istruzioni-selezione-iterazione-condizioni

22

Esempio di ciclo while

int main(){ int n = 9;

cout << " PRONTI... " << endl; while ( n > 0 ) {

cout << " ...meno " << n << endl; n = n-1; } cout << " ...VIA!!! " << endl; return 0;

}

condizione

Corpo del ciclo: blocco di istruzioni

variabile di

governo

Page 23: 05 3 istruzioni-selezione-iterazione-condizioni

Ciclo while: errori tipici

int main()

{

int n = 9;

cout << " PRONTI... " << endl;

while ( n > 0 )

cout << " ...meno " << n << endl;

n = n-1;

cout << " ...VIA!!! " << endl;

return 0;

}

ERRATO!!Che fa?

Page 24: 05 3 istruzioni-selezione-iterazione-condizioni

Ciclo while: errori tipici

int main()

{

int n = 9;

cout << " PRONTI... " << endl;

while ( n > 0 ); {

cout << " ...meno " << n << endl;

n = n-1;

}

cout << " ...VIA!!! " << endl;

return 0;

}

ERRATO!!Che fa?

Page 25: 05 3 istruzioni-selezione-iterazione-condizioni

25

Sequenze di input di lunghezza ignota

• Iterazione controllata da una "sentinella", cioè un valore che denota la fine della sequenza

• L’iterazione avviene un numero di volte non determinata a priori

• Procede fintantoché resta vera una condizione– L’inserimento, da parte dell’utente, della sentinella

al posto del valore da elaborare

• NB: si sceglie come sentinella un valore che non appartiene all'insieme dei valori da elaborare!

Page 26: 05 3 istruzioni-selezione-iterazione-condizioni

Schema tipico

26

cout << "fornisci valore da elaborare;se hai finito, fornisci …" << sentinella;

cin >> valore;while (valore != sentinella) {

elabora valore;cout << "fornisci valore da elaborare;se hai finito, fornisci …" << sentinella;

cin >> valore;}

Page 27: 05 3 istruzioni-selezione-iterazione-condizioni

Errore tipico

27

while (valore != sentinella) {cout << "fornisci valore da elaborare;se hai finito, fornisci …" << sentinella;

cin >> valore; elabora valore;}

Page 28: 05 3 istruzioni-selezione-iterazione-condizioni

28

Esempio di ciclo con sentinella

• Calcolare la media di una serie di numeri interi positivi inseriti dall’utente

• Il valore –1 indica la fine del flusso

• Applicazione– Calcolo della media dei voti della classe

con un numero arbitrario di voti

Page 29: 05 3 istruzioni-selezione-iterazione-condizioni

Pseudocodice

• Inizializzazione delle variabili:• Inizializza il totale a zero• Inizializza il contatore a zero

• Lettura, addizione e conteggio dei voti:• Leggi da terminale il prossimo voto (potrebbe essere la

sentinella)WHILE l’utente non ha ancora immesso la sentinella

– Aggiungi il voto al totale– Aggiungi uno al contatore– Leggi il prossimo voto (potrebbe essere la sentinella)

• Calcolo e scrittura della media:– IF il contatore è diverso da zero

• Calcola la media (uguale a totale / contatore)Stampa a terminale la media

– ELSEStampa a terminale “Non è stato immesso

alcun voto”

Page 30: 05 3 istruzioni-selezione-iterazione-condizioni

Programma media di una sequenza

int main() { int valore, sum = 0, num = 0, media; // la media verrà troncata const int sentinella = -1; cout << "Fornisci valore..." << endl; cout << "Per finire fornisci " << sentinella << endl; cin >> valore; while (valore != sentinella) { sum += valore; ++num; cout << endl << "Fornisci valore..." << endl; cout << "Per finire fornisci" << sentinella << endl; cin >> valore; } if (num > 0) { media = sum / num; // di che tipo è media?? cout << "La media dei valori è " << media; } else cout << "Nessun valore immesso" << endl; return 0;}

Page 31: 05 3 istruzioni-selezione-iterazione-condizioni

Versione con condizione nell'input

#include <iostream>

using namespace std;

int main() {

int contatore = 0, voto = 0;

float media = 0.0, totale = 0.0;

cout << "Inserisci serie di numeri; ctl-z per terminare" << endl;

cout << "Prox voto: " << endl;

while (cin >> voto) {

totale += voto;

++contatore;

cout << "Prossimo voto: " << endl;

}

if (contatore > 0) {

media = totale / contatore;

cout << endl << "Numero voti inseriti: " << contatore

<< " Somma numeri inseriti: " << totale << " Media dei voti: "

<< media << endl;

} else

cout << "Serie vuota" << endl;

return 0;

}

31

Si usa ctrl-z come sentinella, che termina del tutto l'input, oppure un carattere non numerico

Page 32: 05 3 istruzioni-selezione-iterazione-condizioni

32

Gli operatori ++ e --• Attenzione all'uso degli operatori incremento e decremento (++

e --)• ++i è un'espressione che prima incrementa i e poi ne fornisce il

valore (pre-incremento)• i++ è un'espressione che prima fornisce il valore di i e poi la

incrementa (post-incremento)– Esempio: sia la dichiarazione int c = 5;

cout << ++c; stampa 6 cout << c++; stampa 5

in entrambi i casi al termine dell'istruzione c ha valore 6• Il post-incremento è più costoso, perché deve salvare il valore

precedente all'incremento• All’interno di una espressione, però, è determinante la regola

del pre- e del post-– Quindi if ( i++ > 0 )… è diverso da if ( ++i > 0 )…

• Usare sempre la forma prefissa, a meno che non sia necessario preservare il valore precedente all'incremento

Page 33: 05 3 istruzioni-selezione-iterazione-condizioni

Lo stato di cin

• cin è un oggetto di tipo istream• Rappresenta una sequenza di caratteri letta dal

programma• Internamente l'oggetto mantiene lo stato

dell'ultima operazione di lettura• (cin>>voto) viene convertito in un valore di tipo

bool, secondo la seguente logica– true se la lettura è andata a buon fine– false se si è incontrato il carattere end-of-file

(ctrl-z) o si è letto un dato di tipo non conforme alla variabile a destra dell'operatore >>

• Nell'esempio anche una lettera al posto di un numero

33

Page 34: 05 3 istruzioni-selezione-iterazione-condizioni

34

1. Acquisisci i valori di A e B2. Calcola MIN, il minimo tra A e B3. Parti con X=1 ed assumi che MCD sia 14. Fintantoché X < MIN

1. incrementa X di 12. se X divide sia A sia B, assumi che MCD sia X

5. Mostra come risultato MCD

M.C.D. di due interi positivi

Page 35: 05 3 istruzioni-selezione-iterazione-condizioni

35

int main() {int x = 1;int mcd = 1;int a, b, min;cout << "Inserisci due numeri: ";cin >> a >> b;if (a < b) // Trovo il più piccolo tra a e b

min = a;else

min = b;while (x < min) { // Verifico tutti i numeri tra 2 e min

++x; // Prima incremento poi verificoif ((a % x)==0 && (b % x)==0 )

mcd = x;}cout << "Il MCD tra " << a << " e " << b << " è: "<< mcd;

return 0;}

Esempio: MCD v1

Page 36: 05 3 istruzioni-selezione-iterazione-condizioni

36

int main() { // Scansione numeri da 2 a min: ultimo trovato è MCDint x = 1;int mcd = 1;int a, b, min;cout << "Inserisci due numeri maggiori di zero: ";cin >> a >> b;if (a < b) // Trovo il più piccolo tra a e b

min = a;else

min = b;while (x <= min) { // Verifico tutti i numeri tra 1 e min

if ((a % x) == 0 && (b % x) == 0) // Prima verificomcd = x;

++x; // Poi incremento}cout << "Il MCD tra " << a << " e " << b << " è: " << mcd;

return 0;}

Esempio: MCD v2

Page 37: 05 3 istruzioni-selezione-iterazione-condizioni

37

int main() { // Si scandiscono i naturali diminuendo // a partire dal minimo tra a e b. // Il primo divisore comune trovato è il MCD

int mcd = 1;int a, b, x;cout << "Inserisci due numeri maggiori di zero: ";cin >> a >> b;if (a < b) // Trovo il più piccolo tra a e b

x = a;else

x = b; // e lo metto in xwhile (!((a%x) == 0 && (b%x) == 0)) { // Verifico numeri tra min e 1

--x; // Poi decremento} // all'uscita vale (a%x) == 0 && (b%x) == 0)mcd = x; // Il primo che trovo è MCDcout << "Il MCD tra " << a << " e " << b << " è: " << mcd;return 0;

}

Si tratta della negazione della condizione precedente

Esempio: MCD v3

Page 38: 05 3 istruzioni-selezione-iterazione-condizioni

38

int main() { // Si scandiscono i naturali diminuendo // a partire dal minimo tra a e b. // Il primo divisore comune trovato è il MCD

int mcd = 1;int a, b, x;cout << "Inserisci due numeri maggiori di zero: ";cin >> a >> b;if (a < b) // Trovo il più piccolo tra a e b

x = a;else

x = b; // e lo metto in xwhile ((a%x) != 0 || (b%x) != 0) { // Verifico numeri tra min e 1

--x; // Poi decremento}mcd = x; // Il primo che trovo è MCDcout << "Il MCD tra " << a << " e " << b << " è: " << mcd;return 0;

}

Esempio: MCD v4

Equivalente al precedente: per la legge di De Morgan

!( C && D ) !C || !D

Page 39: 05 3 istruzioni-selezione-iterazione-condizioni

39

Esempio: MCD v. Euclideint main() {

int mcd;

int a, b;

cout << "VERSIONE ALGORITMO DI EUCLIDE" <<

" Inserisci due numeri maggiori di zero: " << endl;

cin >> a >> b;

while (a != b) {

if (a > b)

a = a-b;

else

b = b-a;

}

mcd = a; // All'uscita dal ciclo a e b sono uguali

cout << "Il MCD è: " << mcd << endl;

return 0;

}

Scegliere a o b come MCD è indifferente: al momento dell’uscita dal ciclo while, infatti, a e b sono certamente uguali.

Page 40: 05 3 istruzioni-selezione-iterazione-condizioni

40

Analisi critica

Siamo sicuri che il ciclo termini sempre?–È cruciale l'ipotesi che a e b siano strettamente

positivi• Un programmatore scrupoloso effettuerebbe un

opportuno controllo sui dati in ingresso

–Sotto questa ipotesi, ad ogni passo o a o b decresce, ma resta positivo

–Non esiste una sequenza di coppie (a, b) che rispetti queste proprietà e che non sia finita

Riconosciamo nel corpo del ciclo una sezione che garantisce un

progressivo avvicinamento alla condizione di uscita (terminazione)

Page 41: 05 3 istruzioni-selezione-iterazione-condizioni

Cosa domandarsi mentre si scrive un ciclo

• Quali sono le variabili su cui il ciclo agisce?

• Quali sono i valori prima di entrare nel corpo del ciclo?

• Come agisce il corpo del ciclo sui valori delle variabili?

• Ci si avvicina SEMPRE alla condizione di uscita? Ci sono casi in cui ci si allontana o si resta fermi?

• Quali sono i valori dopo la terminazione del ciclo?

Page 42: 05 3 istruzioni-selezione-iterazione-condizioni

42

Stampa dei numeri pari minori di N

int main() { // Stampa dei numeri pari minori di N int n, pari = 0; // considera lo 0 pari cout << "Dammi un intero positivo : " << endl; cin >> n; while ( pari != n ) { pari += 2; } return 0;}

errore!!!

Page 43: 05 3 istruzioni-selezione-iterazione-condizioni

Conteggio con ciclo while

• Il ciclo while si può usare anche nel caso in cui il numero di iterazioni sia predeterminato (ad esempio N)

int contatore = 1;while (contatore <= N) {

…;++contatore;

}

int contatore = 0;while (contatore < N) {

…;++contatore;

}

Page 44: 05 3 istruzioni-selezione-iterazione-condizioni

44

Definito solo su interi non negativi

n * (n-1) * ... * 2 * 1 se n > 1

n! = 1 se n = 0, 1

indefinito altrimenti

Calcolo del fattoriale

Page 45: 05 3 istruzioni-selezione-iterazione-condizioni

45

int main() {int n, cont, fatt = 1;cout << "Fattoriale con while: inserisci n: " << endl;cin >> n;if (n < 0) /* verifica dati d’ingresso */

cout << "Numero negativo, fattoriale indefinito" << endl;else {

cont = n;while (cont > 1) {

fatt *= cont;--cont;

}cout << "Fattoriale di " << n << " vale " << fatt <<

endl;}

return 0;}

Calcolo del fattoriale

Quante volte viene eseguito il ciclo?

Page 46: 05 3 istruzioni-selezione-iterazione-condizioni

46

Tutto si può fare in molti modi

• In teoria– sequenze, if-else e while sono complete– bastano per codificare qualsiasi algoritmo

eseguibile da un computer• Teorema di Boehm e Jacopini

• In pratica– per rendere più semplice la scrittura dei

programmi i linguaggi introducono altre istruzioni di controllo

Page 47: 05 3 istruzioni-selezione-iterazione-condizioni

ATTENZIONE

Il ciclo do-while

do {

istruz.1

...

istruz.N

} while ( cond );

Istruz.1

...

Istruz.N

while ( cond ) {

istruz.1

...

istruz.N

}

Page 48: 05 3 istruzioni-selezione-iterazione-condizioni

Con ciclo while si ripeteva il codice sul primo elemento di una sequenza, con ciclo do-while si ripete la condizione

La "trasformazione inversa"

while ( cond ) {

istruz.1

...

istruz.N

}

do {

if ( cond ) {

istruz.1

...

istruz.N

}

} while ( cond );

Page 49: 05 3 istruzioni-selezione-iterazione-condizioni

49

Sentinellacout << "prompt"; cin >> valore;

while (valore != sentinella) {elabora valore;

cout << "prompt"; cin >> valore;

}do {

cout << "prompt"; cin >> valore;

if (valore != sentinella) {

elabora valore;}

} while (valore != sentinella);

Page 50: 05 3 istruzioni-selezione-iterazione-condizioni

Do-while per interazione ripetitiva

int main() { char rsp; // used in the condition; // can't be defined inside the do do {

cout << "enter two values: " << endl;int val1 = 0, val2 = 0;cin >> val1 >> val2;cout << endl << "The sum of " << val1

<< " and " << val2 << " = " << val1 + val2 << "\n\n" << "More? Enter y or n: " << endl;

cin >> rsp;} while (rsp != 'n');

cout << "Thank you for playing!!" << endl; return 0;}

50

Page 51: 05 3 istruzioni-selezione-iterazione-condizioni

I caratteri speciali

• \n: carattere "a capo"– A differenza di endl non produce lo

svuotamento del buffer

• Sono usati come un carattere singolo

51

Page 52: 05 3 istruzioni-selezione-iterazione-condizioni

52

Il ciclo for

for ( exp.Iniz; cond; exp.Incr ) {

ist.1;

...

ist.N;

}

exp.Iniz;

while ( cond ) {

ist.1;

...

ist.N;

exp.Incr;

}

Page 53: 05 3 istruzioni-selezione-iterazione-condizioni

53

cont = 0;while (cont < N)

{…;…;

cont++;}

for (cont = 0; cont < N; ++cont) {

…;…;

}

Ciclo a contatore

Page 54: 05 3 istruzioni-selezione-iterazione-condizioni

54

INIZIO

FINE

S = 0

LEGGI N

I > N

SCRIVI:LASOMMA E’ S

sìno

S = S + I

I = 1

I = I + 1

ciclo

istruzione di test

istruzione di inizializzazione

istruzione di inizializzazione

istruzione di assegnamento

istruzione di assegnamento

istruzione di I/O(lettura)

istruzione di I/O(scrittura)

Somma dei primi N numeri naturali

Page 55: 05 3 istruzioni-selezione-iterazione-condizioni

#include <iostream>

/* Somma dei primi N naturali */

int main() {

int n;

cout << "Versione con ciclo a condizione iniziale"

<< "\nInserisci n: " << endl;

cin >> n;

if (n >= 0) {

int somma = 0, i = 1; // dichiarazione vicino all'uso

while (i <= n) {

somma += i;

++i;

}

cout << "La somma vale: " << somma << endl;

}

return 0;

corpo del ciclo

condizione di permanenza nel ciclo

Ciclo a condizione iniziale - while

Page 56: 05 3 istruzioni-selezione-iterazione-condizioni

#include <iostream>/* Somma dei primi N numeri naturali */int main ( ) {

int n;cout << "Versione con ciclo a condizione finale" << "\nInserisci n: " << endl;cin >> n;if (n > 0) {

int somma = 0, i = 1;do { // ciclo a condizione finale

somma += i;++i;

} while (i <= n);

cout << "La somma vale: " << somma << endl;}return 0;

}

corpo del ciclo condizione di

permanenza nel ciclo

Ciclo a condizione finale - do

Page 57: 05 3 istruzioni-selezione-iterazione-condizioni

57

#include <iostream>/* Somma dei primi N numeri naturali */int main() {

int n, somma=0;cout << "Versione con ciclo a conteggio" << "\nInserisci n: " << endl;cin >> n;if (n >= 0) {

somma = 0;for (int i = 1; i <= n; ++i) { // ciclo a

conteggiosomma += i;

}cout << "La somma vale: " << somma << endl;

}return 0;

}

corpo del ciclo

intestazionedel ciclo

Ciclo a conteggio - for

Page 58: 05 3 istruzioni-selezione-iterazione-condizioni

Visibilità della variabile di controllo

for (int i = 1; i <= n; ++i) { blocco}

– Se la variabile di controllo (i) è dichiarata all'interno del ciclo for si può usare solo nel blocco del ciclo

int i;

for (i = 1; i <= n; ++i) { blocco}

– Se la variabile di controllo (i) è usata all'interno del ciclo for ma dichiarata prima, si può usare sia nel blocco del ciclo sia fuori

58

Page 59: 05 3 istruzioni-selezione-iterazione-condizioni

Altra formulazione del fattoriale#include <stdio.h>

/* Calcolo del fattoriale */

int main() {

int n, fatt = 1;

cout << "Fattoriale con for: inserisci n: " << endl;

cin >> n;

if (n < 0) /* verifica dati d’ingresso */

cout << "Numero negativo, fattoriale indefinito" << endl;

else {

for (int cont = n; cont > 1; --cont)

fatt *= cont;

cout << "Fattoriale di " << n << " vale " << fatt << endl;

}

return 0;

}

intestazionedel ciclo

corpo del ciclo

Page 60: 05 3 istruzioni-selezione-iterazione-condizioni

Istruzione condizionale a scelta multipla: switch

switch ( var ) {

case v1: ist.1; break; case ...: ist.2; break;

case vi:

case vj: ist.ij; break; case ...: ist.3; break;

case vN: ist.N; break; default: ist.U; break;}

• Consente la scelta tra numerose opzioni prefissate

– L' espressioni tra parentesi (di tipo integral) è confrontata con il valore di ogni caso (case label)

– I valori delle case label (v) devono essere di tipo integral

• Se il valore concorda si esegue la prima istruzione successiva al case

• L'istruzione break interrompe lo switch e l'esecuzione procede dall'istruzione ad esso seguente

• Se nessun valore concorda, l'esecuzione procede dalla prima istruzione che segue lo switch

Page 61: 05 3 istruzioni-selezione-iterazione-condizioni

Conteggio delle vocaliint main() {

// initialize counters for each vowelunsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;char ch;while (cin >> ch) {

// if ch is a vowel, increment the appropriate counterswitch (ch) {case 'a':

++aCnt;break;

case 'e':++eCnt;break;

case 'i':++iCnt;break;

case 'o':++oCnt;break;

case 'u':++uCnt;break;

}}// print resultscout << "Number of vowel a: \t" << aCnt << '\n' << "Number of vowel e: \t"

<< eCnt << '\n' << "Number of vowel i: \t" << iCnt << '\n'<< "Number of vowel o: \t" << oCnt << '\n'<< "Number of vowel u: \t" << uCnt << endl;

return 0;}

Page 62: 05 3 istruzioni-selezione-iterazione-condizioni

Switch e case label

• I valori delle case label (v) devono essere di tipo integral

int ival = 42;

switch(ch) {

case 3.14: // error: noninteger as case label

case ival: // error: nonconstant as case label

• Normalmente dopo le istruzion di un caso o gruppo di casi si inserisce break;

• Omettere break è un errore comune, se non serve meglio aggiungere un commento che spieghi perché

• La label default, se presente, concorda con qualsiasi valore dell'espressione di controllo

• E' buona prassi mettere un caso default anche se non si devono eseguire istruzioni, per segnalare che si è considerato il caso

– In questo caso va messo un blocco vuoto {} o l'istruzione nulla ;

Page 63: 05 3 istruzioni-selezione-iterazione-condizioni

#include <iostream>int main() {

char c;int n_cifre = 0, n_separatori = 0, n_altri = 0;do {

cout << "dammi un carattere; ! per terminare " << endl;cin >> c;switch (c) {case '0': case '1': case '2': case '3':case '4': case '5': case '6': case '7':case '8': case '9': ++n_cifre;

break;case '.':case ';':case ':':case ',':

++n_separatori;break;

default: // considera anche ! tra gli altri caratteri++n_altri;

}

} while (c != '!');cout << "cifre: " << n_cifre << " separatori: " << n_separatori

<< " altri: " << n_altri << endl;return 0;

}

Page 64: 05 3 istruzioni-selezione-iterazione-condizioni

Switch e inizializzazione di variabili

• Bypass illegale

case true: // illegal bypass

int ival = 0; // error: control bypasses explicitly initialization

int jval; // ok: jval not initialized

break;

case false: // ok

jval = 3; // ok: assign a value to jval

if (ival > 0) // ko, file_name in scope

// but not initialized

• Uso di un blocco per limitare la visibilità della variabile all'esterno del case

case true:

{ // ok: declaration statement within a statement block

int ival = 22;

// ...

}

64

Page 65: 05 3 istruzioni-selezione-iterazione-condizioni

Istruzioni break e continue

• break fa uscire da corpo di un ciclo o da switch

• continue interrompe iterazione corrente di un ciclo (do, while o for) e dà inizio alla iterazione successiva

Page 66: 05 3 istruzioni-selezione-iterazione-condizioni

/* ciclo con elaborazioni su una serie di valori (al più N), assunti successivamente dalla variabile intera x saltando i valori negativi e interrompendo l'elaborazione al primo zero incontrato */

int main() { // somma solo i numeri positivi immessi int x, somma = 0, n = 10; for (int i = 0; i < n; ++i) { cout << "passo " << i << " immettere un intero: " << endl; cin >> x; if (x < 0) // salta il valore continue; if (x == 0) // termina il ciclo break; somma += x; // elabora se positivo } cout << "La somma dei numeri positivi vale:" << somma << endl; return 0;}

Esempio

Page 67: 05 3 istruzioni-selezione-iterazione-condizioni

• Trasferimento esplicito e incondizionato del flusso di esecuzione

• Quasi sempre da evitare! (spaghetti programs)

int main() { // somma solo i numeri positivi immessii, x, somma = 0, n = 10;for (int i = 0; i < n; ++i) {

cout << "passo " << i+1 << " immettere un intero: " << endl;cin >> x;if (x < 0)

continue;if (x == 0)

goto finito;somma += x;

}finito: cout << "La somma dei positivi vale:" << somma << endl;return 0;

}

Istruzione goto

Page 68: 05 3 istruzioni-selezione-iterazione-condizioni

68

Consigli

• Fare in modo che il flusso di controllo sia poco intricato (evitare goto)

• Usare cicli for quando il numero di iterazioni è noto a priori

• Usare cicli a condizione finale quando si è certi di dover iterare almeno una volta, quelli a condizione iniziale quando può succedere di non dover estrare nel ciclo

• Attenzione a non dimenticare i break in uno switch• Mettere il caso di default in uno switch anche se non

si deve fare nulla• Usare MOLTO parsimoniosamente break e

continue nei cicli

Page 69: 05 3 istruzioni-selezione-iterazione-condizioni

Un altro esempio di costruzione incrementale dei programmi

(approccio top down)

• Si leggono sequenze di gruppi di numeri naturali; i gruppi sono separati dal valore 0

• L’ultimo gruppo è terminato dal valore -1

• Si stampi in output una sequenza di naturali corrispondenti alle somme dei valori contenuti nei singoli gruppi

Page 70: 05 3 istruzioni-selezione-iterazione-condizioni

Passo 1

Che cosa serve

• Una variabile per il numero letto

• Una variabile per la somma di gruppo

Inizio

Fine

C'è un gruppo?

Calcola somma gruppo

no

si

Comincia a leggere input

Stampa somma gruppo

Page 71: 05 3 istruzioni-selezione-iterazione-condizioni

Passo 2

71

Inizio

Fine

while (i != -1)

Calcola somma gruppo

no

si

int i; cin >> i;

Stampa somma gruppo

Page 72: 05 3 istruzioni-selezione-iterazione-condizioni

Passo 3

72

Inizio

Fine

while (i != -1)

sum=0;

no

si

int i, sum; cin >> i;

cout << sum;

accumula somma

Page 73: 05 3 istruzioni-selezione-iterazione-condizioni

Passo 4

73

Inizio

Fine

while (i != -1)

sum=0;

no

si

int i, sum; cin >> i;

cout << sum; cin>>i;

sum = sum + 1; cin >> i;

gruppo prosegue?

si

no

// Fine gruppo

Page 74: 05 3 istruzioni-selezione-iterazione-condizioni

Passo 5

74

Inizio

Fine

while (i != -1)

sum=0;

no

si

int i, sum; cin >> i;

cout << sum; cin >> i;

sum = sum + 1; if (i!=-1) cin >> i;

i!=-1 && i!=0

si

no

Page 75: 05 3 istruzioni-selezione-iterazione-condizioni

Codice C++

int main() {

int num, sum = 0;

cout << "Inserire un numero, -1 termina, 0 termina gruppo: " << endl;

cin >> num;

while (num != -1) { // finché ci sono gruppi

sum = 0;

while (num != -1 && num != 0) { // finché ci sono numeri nel gruppo

sum += num;

cout << "inserire un numero, -1 termina, 0 termina gruppo: "

<< endl;

cin >> num;

}

cout << "Somma: " << sum << endl; // stampa somma gruppo appena terminato

if (num != -1) {

cout << "Inserire un numero, -1 termina, 0 termina gruppo: "

<< endl;

cin >> num;

}

}

cout << "Grazie e alla prossima!!" << endl;

return 0;

}

75

Page 76: 05 3 istruzioni-selezione-iterazione-condizioni

76

Che cosa abbiamo fatto

• Il programma è ottenuto per passi successivi di raffinamento

• È scritto ad ogni passo in un misto di C e di linguaggio naturale (pseudo-codice)

• Alla fine del processo di raffinamento risulta scritto in C ed è eseguibile

• I passi scritti in linguaggio naturale e raffinati al passo successivo possono diventare commenti

Page 77: 05 3 istruzioni-selezione-iterazione-condizioni

• L’utente immette una sequenza (di lunghezza libera) di caratteri alfabetici terminata dal carattere ‘.’

• Il programma deve rifiutare e ignorare ogni carattere non alfabetico diverso da ‘.’– Va bene accettare solo caratteri alfabetici minuscoli

• Al termine dell’elaborazione il programma segnala – la vocale inserita il maggior numero di volte [indicando anche

quante volte]• In caso di “equinumerosità” tra più vocali, va bene una qualsiasi

– il numero totale di consonanti

• Aggiunte per renderlo più “difficile”:– Considerare i caratteri case-insensitive (cioè d è uguale a D)– Indicare tutte le vocali, in caso di “equinumerosità”– Segnalare anche la lunghezza della massima sequenza di

caratteri consecutivi uguali, considerando che comunque i caratteri non alfabetici interrompono il conteggio di tali sequenze [a_bB@bbì^+pcDdg+pPPba°pabP*Pab. 3]

Esercizio (filtro a memoria finita)