1 / 53

Come scrivere bene codice?

Come scrivere bene codice?. Prima di iniziare a scrivere un programma: Acquisire profonda comprensione del problema Progettare approccio per la risoluzione del problema Quando si scrive un programma è importante: Sapere quali “building blocks” sono disponibili

carnig
Download Presentation

Come scrivere bene codice?

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Come scrivere bene codice? • Prima di iniziare a scrivere un programma: • Acquisire profonda comprensione del problema • Progettare approccio per la risoluzione del problema • Quando si scrive un programma è importante: • Sapere quali “building blocks” sono disponibili • Usare tecniche di buona programmazione

  2. Algoritmi Tutti i problemi di calcolo possono essere risolti eseguendo una serie di azioni primitive in un ordine specifico • Algoritmo • Procedura che determina: • azioni che devono essere eseguite • ordine in cui eseguire queste azioni • Strutture di Controllo • Specifica l’ordine in cui sono eseguiti statements

  3. Pseudocodice • Linguaggio informale per esprimere algoritmi • Simile (in qualche modo) al linguaggio naturale • Non è eseguibile su computer • “Pensare” come risolvere i problemi prima di scrivere codice! • Facile convertire pseudocodice nel programma C++ corrispondente

  4. Strutture di Controllo • Esecuzione sequenziale • Statement eseguiti uno dopo l’altro nell’ordine scritto • Trasferimento di controllo • Statement da eseguire non è quello in sequenza • Teorema di Böhm-Jacopini Tutti i programmi possono essere scritti usando solo tre strutture di controllo: • Sequenziale • Built in. Programmi eseguiti sequenzialmente per default. • Selezione • C++ ha tre tipi - if, if/else, e switch • Ciclo • C++ ha tre tipi - while, do/while, e for

  5. true product <= 1000 product = 2 * product false Diagrammi di flusso Rappresentazione grafica di un algoritmo

  6. Diagrammi di flusso Ottenuti usando simboli speciali connessi da frecce (flowlines): • Rettangolo (simbolo di azione) • indica ogni tipo di azione. • Ovale (inizio/fine) • indica inizio/fine di programma o di sezione di codice. • Struttura di controllo (single-entry/single-exit) • Connette punto di uscita di una struttura di controllo con punto di ingresso della successiva (control-structure stacking). • Rende programmi facili da costruire.

  7. Struttura Selezione(if) • Scegliere tra varie alternative • Esempio pseudocodice : If voto studente >= 60 Stampa “Promosso” • Se la condizione è true • Viene eseguito statement Stampa “Promosso” e programma continua con statement successivo • Se la condizione è false • statement Stampa “Promosso” viene ignorato e programma continua con statement successivo • Indentazione rende programmi più leggibili • C++ ignora blank

  8. Istruzione if • Tradurre pseudocodice in C++: if ( grade >= 60 ) cout << "Passed"; • Rombo (decisione) • indica che bisogna prendere una decisione • Contiene un espressione che può essere true o false. • Testa la condizione, segui percorso appropriato • if single-entry/single-exit

  9. Decisione può essere presa su ogni espressione. zero - false nonzero - true Esempio: 3 - 4 ètrue true false print “Passed” grade >= 60 Selezione if • Diagramma di flusso dello pseudocodice

  10. Selezioneif/else • if • Esegue un’azione solo se la condizione è verificata • if/else • Si esegue un’azione diversa a seconda che la condizione sia verificata o meno • Pseudocodice if student’s grade is greater than or equal to 60print “Passed” else print “Failed” • Codice C++ if ( grade >= 60 ) cout << "Passed";else cout << "Failed";

  11. false true print “Passed” print “Failed” grade >= 60 Selezioneif/else • Operatore ternario condizionale (?:) • Ha tre argomenti (condizione, valore se true, valore se false) • Pseudocodice potrebbe essere codificato come: cout << ( grade >= 60 ? “Passed” : “Failed” );

  12. Selezione if/else • Strutture if/else innestate: • Testare casi multipli con strutture di selezione if/else dentro altre strutture di selezione if/else. if student’s grade is greater than or equal to 90 Print “A”elseif student’s grade is greater than or equal to 80 Print “B”elseif student’s grade is greater than or equal to 70 Print “C”elseif student’s grade is greater than or equal to 60 Print “D”else Print “F” • Quando una condizione è verificata, si salta il resto delle istruzioni

  13. Selezione if/else • Statement composto: • Insieme di statement all’interno di una coppia di { } • Esempio: if ( grade >= 60 ) cout << "Passed.\n"; else { cout << "Failed.\n"; cout << "You must take this course again.\n";} • Senza { }, si eseguirebbe sempre cout << "You must take this course again.\n"; • Blocco • Statement composti con dichiarazioni

  14. Selezione if/else • Errori di sintassi • Segnalati dal compilatore • Esempio: if ( x == 0 ) y = 0; esle y = 1; • Errori logici • Errori che si presentano in esecuzione • Errori logici “non fatali” • programma va in esecuzione ma produce output non corretto • Esempio: if ( x = 0 ) y = 0; • Errori logici “fatali” • programma finisce prematuramente • Esempio: x = 0; y = y/x;

  15. Ciclo while • Strutture di ciclo • Si vuole specificare un azione che deve essere ripetuta fintantoché una determinata condizione è verificata • Pseudocodice while there are more items on my shopping list Purchase next item and cross it off my list • Ciclo while ripetuto fino a che la condizione non diventa falsa. • Esempio int product = 2; while ( product <= 1000 ) product = 2 * product;

  16. true product <= 1000 product = 2 * product false Ciclo while • Diagramma di flusso del ciclo while

  17. Cicli controllati da un contatore • Ciclo ripetuto finché contatore raggiunge un determinato valore • Numero di ripetizioni noto • Esempio Una classe di 280 studenti sostiene un esame. Dati i voti (interi nell’intervallo [0,100]), determinare la media della classe.

  18. Cicli controllati da un contatore • Pseudocodice per l’esempio: Set total to zero Set grade counter to one While grade counter is less than or equal to 280 Input the next grade Add the grade into the total Add one to the grade counter Set the class average to the total divided by 280 Print the class average • Partendo da questo pseudocodice non è difficile scrivere codice C++…

  19. 1 // Fig. 2.7: fig02_07.cpp 2 // Class average program with counter-controlled repetition 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; Il contatore viene incrementato ogni volta che si esegue un’iterazione del ciclo. Alla fine, il valore del contatore determina l’uscita dal ciclo. 8 9 int main() 10 { 11 int total, // sum of grades 12 gradeCounter, // number of grades entered 13 grade, // one grade 14 average; // average of grades 15 16 // initialization phase 17 total = 0; // clear total 18 gradeCounter = 1; // prepare to loop 19 20 // processing phase 21 while ( gradeCounter <= 10 ) { // loop 10 times 22 cout << "Enter grade: "; // prompt for input 23 cin >> grade; // input grade 24 total = total + grade; // add grade to total 25 gradeCounter = gradeCounter + 1; // increment counter 26 } 27 28 // termination phase 29 average = total / 10; // integer division 30 cout << "Class average is " << average << endl; 31 32 return 0; // indicate program ended successfully 33 } 1. Initialize Variables 2. Execute Loop 3. Output results

  20. Enter grade: 98 Enter grade: 76 Enter grade: 71 Enter grade: 87 Enter grade: 83 Enter grade: 90 Enter grade: 57 Enter grade: 79 Enter grade: 82 Enter grade: 94 Class average is 81 Program Output

  21. Tecnica di progettazione top-down(Ciclo controllato da sentinella) • Supponiamo che il problema sia: Scrivere un programma che esegua la media di un numero arbitrario (non noto a priori) di voti. • Numero arbitrario di studenti • Come sappiamo che dobbiamo fermarci? • Valore “sentinella” • Indica “fine dei dati in ingresso” • Ciclo deve terminare quando viene immessa la sentinella • Valore della sentinella scelto in modo tale da non essere confuso con input regolare (come ad esempio -1 per questo problema)

  22. Tecnica di progettazione top-down(Ciclo controllato da sentinella) • Raffinamento per passi successivi, in modo Top-down (divide et impera): • Comincia con pseudocodice ad alto livello: Determine the class average for the quiz • Dividi in sottoproblemi più piccoli: Initialize variables Input, sum and count the quiz grades Calculate and print the class average

  23. Raffinamenti successivi, Top-down • Molti programmi possono essere divisi in tre fasi: • Inizializzazione • Inizializza le variabili del programma • Processing • Leggi dati in ingresso e modifica variabili di programma. • Chiusura • Calcola e stampa risultati finali. • Ci aiuta nella definizione di raffinamenti top-down. • Raffiniamo fase di inizializzazione da Initialize variables a Initialize total to zero Initialize counter to zero

  24. Raffinamenti successivi, Top-down • Raffiniamo Input, sum and count the quiz grades a Input the first grade (possibly the sentinel) While the user has not yet entered the sentinel Add this grade into the running total Add one to the grade counter Input the next grade (possibly the sentinel) • Raffiniamo Calculate and print the class average a If counter not equal to zero Set the average to the total divided by the counter Print the average Else Print “No grades were entered”

  25. 1 // Fig. 2.9: fig02_09.cpp 2 // Class average program with sentinel-controlled repetition. Tipo di dato double usato per rappresentare numeri decimali. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 using std::ios; 9 10 #include <iomanip> 11 12 using std::setprecision; 13 using std::setiosflags; 14 15 int main() 16 { 17 int total, // sum of grades 18 gradeCounter, // number of grades entered 19 grade; // one grade 20 double average; // number with decimal point for average 21 22 // initialization phase 23 total = 0; 24 gradeCounter = 0; 25 26 // processing phase 27 cout << "Enter grade, -1 to end: "; 28 cin >> grade; 29 1. Initialize Variables 2. Get user input 2.1 Perform Loop

  26. 31 total = total + grade; static_cast<double>() - tratta total come un double (temporaneamente). Necessario perché la divisione tra due interi restituisce un intero (tronca il resto). gradeCounter è int, ma viene promosso a double. 32 gradeCounter = gradeCounter + 1; 33 cout << "Enter grade, -1 to end: "; 34 cin >> grade; 35 } setiosflags(ios::fixed | ios::showpoint)– manipolatore di stream | - separata opzioni multiple. ios::fixed - stampa valori in virgola fissa. ios::showpoint - forza la virgola (con zero eventuali) anche quando non necessario : 66 stampato 66.00 36 37 // termination phase 30 while ( grade != -1 ) { 38 if ( gradeCounter != 0 ) { setprecision(2)– stampa solo due cifre decimali dopo la virgola. Programmi che lo usano devono includere <iomanip> 39 average = static_cast< double >( total ) / gradeCounter; 40 cout << "Class average is " << setprecision( 2 ) 41 << setiosflags( ios::fixed | ios::showpoint ) 42 << average << endl; 43 } 44 else 45 cout << "No grades were entered" << endl; 46 47 return 0; // indicate program ended successfully 48 } 3. Calculate Average 3.1 Print Results Program Output Enter grade, -1 to end: 75 Enter grade, -1 to end: 94 Enter grade, -1 to end: 97 Enter grade, -1 to end: 88 Enter grade, -1 to end: 70 Enter grade, -1 to end: 64 Enter grade, -1 to end: 83 Enter grade, -1 to end: 89 Enter grade, -1 to end: -1 Class average is 82.50

  27. Esempio su strutture di controllo innestate • Problema: Un docente ha lista risultati esame (1 = pass, 2 = fail) per 10 studenti. Scrivere un programma che analizza i risultati. Se più di 8 studenti sono stati promossi, stampa “Hanno copiato?". • Programma deve processare 10 test. Usare ciclo controllato da contatore. • Si possono usare due contatori —uno per contare il numero di studenti promossi, l’altro per contare il numero di studenti bocciati. • Ogni risultato di test è 1 o 2. Se il numero non è 1, assumiamo che sia un 2. • Top level outline: Analyze exam results and decide if possible cheating

  28. Strutture di controllo innestate • Primo raffinamento: Initialize variables Input the ten quiz grades and count passes and failures Print a summary of the exam results and decide if possibly cheating • Raffinamenti successivi Initialize variables in Initialize passes to zero Initialize failures to zero Initialize student counter to one

  29. Strutture di controllo innestate • Raffinamenti successivi Input the ten quiz grades and count passes and failures in While student counter is less than or equal to tenInput the next exam result If the student passed Add one to passesElse Add one to failures Add one to student counter • Raffinamenti successivi Print a summary of the exam results and decide if tests should be tougher in Print the number of passes Print the number of failures If more than eight students passed Print “Hanno copiato?”

  30. 1 // Fig. 2.11: fig02_11.cpp 2 // Analysis of examination results 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 int main() 10 { 11 // initialize variables in declarations 12 int passes = 0, // number of passes 13 failures = 0, // number of failures 14 studentCounter = 1, // student counter 15 result; // one exam result 16 17 // process 10 students; counter-controlled loop 18 while ( studentCounter <= 10 ) { 19 cout << "Enter result (1=pass,2=fail): "; 20 cin >> result; 21 22 if ( result == 1 ) // if/else nested in while 23 passes = passes + 1; 1. Initialize variables 2. Input data and count passes/failures

  31. 24 else 25 failures = failures + 1; 26 27 studentCounter = studentCounter + 1; 28 } 29 30 // termination phase 31 cout << “Promossi " << passes << endl; 32 cout << “Bocciati " << failures << endl; 33 34 if ( passes > 8 ) 35 cout << “Hanno copiato?" << endl; 36 37 return 0; // successful termination 38 } 3. Print results Program Output Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 2 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Enter result (1=pass,2=fail): 1 Promossi 9 Bocciati 1 Hanno copiato?

  32. Operatori di Assegnazione • Abbreviazioni per espressioni di assegnazione c = c + 3; può essere abbreviato come c += 3; (operatore di assegnazione/addizione) • Statement della forma variable = variable <operator> expression; Possono essere riscritti come variable <operator>= expression; • Esempi di altri operatori di assegnazione includono: d -= 4 (d = d - 4) e *= 5 (e = e * 5) f /= 3 (f = f / 3) g %= 9 (g = g % 9)

  33. Operatori di Incremento e Decremento • Incremento (++) può essere usato al posto di c += 1 • Decremento (--) può essere usato al posto di c -= 1 • Preincremento (predecremento) • Operatore usato prima della variabile (++c o –-c) • Prima modificata variabile, poi valutata espressione contenente variabile. • Postincremento (postdecremento) • Operatore usato dopo la variabile (c++ or c--) • Prima valutata espressione contenente variabile, poi modificata variabile. • Esempio: supponiamo c = 5 • cout << ++c; stampa 6 (c modificata prima di esecuzione di cout) • cout << c++; stampa 5 (cout eseguita prima di incremento. Alla fine c vale 6)

  34. Operatori di Incremento e Decremento • Se la variabile non è in una espressione • Preincremento e postincremento hanno esattamente lo stesso effetto • Esempio (c=5) ++c; cout << c; e c++; cout << c; Stampano sempre 6.

  35. Cicli controllati da un contatore • Richiedono: • Variabile di controllo (contatore di ciclo). • Valore iniziale di variabile di controllo. • Condizione che testa valore finale di variabile di controllo (i.e., se ciclo deve continuare). • Incremento (o decremento) con cui viene aggiornata la variabile di controllo ad ogni iterazione del ciclo. • Esempio: int counter = 1; //initialization while (counter <= 10){ //repetition condition cout << counter << endl; ++counter; //(pre)increment }

  36. Cicli controllati da un contatore • La dichiarazione int counter = 1; • Definisce una variabile di nome counter • Dichiara counter di tipo integer • Fa riservare spazio per counter in memoria • Inizializza counter ad 1

  37. No ; dopo ultimo statement! Ciclo for • Formato generale di ciclo for è for ( initialization; LoopContinuationTest; increment ) statement; • Esempio: for( int counter = 1; counter <= 10; counter++ ) cout << counter << endl; Stampa gli interi da 1 a 10

  38. Ciclo for • Cicli for possono essere riscritti come cicli while: for ( initialization; LoopContinuationTest; increment ) statement; diventa initialization; while ( loopContinuationTest ){ statement; increment; } • Inizializzazione e incremento possono essere liste (separate da virgole): for (int i = 0, j = 0; j + i <= 10;j++, i++) cout << j + i << endl;

  39. 1 // Fig. 2.20: fig02_20.cpp 2 // Summation with for 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int main() 9 { 10 int sum = 0; 11 12 for ( int number = 2; number <= 100; number += 2 ) 13 sum += number; 14 15 cout << "Sum is " << sum << endl; 16 17 return 0; 18 } Esempi con il ciclo for • Programma per sommare numeri pari da 2 to 100 Sum is 2550

  40. true false true false . . . true false case a action(s) case z action(s) case b action(s) break break break default action(s) case b case a case z Struttura switch per selezione multipla • switch • Utile quando si vuole testare variabile o espressione per valori multipli • Serie di case e default opzionale

  41. 1 // Fig. 2.22: fig02_22.cpp 2 // Counting letter grades cin.get() legge un carattere Gestione EOF dipende dal sistema (inserimento ctrl+z, valore -1) switch opera su costanti carattere e intere Lo spazioè necessario 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 int main() 10 { 11 int grade, // one grade 12 aCount = 0, // number of A's 13 bCount = 0, // number of B's 14 cCount = 0, // number of C's 15 dCount = 0, // number of D's 16 fCount = 0; // number of F's 17 18 cout << "Enter the letter grades." << endl 19 << "Enter the EOF character to end input." << endl; 20 21 while ( ( grade = cin.get() ) != EOF ) { 22 23 switch ( grade ) { // switch nested in while 24 25 case 'A': // grade was uppercase A 26 case 'a': // or lowercase a 27 ++aCount; 28 break; // necessary to exit switch 29 30 case 'B': // grade was uppercase B 31 case 'b': // or lowercase b 32 ++bCount; 33 break; 34 1. Initialize variables 2. Input data 2.1 Use switch loop to update count

  42. 35 case 'C': // grade was uppercase C 36 case 'c': // or lowercase c 37 ++cCount; breakinterrompe loswitchprogramma continua con primo statement dopo la strutturaswitch. 38 break; 39 40 case 'D': // grade was uppercase D Nota lo statement default. 41 case 'd': // or lowercase d 42 ++dCount; 43 break; 44 45 case 'F': // grade was uppercase F 46 case 'f': // or lowercase f 47 ++fCount; 48 break; 49 50 case '\n': // ignore newlines, 51 case '\t': // tabs, 52 case ' ': // and spaces in input 53 break; 54 55 default: // catch all other characters 56 cout << "Incorrect letter grade entered." 57 << " Enter a new grade." << endl; 58 break; // optional 59 } 60 } 61 62 cout << "\n\nTotals for each letter grade are:" 63 << "\nA: " << aCount 64 << "\nB: " << bCount 65 << "\nC: " << cCount 66 << "\nD: " << dCount 67 << "\nF: " << fCount << endl; 68 69 return 0; 70 } 2.1 Use switch loop to update count 3. Print results

  43. Enter the letter grades. Enter the EOF character to end input. a B c C A d f C E Incorrect letter grade entered. Enter a new grade. D A b Totals for each letter grade are: A: 3 B: 2 C: 3 D: 2 F: 1 Program Output

  44. true false action(s) condition Ciclo do/while • Ciclo do/while simile al while • Differenza: condizione di permanenza nel ciclo testata dopo l’esecuzione del corpo del ciclo • Formato: do { statement; } while ( condition ); • Esempio (prima counter = 1): do { cout << counter << " "; } while (++counter <= 10); • Stampa gli interi da 1 a 10 • Tutte le azioni all’interno del ciclo vengono eseguite almeno una volta.

  45. Statement break • Break • Causa uscita immediata da strutture while, for, do/while o switch • L’esecuzione del programma continua con il primo statement dopo la struttura • Uso comune di break: • Uscire prematuramente da un ciclo • Saltare parte rimanente di una struttura switch

  46. Statementcontinue • Continue • Salta la parte rimanente nel corpo di strutture while, for o do/while e procedi con l’iterazione successiva del ciclo • Nel while e do/while, immediatamente dopo il continue viene eseguita la condizione di permanenza nel ciclo • Nel for, viene eseguita l’espressione incremento, e quindi testata la condizione di permanenza nel ciclo

  47. Operatori Logici • && (logical AND) • Restituisce true se entrambe le condizioni sono true • || (logical OR) • Restituisce true se una delle condizioni è true • ! (logical NOT, logical negation) • Complementa verità/falsità della condizione • Restituisce true quando la condizione è false • E’ un operatore unario: agisce su una sola condizione • Operatori logici usati come condizioni nei cicli Espressione Risultato true && false falsetrue || false true!false true • Esempio:if ((voto == 18) && (!(copiato)))

  48. Non confonderegli operatori Equality (==) e Assignment (=) !!!! • Errori disastrosi perché normalmente non causano errori sintattici. • Ricorda che ogni espressione che produce un valore può essere usata nelle strutture di controllo. Valori diversi da zero equivalgono a true, e valori zero a false • Esempio: if ( grade == 5 ) cout << "Sei bocciato" << endl; • Controlla voto, se è 5 allora sei bocciato • Se per errore si scrive = al posto di == if ( grade = 5 ) cout << "Sei bocciato" << endl; • Assegna 5 agrade • 5 è diverso da zero, quindi l’espressione viene valutata a true esi viene bocciati, indipendentemente da grade…

  49. Non confonderegli operatori Equality (==) e Assignment (=) • Lvalues • Espressioni che possono apparire sul lato sinistro di una equazione • I loro valori possono essere modificati • Nomi di variabili sono un esempio comune (e.g., x = 4;) • Rvalues • Espressioni che possono apparire solo sul lato destro di un’equazione • Costanti, come i numeri (i.e. non si può scrivere 4 = x;) • Lvalues possono essere usati come rvalues, ma non viceversa!

  50. Sommario su Programmazione Strutturata • Programmazione Strutturata • Tecnica che rende i programmi più facili da capire, testare, debuggare e modificare. • Regole per la Programmazione Strutturata • Usare soltanto strutture di controllo single-entry/single-exit • Regole: 1) Comincia col “diagramma di flusso più semplice”. 2) Ogni rettangolo (azione) può essere rimpiazzato da due rettangoli (azioni) in sequenza. 3) Ogni rettangolo (azione) può essere rimpiazzato da ogni struttura di controllo (sequenza, if, if/else, switch, while, do/while o for). 4) Le regole 2 e 3 possono essere applicate in ogni ordine e più volte.

More Related