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) G. Mecca – Università della Basilicata – [email protected] Strutture di Controllo: Conclusioni >> Sommario Sommario Ricapitolazione Convenzioni di Stile Alcune Tecniche Notevoli Somma con Accumulatore Conteggio con Contatore Variabili Bandiera (“flag”) Convalida dei Dati in Ingresso Errori Frequenti G. Mecca - Programmazione Procedurale in Linguaggio C++ 2 Strutture di Controllo: Conclusioni >> Ricapitolazione Ricapitolazione Strutture di controllo elementi fondamentali della programmazione procedurale consentono di eseguire o meno una porzione di programma sulla base di condizioni Due categorie istruzioni condizionali istruzioni iterative o cicli G. Mecca - Programmazione Procedurale in Linguaggio C++ 3 Strutture di Controllo: Conclusioni >> Ricapitolazione Ricapitolazione Istruzioni condizionali servono ad eseguire una porzione oppure un’altra sulla base del valore di una condizione Condizione espressione a valori booleani Due istruzioni (in tutti i linguaggi) IF-THEN-ELSE IF-THEN G. Mecca - Programmazione Procedurale in Linguaggio C++ 4 Strutture di Controllo: Conclusioni >> Ricapitolazione Ricapitolazione Istruzioni iterative servono ad eseguire più volte una porzione di programma sulla base del valore di una condizione Due istruzioni (in tutti i linguaggi) WHILE (cicli “aperti” oppure cicli “chiusi”) FOR (cicli “chiusi” o a conteggio) G. Mecca - Programmazione Procedurale in Linguaggio C++ 5 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile In questo corso (e nei successivi) convenzioni sullo “stile di scrittura” del codice Obiettivi uniformare il modo di scrivere il codice per renderlo più leggibile e per favorire la collaborazione nei gruppi di lavoro Tendenza internazionale G. Mecca - Programmazione Procedurale in Linguaggio C++ 6 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile Nelle lezioni successive raffineremo progressivamente le nostre regole in modo che valgano anche dopo (Java, C#) Per ora a) regole sull’indentazione del codice: 4 spazi b) regole sulle parentesi graffe c) regole sulle espressioni: spazi tra op.di e operatori d) regole sui nomi di variabili: notazione “cammello” G. Mecca - Programmazione Procedurale in Linguaggio C++ 7 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile a) Indentazione codice di un programma: insieme di blocchi nidificati (es: strutture di controllo) Per rendere più leggibile il codice è necessario dentellarlo (o “indentarlo”) le istruzioni di ogni blocco sono rientrate rispetto alle parentesi molto importante Regola: rientri di 4 spazi G. Mecca - Programmazione Procedurale in Linguaggio C++ 8 Strutture di Controllo: Conclusioni >> Convenzioni di Stile 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; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 9 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile b) Posizione delle parentesi graffe due convezioni principali Convenzione n.1 if (condizione) { <istruzioni>; } if (condizione) { <istruzioni>; } else { <istruzioni>; } Convenzione n.2 if (condizione) { <istruzioni>; } else { <istruzioni>; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 10 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile Regola n.1 adotteremo la convenzione n.1 Regola n.2 utilizzeremo sempre le parentesi anche nel caso in cui un blocco contenga un’unica istruzione G. Mecca - Programmazione Procedurale in Linguaggio C++ 11 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile c) Scrittura delle espressioni espressione: fatta di operandi ed operatori per renderla più leggibile è possibile inserire spazi tra operandi ed operatori Esempio (sqrt(x)+(y-z))==k (sqrt(x) + (y - z)) == k G. Mecca - Programmazione Procedurale in Linguaggio C++ 12 Strutture di Controllo: Conclusioni >> Convenzioni di Stile Convenzioni di Stile d) Nomi delle variabili identificatori regola n.1: inziale minuscola (es: voto, continua) regola n.2: convenzione “cammello” Convenzione cammello identificatore fatto di più parole concatenate ogni iniziale a parte la prima è maiuscola es: sommaVoti, numeroEsami G. Mecca - Programmazione Procedurale in Linguaggio C++ 13 Strutture di Controllo: Conclusioni >> Convenzioni di Stile #include <iostream.h> a) rientri di 4 spazi void main() { float voto, sommaVoti, media; NO più istruzioni per linea int numeroEsami; bool continua; b) posizione delle parentesi continua = true; numeroEsami = 0; NO convenzione n. 2 sommaVoti = 0.0; + parentesi sempre while (continua == true) { cout << "Immetti il voto (0 per fermarti)" << endl; cin >> voto; if (voto == 0) { c) espressioni continua = false; NO (continua==true) } else { numeroEsami++; sommaVoti += voto; d) nomi delle variabili } NO numeroesami } NO somma_voti if (numeroEsami > 0) { media = sommaVoti/numeroEsami; cout << "La media vale: " << media << endl; } else { cout << "Non hai fornito nessun voto" << endl; } } G. Mecca - Programmazione Procedurale in Linguaggio C++ 14 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Alcune Tecniche Notevoli Il nostro esempio n programma per il calcolo della media degli esami Due versioni l’utente inserisce preliminarmente il numero di esami sostenuti, e poi tutti i voti (versione con for) >> ciclo chiuso l’utente inserisce i voti uno per uno e si ferma digitando 0 (versione con while) >> ciclo aperto G. Mecca - Programmazione Procedurale in Linguaggio C++ 15 Strutture di Controllo: Conclusioni >> Ricapitolazione Un Esempio: Media con For #include <iostream.h> void main() { float voto, sommaVoti, media; int numeroEsami, i; cout << "Quanti esami hai sostenuto ?" << cin >> numeroEsami; sommaVoti = 0.0; for (i=0; i<numeroEsami; i++) { cout << "Immetti il voto di un esame" cin >> voto; sommaVoti += voto; } if (numeroEsami > 0) { media = sommaVoti/numeroEsami; cout << "La media vale: " << media << } else cout << "Non hai fornito nessun voto" } G. Mecca - Programmazione Procedurale in Linguaggio C++ endl; << endl; endl; << endl; 16 Strutture di Controllo: Conclusioni >> Ricapitolazione Un Esempio: Media con While #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; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 17 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Calcolo della Media Una annotazione le variabili voto e sommaVoti avrebbero potuto essere di tipo int ma questo avrebbe portato ad un valore scorretto della media (divisione intera) int sommaVoti, numeroEsami; float media; media = sommaVoti/numeroEsami; es: se sommaVoti vale 64 e numeroEsami vale 3, media vale 21 e non 21.3333 G. Mecca - Programmazione Procedurale in Linguaggio C++ 18 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Alcune Tecniche Notevoli Tecniche notevoli contenute nei progr. somma dei voti (somma con variabile “accumulatore”) conteggio del numero di esami (conteggio con variabile “contatore”) tecnica per fermare il ciclo while (variabile “bandiera”) Inoltre, vedremo anche convalida dei dati forniti dall’utente G. Mecca - Programmazione Procedurale in Linguaggio C++ 19 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Somma con Accumulatore 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) Tecnica notevole utilizzabile tutte le volte che bisogna sommare un insieme di valori G. Mecca - Programmazione Procedurale in Linguaggio C++ 20 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Accumulatore 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Memoria RAM #2500 numeroEsami xxx 3 #2501 sommaVoti xxx 67.0 21.0 0.0 43.0 float voto, sommaVoti; #2502 i xxx 013 2 int numeroEsami, i; #2503 voto xxx 21 22 24 cout << "Quanti esami ? “; cin >> numeroEsami; Schermo sommaVoti = 0.0; for (i = 0; i < numeroEsami; i++) { Quanti esami ? 3 cout << “Voto ? "; Voto ? 21 cin >> voto; Voto ? 22 sommaVoti = sommaVoti + voto; Voto ? 24 } G. Mecca - Programmazione Procedurale in Linguaggio C++ 21 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Somma con Accumulatore E’ usata anche nella versione basata su while 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 G. Mecca - Programmazione Procedurale in Linguaggio C++ 22 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Variabile Contatore 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 Anche questa è una tecnica notevole contare gli elementi di un insieme G. Mecca - Programmazione Procedurale in Linguaggio C++ 23 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Un Esempio: Media con While #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; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 24 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Variabile Contatore Attenzione abbiamo già visto questa tecnica 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) G. Mecca - Programmazione Procedurale in Linguaggio C++ 25 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Un Esempio Già Visto: I 5 Quadrati ATTENZIONE: #include <iostream.h> nel caso della media void main() { non conto il numero di float lato, area; esecuzioni del ciclo, ma int i; il numero di voti forniti 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”; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 26 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Variabile Bandiera (“Flag”) 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) Tecnica notevole per il controllo di cicli G. Mecca - Programmazione Procedurale in Linguaggio C++ 27 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Un Esempio: Media con While #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; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 28 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Variabile Bandiera (“Flag”) Una annotazione la condizione del ciclo while avrebbe potuto essere scritta anche come while (continua) {...} infatti, le due espressioni, (continua) (continua==true) espressione fatta da un’unico operando e nessun operatore sono equivalenti (vere se “continua” vale true, false se continua vale false”) G. Mecca - Programmazione Procedurale in Linguaggio C++ 29 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Variabile Bandiera (“Flag”) 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) vera se b vale false falsa se b vale true G. Mecca - Programmazione Procedurale in Linguaggio C++ 30 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Accumulatore 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. continua = true; numeroEsami = 0; sommaVoti = 0.0; while (continua == true) { cout << “Voto? (0 stop)“; cin >> voto; if (voto == 0) { continua = false; } else { numeroEsami++; sommaVoti += voto; } } ... Memoria RAM #2500 numeroEsami xxx 012 #2501 sommaVoti xxx 21.0 0.0 43.0 #2502 continua xxx true false #2503 voto xxx 21 22 0 G. Mecca - Programmazione Procedurale in Linguaggio C++ Schermo Voto? (0 stop) 21 Voto? (0 stop) 22 Voto? (0 stop) 0 31 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Convalida dell’Input mediaForConvalida.cpp >> mediaWhileConvalida.cpp >> 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 Convalida dei valori in ingresso è possibile utilizzare un ciclo while G. Mecca - Programmazione Procedurale in Linguaggio C++ 32 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Convalida dell’Input 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 G. Mecca - Programmazione Procedurale in Linguaggio C++ 33 Strutture di Controllo: Conclusioni >> Alcune Tecniche Notevoli Convalida dell’Input Una soluzione alternativa: cout << “Esami ?" << endl; cin >> numeroEsami; bool continua; continua = true; while (numeroEsami < 0) { cout << “Errore“ << endl; cout << “Esami ?" << endl; cin >> numeroEsami; } while (continua) { cout << “Esami ?" << endl; cin >> numeroEsami; if (numeroEsami < 0) { cout << "Errore“; } else { continua = false; } } Svantaggi di questa soluzione: - il codice è meno compatto - è molto meno leggibile Utilizzeremo la seconda G. Mecca - Programmazione Procedurale in Linguaggio C++ 34 Strutture di Controllo: Conclusioni >> Errori Frequenti Errori Frequenti Un errore sintattico frequente parentesi graffe mancanti per i blocchi delle istruzioni di controllo Due casi entrambe le parentesi mancanti solo la parentesi finale è mancante G. Mecca - Programmazione Procedurale in Linguaggio C++ 35 Strutture di Controllo: Conclusioni >> Errori Frequenti Un Esempio: Media con For #include <iostream.h> manca la parentesi di chiusura void main() { mancano le parentesi float voto, sommaVoti, media; del I blocco int numeroEsami, i; cout << "Quanti esami hai sostenuto ?" << endl; cin >> numeroEsami; sommaVoti = 0.0; for (i=0; i<numeroEsami; i++) { cout << "Immetti il voto di un esame" << endl; cin >> voto; sommaVoti += voto; if (numeroEsami > 0) media = sommaVoti/numeroEsami; cout << "La media vale: " << media << endl; else { cout << "Non hai fornito nessun voto" << endl; } } G. Mecca - Programmazione Procedurale in Linguaggio C++ 36 Strutture di Controllo: Conclusioni >> Errori Frequenti Errori Frequenti 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” 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” G. Mecca - Programmazione Procedurale in Linguaggio C++ 37 Strutture di Controllo: Conclusioni >> Errori Frequenti Errori Frequenti Un errore logico frequente nei cicli aperti, gestione scorretta della variabile di ciclo mancanza dell’inizializzazione mancanza dell’incremento In questi casi il ciclo si comporta in modo scorretto nel secondo caso si verifica un loop G. Mecca - Programmazione Procedurale in Linguaggio C++ 38 Strutture di Controllo: Conclusioni >> Errori Frequenti Errori Frequenti Manca inizializzazione il comportamento è casuale dipende dal valore di i int i; while (i < 5) { cout << “Valore di i: “; cout << i << endl; i++; } 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 Strutture di Controllo: Conclusioni >> Sommario Riassumendo Ricapitolazione Convenzioni di Stile (ATTENZIONE) Alcune Tecniche Notevoli Somma con Accumulatore Conteggio con Contatore Variabili Bandiera (“flag”) Convalida dei Dati in Ingresso Errori Frequenti G. Mecca - Programmazione Procedurale in Linguaggio C++ 40 Strutture di Controllo: Conclusioni >> Un Esempio Un Esempio: Media con For #include <iostream.h> void main() { float voto, sommaVoti, media; int numeroEsami, i; cout << "Quanti esami hai sostenuto ?" << cin >> numeroEsami; sommaVoti = 0.0; for (i=0; i<numeroEsami; i++) { cout << "Immetti il voto di un esame" cin >> voto; sommaVoti += voto; } if (numeroEsami > 0) { media = sommaVoti/numeroEsami; cout << "La media vale: " << media << } else cout << "Non hai fornito nessun voto" } G. Mecca - Programmazione Procedurale in Linguaggio C++ endl; << endl; endl; << endl; 41 Strutture di Controllo: Conclusioni >> Un Esempio Un Esempio: Media con While #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; } G. Mecca - Programmazione Procedurale in Linguaggio C++ 42 Termini della Licenza Termini della Licenza This work is licensed under the Creative Commons AttributionShareAlike 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. 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. G. Mecca - Programmazione Procedurale in Linguaggio C++ 43