G. Mecca – Università della Basilicata – mecca@unibas.it
Programmazione Procedurale in Linguaggio C++
Strutture di Controllo Parte 4
Conclusioni
versione 2.1
Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)
Sommario
m Ricapitolazione
m Convenzioni di Stile
m Tecniche Algoritmiche Notevoli
ðSomma con Accumulatore ðConteggio con Contatore ðVariabili Bandiera (“flag”) ðSimulazione
ðConvalida dei Dati in Ingresso
m Errori Frequenti
Strutture di Controllo: Conclusioni >> Sommario
G. Mecca - Programmazione Procedurale in Linguaggio C++ 3
Ricapitolazione
m
Strutture di controllo
ðelementi fondamentali della programmazione procedurale
ðconsentono di eseguire o meno una porzione di programma sulla base di condizioni
m
Due categorie
ðistruzioni condizionali ðistruzioni iterative o cicli
Strutture di Controllo: Conclusioni >> Ricapitolazione
Ricapitolazione
m
Istruzioni condizionali
ðservono ad eseguire una porzione oppure un’altra sulla base del valore di una
condizione
m
Condizione
ðespressione a valori booleani
m
Due istruzioni (in tutti i linguaggi)
ðIF-THEN-ELSEðIF-THEN
Strutture di Controllo: Conclusioni >> Ricapitolazione
G. Mecca - Programmazione Procedurale in Linguaggio C++ 5
Ricapitolazione
m
Istruzioni iterative
ðservono ad eseguire più volte una porzione di programma sulla base del valore di una condizione
m
Due istruzioni (in tutti i linguaggi)
ðWHILE (cicli “aperti” oppure cicli “chiusi”) ðFOR (cicli “chiusi” o a conteggio)
Strutture di Controllo: Conclusioni >> Ricapitolazione
Convenzioni di Stile
m
In questo corso (e nei successivi)
ðconvenzioni sullo “stile di scrittura” del codice
m
Obiettivi
ðuniformare il modo di scrivere il codice ðper renderlo più leggibile
ðe per favorire la collaborazione nei gruppi di lavoro
m
Tendenza internazionale
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
G. Mecca - Programmazione Procedurale in Linguaggio C++ 7
Convenzioni di Stile
m
Nelle lezioni successive
ðraffineremo progressivamente le nostre regole
ðin modo che valgano anche dopo (Java, C#)
m
Per ora
ða) regole sull’indentazione del codice ðb) regole sulle parentesi graffe
ðc) regole sulle espressioni ðd) regole sui nomi di variabili
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
Convenzioni di Stile
m
a) Indentazione
ðcodice di un programma: insieme di blocchi nidificati (es: strutture di controllo)
m
Per rendere più leggibile il codice
ðè necessario dentellarlo (o “indentarlo”) ðle istruzioni di ogni blocco sono rientraterispetto alle parentesi ðmolto importante
m
Regola: rientri di 4 spazi
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
G. Mecca - Programmazione Procedurale in Linguaggio C++ 9
Codice senza Indentazione
#include <iostream.h>
void main() {
float voto, sommaVoti, media;
int numeroEsami;
bool continua;
continua = true;
numeroEsami = 0;
sommaVoti = 0.0;
while (continua == true) {
cout << "Immetti il voto (0 per fermarti)" << endl;
cin >> voto;
if (voto == 0) continua = false;
else { numeroEsami++;
sommaVoti += voto;
} }
if (numeroEsami > 0) { media = sommaVoti/numeroEsami;
cout << "La media vale: " << media << endl;
} else
cout << "Non hai fornito nessun voto" << endl;
}
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
Convenzioni di Stile
m
b) Posizione delle parentesi graffe
ðdue convezioni principaliStrutture di Controllo: Conclusioni >> Convenzioni di Stile
if (condizione) {
<istruzioni>;
}
if (condizione) {
<istruzioni>;
} else {
<istruzioni>;
}
if (condizione) {
<istruzioni>;
} else {
<istruzioni>;
}
Convenzione n.1 Convenzione n.2
G. Mecca - Programmazione Procedurale in Linguaggio C++ 11
Convenzioni di Stile
m
Regola n.1
ðadotteremo la convenzione n.1
m
Regola n.2
ðutilizzeremo sempre le parentesi
ðanche nel caso in cui un blocco contenga un’unica istruzione
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
Convenzioni di Stile
m
c) Scrittura delle espressioni
ðespressione: fatta di operandi ed operatori ðper renderla più leggibile è possibile inserire
spazi tra operandi ed operatori
m
Esempio
ð(sqrt(x)+(y-z))==k
ð(sqrt(x) + (y - z)) == k
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
G. Mecca - Programmazione Procedurale in Linguaggio C++ 13
Convenzioni di Stile
m
d) Nomi delle variabili
ðidentificatoriðregola n.1: iniziale minuscola (es: voto, continua)
ðregola n.2: convenzione “cammello”
m
Convenzione cammello
ðidentificatore fatto di più parole concatenate ðogni iniziale a parte la prima è maiuscola ðes: sommaVoti, numeroEsami
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
#include <iostream.h>
void main() {
int voto, sommaVoti, numeroEsami;
float media;
bool continua;
continua = true;
numeroEsami = 0;
sommaVoti = 0;
while (continua == true) {
cout << "Immetti il voto (0 per fermarti)" << endl;
cin >> voto;
if (voto == 0) { continua = false;
} else {
numeroEsami++;
sommaVoti += voto;
} }
if (numeroEsami > 0) {
media = ((float)sommaVoti) / numeroEsami;
cout << "La media vale: " << media << endl;
} else {
cout << "Non hai fornito nessun voto" << endl;
} }
Strutture di Controllo: Conclusioni >> Convenzioni di Stile
a) rientri di 4 spazi
NO più istruzioni per linea b) posizione delle parentesi
NO convenzione n. 2 + parentesi sempre
c) espressioni
NO (continua==true) d) nomi delle variabili
NO numeroesami NO somma_voti
G. Mecca - Programmazione Procedurale in Linguaggio C++ 15
Tecniche Algoritmiche Notevoli
m
A questo punto
ðpotremmo procedere alla simulazione dell’esecuzione dei progetti di riferimento
m
Ma, prima di farlo
ðè opportuno descrivere preliminarmente alcuni aspetti del codice
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Tecniche Algoritmiche Notevoli
m
Infatti
ði due programmi utilizzano delle “tecniche algoritmiche notevoli”
m
Tecniche algoritmiche notevoli
ðsoluzioni standard a problemi ricorrenti di programmazione
ðrappresentano un bagaglio di conoscenze riutilizzabili per il programmatore
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
G. Mecca - Programmazione Procedurale in Linguaggio C++ 17
Tecniche Algoritmiche Notevoli
m
Tecniche notevoli nei due progetti
ðsomma con variabile “accumulatore” >>somma dei voti
ðconteggio con variabile “contatore” >>
conteggio del numero di esami
ðutilizzo di una variabile “bandiera” >>
controllo del ciclo while
m
Inoltre, vedremo anche
ðconvalida dei dati forniti dall’utente
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Somma con Accumulatore
m
Somma dei voti
ðutilizzo una variabile come “accumulatore”
ðinizialmente la variabile vale 0
ðad ogni esecuzione del ciclo sommo al
valore precedente il nuovo voto (“accumulo” il valore nella variabile)
m
Tecnica notevole
ðutilizzabile tutte le volte che bisogna sommare un insieme di valori
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
G. Mecca - Programmazione Procedurale in Linguaggio C++ 19
Somma con Accumulatore
1. float voto, sommaVoti;
2. int numeroEsami, i;
3. cout << "Quanti esami ? “;
4. cin >> numeroEsami;
5. sommaVoti = 0.0;
6. for (i = 0; i < numeroEsami; i++) { 7. cout << “Voto ? ";
8. cin >> voto;
9. sommaVoti = sommaVoti + voto;
10. }
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
xxx voto
#2503
xxx i
#2502
xxx sommaVoti
#2501
xxx numeroEsami
#2500
Memoria RAM
Schermo 3
Quanti esami ? 3 Voto ? 21 Voto ? 22 Voto ? 24
0.0 0 21 21.0 1 22 43.0 2 24
67.0 3
Somma con Accumulatore
m
La stessa tecnica
ðè usata anche nella versione basata su while
m
In questo caso però
ðoltre a sommare i voti, bisogna anche contare gli esami
ðinoltre bisogna decidere quando fermarsi ða questo scopo vengono usate due altre
tecniche notevoli
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
G. Mecca - Programmazione Procedurale in Linguaggio C++ 21
Conteggio con Contatore
m
Conteggio degli esami
ðconteggio attraverso la variabile intera numeroEsami
ðla variabile svolge le funzioni di “contatore”
ðvalore iniziale pari a 0
ðincrementata ad ogni nuovo voto
m
Anche questa è una tecnica notevole
ðcontare gli elementi di un insiemeStrutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Un Esempio: Media con While
#include <iostream.h>
void main() {
int voto, sommaVoti, numeroEsami;
float media;
bool continua;
continua = true;
numeroEsami = 0;
sommaVoti = 0;
while (continua == true) {
cout << "Immetti il voto (0 per fermarti)" << endl;
cin >> voto;
if (voto == 0) { continua = false;
} else {
numeroEsami++;
sommaVoti += voto;
} }
if (numeroEsami > 0) {
media = ((float)sommaVoti) / numeroEsami;
cout << "La media vale: " << media << endl;
} else {
cout << "Non hai fornito nessun voto" << endl;
}
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
G. Mecca - Programmazione Procedurale in Linguaggio C++ 23
Conteggio con Contatore
m
Attenzione
ðabbiamo già visto questa tecnica
m
Cicli a conteggio
ðè la stessa tecnica che viene utilizzata per controllare i cicli a conteggio
ðanche in quel caso viene utilizzato un contatore (per contare il numero di esecuzioni del ciclo)
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Un Esempio Già Visto: I 5 Quadrati
#include <iostream.h>
void main() {
float lato, area;
int i;
i = 0;
while (i < 5){
cout << “Immetti la lung. del lato” << endl;
cin >> lato;
area = lato * lato;
cout << “Area quadrato: “ << area << endl;
i++;
}
cout << “Fine”;
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
ATTENZIONE:
nel caso della media non conto il numero di esecuzioni del ciclo, ma
il numero di voti forniti
G. Mecca - Programmazione Procedurale in Linguaggio C++ 25
Variabile Bandiera (“Flag”)
m
Quando fermarsi ?
ðviene utilizzata una variabile booleana ðinizializzata a true
ðil ciclo prosegue finchè la var. è vera (la var.
è la bandiera che da via libera al ciclo) ðad ogni nuovo voto si controlla se l’utente
vuole interrompere; in questo caso la variabile diventa falsa)
m
Tecnica notevole per il controllo di cicli
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Un Esempio: Media con While
#include <iostream.h>
void main() {
int voto, sommaVoti, numeroEsami;
float media;
bool continua;
continua = true;
numeroEsami = 0;
sommaVoti = 0;
while (continua == true) {
cout << "Immetti il voto (0 per fermarti)" << endl;
cin >> voto;
if (voto == 0) { continua = false;
} else {
numeroEsami++;
sommaVoti += voto;
} }
if (numeroEsami > 0) {
media = ((float)sommaVoti) / numeroEsami;
cout << "La media vale: " << media << endl;
} else {
cout << "Non hai fornito nessun voto" << endl;
}
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
G. Mecca - Programmazione Procedurale in Linguaggio C++ 27
Variabile Bandiera (“Flag”)
m
Una annotazione
ðla condizione del ciclo while avrebbe potuto essere scritta anche come
while (continua) {...}
ðinfatti, le due espressioni,
(continua)
(continua==true)
sono equivalenti (vere se “continua” vale true, false se continua vale false”)
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
espressione fatta da un unico operando e nessun operatore
Variabile Bandiera (“Flag”)
m
Più in generale
ðdata una variabile b di tipo bool ðdovunque sia necessario utilizzare
un’espressione del tipo (b==true), è possibile utilizzare solo (b)
ðdovunque sia necessario utilizzare
un’espressione del tipo (b==false) è possibile utilizzare solo (!b)
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
vera se b vale false
G. Mecca - Programmazione Procedurale in Linguaggio C++ 29
Simulazione
m
A questo punto
ðsiamo pronti a simulare l’esecuzione della versione con while
ðci concentriamo sull’esecuzione del ciclo while, e quindi
ðsulla somma ðsul conteggio ðsull’uso del flag
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Simulazione
1. continua = true;
2. numeroEsami = 0;
3. sommaVoti = 0;
4. while (continua == true) { 5. cout << “Voto? (0 stop)“;
6. cin >> voto;
7. if (voto == 0) { 8. continua = false;
9. } else {
10. numeroEsami++;
11. sommaVoti += voto;
12. } 13. } 14. ...
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
xxx voto
#2503
xxx continua
#2502
xxx sommaVoti
#2501
xxx numeroEsami
#2500
Memoria RAM
Schermo 0
Voto? (0 stop) 21 0 true 21
21 false 22 43
Voto? (0 stop) 22 Voto? (0 stop) 0
12
0
G. Mecca - Programmazione Procedurale in Linguaggio C++ 31
Convalida dell’Input
m
I due programmi acquisiscono dati dall’utente
ðsarebbe necessario verificare la correttezza dei valori forniti
ðes: voto tra 18 e 30
ðes: numero di esami >= 0
m
Convalida dei valori in ingresso
ðè possibile utilizzare un ciclo whileStrutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
mediaForConvalida.cpp >>
mediaWhileConvalida.cpp >>
Convalida dell’Input
m In particolare
ðil ciclo viene dopo una lettura;
es: cin >> numeroEsami;
ðla condizione del ciclo è vera nel caso in cui il valore letto sia scorretto
es: while (numeroEsami <= 0) {...}
ðse viene letto un valore corretto, il ciclo di convalida viene ignorato
ðse viene letto un valore scorretto, il ciclo inizia, e va avanti finchè non viene fornito un valore corretto
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
G. Mecca - Programmazione Procedurale in Linguaggio C++ 33
Convalida dell’Input
cout << “Esami ?" << endl;
cin >> numeroEsami;
while (numeroEsami < 0) { cout << “Errore“ << endl;
cout << “Esami ?" << endl;
cin >> numeroEsami;
}
bool continua;
continua = true;
while (continua) {
cout << “Esami ?" << endl;
cin >> numeroEsami;
if (numeroEsami < 0) { cout << "Errore“;
} else {
continua = false;
} }
Strutture di Controllo: Conclusioni >> Tecniche Algoritmiche Notevoli
Svantaggi di questa soluzione:
- il codice è meno compatto - è molto meno leggibile Utilizzeremo la seconda
Una soluzione alternativa:
Errori Frequenti
m
Un errore sintattico frequente
ðparentesi graffe mancanti per i blocchi delle istruzioni di controllo
m
Due casi
ðentrambe le parentesi mancanti ðsolo la parentesi finale è mancante
Strutture di Controllo: Conclusioni >> Errori Frequenti
G. Mecca - Programmazione Procedurale in Linguaggio C++ 35
Un Esempio: Media con For
#include <iostream.h>
void main() {
int voto, sommaVoti;
float media;
int numeroEsami, i;
cout << "Quanti esami hai sostenuto ?" << endl;
cin >> numeroEsami;
sommaVoti = 0;
for (i = 0; i < numeroEsami; i++) {
cout << "Immetti il voto di un esame" << endl;
cin >> voto;
sommaVoti += voto;
if (numeroEsami > 0)
media = ((float)sommaVoti) / numeroEsami;
cout << "La media vale: " << media << endl;
else {
cout << "Non hai fornito nessun voto" << endl;
} }
Strutture di Controllo: Conclusioni >> Errori Frequenti
manca la parentesi di chiusura mancano le parentesi
del I blocco
Errori Frequenti
m Nel primo caso (parentesi di chiusura)
ðil compilatore considera il blocco aperto fino alla fine del file e alla fine del file segnala l’errore
ðError E2134 mediaFor.cpp 23: Compound statement missing } in function main()
ð“Blocco di istruzioni senza parentesi chiusa”
m Nel secondo caso (parentesi dell’if)
ðil compilatore considera il blocco fatto di una sola istruzione; errore quando incontra “else”
ðError E2054 mediaFor.cpp 20: Misplaced else in function main()
ð“Else fuori posto”
Strutture di Controllo: Conclusioni >> Errori Frequenti
G. Mecca - Programmazione Procedurale in Linguaggio C++ 37
Errori Frequenti
m
Un errore logico frequente
ðnei cicli a conteggio programmati con while, gestione scorretta della variabile di ciclo ðmancanza dell’inizializzazione
ðmancanza dell’incremento
m
In questi casi
ðil ciclo si comporta in modo scorretto ðnel secondo caso si verifica un loop
Strutture di Controllo: Conclusioni >> Errori Frequenti
Errori Frequenti
Strutture di Controllo: Conclusioni >> Errori Frequenti
m Manca inizializzazione
ðil comportamento è casuale
ðdipende dal valore di i
int i;
while (i < 5) {
cout << “Valore di i: “;
cout << i << endl;
i++;
}
m Manca l’incremento
ðtipicamente si verifica un “loop”
int i;
i = 0;
while (i < 5) {
cout << “Valore di i: “;
cout << i << endl;
}
G. Mecca - Programmazione Procedurale in Linguaggio C++ 39
Riassumendo
m Ricapitolazione
m Convenzioni di Stile (ATTENZIONE)
m Tecniche Algoritmiche Notevoli (ATTENZIONE)
ðSomma con Accumulatore ðConteggio con Contatore ðVariabili Bandiera (“flag”) ðSimulazione
ðConvalida dei Dati in Ingresso
m Errori Frequenti
Strutture di Controllo: Conclusioni >> Sommario
Un Esempio: Media con For
#include <iostream.h>
void main() {
int voto, sommaVoti;
float media;
int numeroEsami, i;
cout << "Quanti esami hai sostenuto ?" << endl;
cin >> numeroEsami;
sommaVoti = 0;
for (i = 0; i < numeroEsami; i++) {
cout << "Immetti il voto di un esame" << endl;
cin >> voto;
sommaVoti += voto;
}
if (numeroEsami > 0) {
media = ((float)sommaVoti) / numeroEsami;
cout << "La media vale: " << media << endl;
} else
cout << "Non hai fornito nessun voto" << endl;
}
Strutture di Controllo: Conclusioni >> Un Esempio
G. Mecca - Programmazione Procedurale in Linguaggio C++ 41
Un Esempio: Media con While
#include <iostream.h>
void main() {
int voto, sommaVoti, numeroEsami;
float media;
bool continua;
continua = true;
numeroEsami = 0;
sommaVoti = 0;
while (continua == true) {
cout << "Immetti il voto (0 per fermarti)" << endl;
cin >> voto;
if (voto == 0) { continua = false;
} else {
numeroEsami++;
sommaVoti += voto;
} }
if (numeroEsami > 0) {
media = ((float)sommaVoti) / numeroEsami;
cout << "La media vale: " << media << endl;
} else {
cout << "Non hai fornito nessun voto" << endl;
} }
Strutture di Controllo: Conclusioni >> Un Esempio
Termini della Licenza
m This work is licensed under the Creative Commons Attribution- ShareAlike License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Termini della Licenza
m Questo lavoro viene concesso in uso secondo i termini della licenza “Attribution-ShareAlike” di Creative Commons. Per ottenere una copia della licenza, è possibile visitare
http://creativecommons.org/licenses/by-sa/1.0/ oppure inviare una lettera all’indirizzo Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.