appunti3s:programmazione_strutturata
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
appunti3s:programmazione_strutturata [2019/11/11 17:39] – [Struttura iterativa precondizionale] correzione codice profpro | appunti3s:programmazione_strutturata [2020/06/08 22:19] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Programmazione strutturata ====== | ||
+ | ===== Introduzione ===== | ||
+ | |||
+ | Quando si affronta la programmazione si devono indicare al computer delle istruzioni da eseguire. | ||
+ | Se il computer potesse comprendere il linguaggio naturale, sarebbe facile chiedere: | ||
+ | * di eseguire un' | ||
+ | * di eseguire un' | ||
+ | * di eseguire una // | ||
+ | |||
+ | Si tratta di istruzioni per noi molto semplici da comprendere, | ||
+ | Ognuna delle precedenti istruzioni è un esempio di: una condizione, un' | ||
+ | |||
+ | =====Teorema Böhm-Jacopini===== | ||
+ | Questo teorema afferma che qualsiasi // | ||
+ | |||
+ | Gli esempi appena visti erano proprio di queste strutture: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | I programmi che seguiranno sono privi di altre funzioni oltre al main() per mettere in evidenza solo queste tre strutture. Al loro fianco sarà presente un diagramma di flusso che usa gli stessi colori per mettere in evidenza le tre strutture. | ||
+ | |||
+ | Le tre strutture possono anche essere combinate insieme tra di loro: si può inserire una struttura sequenziale all' | ||
+ | {{ : | ||
+ | ===== Traduzione in C++ ===== | ||
+ | |||
+ | Poiché queste tre strutture sono indispensabili per descrivere gli algoritmi, ogni linguaggio di programmazione consente di tradurle come istruzioni. Nei prossimi esempi si vedrà che | ||
+ | * La struttura sequenziale si traduce in C++ usando una coppia di parentesi graffe | ||
+ | < | ||
+ | { | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * La struttura condizionale si traduce in C++ usando un' | ||
+ | < | ||
+ | if ( ... ) | ||
+ | ... | ||
+ | else ... | ||
+ | </ | ||
+ | |||
+ | * La struttura iterativa // | ||
+ | * < | ||
+ | ... | ||
+ | </ | ||
+ | * < | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | =====Struttura sequenziale===== | ||
+ | Un programma può eseguire una lista sequenziale di istruzioni{{ : | ||
+ | * //Esempio che calcola l'area di un cerchio// | ||
+ | * chiedere in input un valore per il raggio | ||
+ | * calcola l'area di un cerchio (formula...) | ||
+ | * visualizzare in output l'area | ||
+ | |||
+ | ^ var. di input ^ tipo ^ var. di output ^ tipo ^ var. di lavoro ^ tipo ^ | ||
+ | | raggio | num. virgola | area | num. virgola | area | num. virgola | | ||
+ | |||
+ | >> La struttura sequenziale si traduce in C++ usando una coppia di parentesi graffe | ||
+ | < | ||
+ | { | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | <file cpp 31.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | std::cout << " | ||
+ | float raggio; | ||
+ | std::cin >> raggio; | ||
+ | float area = raggio*raggio*3.14; | ||
+ | std::cout << " | ||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | =====Struttura condizionale===== | ||
+ | Un programma può eseguire istruzioni diverse in base al verificarsi di una condizione | ||
+ | {{ : | ||
+ | * //Esempio che visualizza la maggiore età// | ||
+ | * chiedere in input il valore dell' | ||
+ | * calcolare l'età attuale | ||
+ | * se età < 18 | ||
+ | * allora visualizzare in output: sei minorenne | ||
+ | * altrimenti visualizzare in output: sei maggiorenne | ||
+ | |||
+ | ^ costanti ^ valore ^ var. di input ^ tipo ^ var. di output ^ tipo ^ var. di lavoro ^ tipo ^ | ||
+ | | annoAttuale | 2012 | annoNascita | intero | - | - | - | - | | ||
+ | |||
+ | >> La struttura condizionale si traduce in C++ indicando la condizione dentro il rombo dentro un' | ||
+ | < | ||
+ | if ( ... ) | ||
+ | ... | ||
+ | else ... | ||
+ | </ | ||
+ | |||
+ | |||
+ | <file cpp 32.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | const int annoAttuale=2012; | ||
+ | std::cout << "Per favore scrivi l'anno di nascita: "; | ||
+ | int annoNascita; | ||
+ | std::cin >> annoNascita; | ||
+ | | ||
+ | if ( annoAttuale-annoNascita < 18 ) | ||
+ | std::cout << " | ||
+ | else | ||
+ | std::cout << " | ||
+ | | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Che differenza c'è tra questi due esempi di istruzione //if//? Perché vengono entrambi compilati senza segnalare errore? | ||
+ | * < | ||
+ | * < | ||
+ | ====Operatori logici==== | ||
+ | L' | ||
+ | |||
+ | ATTENZIONE: non confondere in italiano il termine // | ||
+ | |||
+ | Esempio di proposizione (con valore tra parentesi): | ||
+ | * P = "il quadrato ha 4 lati" (vero) | ||
+ | * Q = "il tuo cane miagola" | ||
+ | |||
+ | In tale algebra esistono diversi operatori (detti operatori booleani oppure connettivi logici) che possono essere applicati ad una o più proposizioni. | ||
+ | * AND (detto congiunzione) | ||
+ | * OR (detto disgiunzione) | ||
+ | * NOT (detto negazione) | ||
+ | * altri meno famosi come: NAND, NOR, XOR,... | ||
+ | |||
+ | === Esempio di NOT === | ||
+ | |||
+ | Applicando l' | ||
+ | * NOT P = "il quadrato NON ha 4 lati" (falso) | ||
+ | * NOT Q = "il tuo cane NON miagola" | ||
+ | |||
+ | === Esempio di AND === | ||
+ | |||
+ | Applicando l' | ||
+ | * P AND Q = "il quadrato ha 4 lati" E "il tuo cane miagola" | ||
+ | |||
+ | === Esempio di OR === | ||
+ | |||
+ | Applicando l' | ||
+ | * P OR Q = "il quadrato ha 4 lati" OPPURE "il tuo cane miagola" | ||
+ | |||
+ | === La tabella di verità === | ||
+ | |||
+ | Per ogni operatore booleano (AND, OR, NOT, ecc.) si può costruire una tabella che aiuta a descriverlo. | ||
+ | Nella seguente tabella sono messe a confronto gli operatori AND e OR. Le prime due colonne sono due proposizioni su cui applicare tali operatori. | ||
+ | |||
+ | ^ P ^ Q ^P AND Q^P OR Q^ | ||
+ | | V | V | V | V | | ||
+ | | V | F | F | V | | ||
+ | | F | V | F | V | | ||
+ | | F | F | F | F | | ||
+ | |||
+ | La tabella di verità del NOT è più semplice: | ||
+ | |||
+ | ^ P ^ NOT P ^ | ||
+ | | V | F | | ||
+ | | F | V | | ||
+ | |||
+ | ===Il calcolo automatico=== | ||
+ | |||
+ | Dopo circa un secolo dalla sua ideazione, l' | ||
+ | Poiché l' | ||
+ | Più in generale, si può dire che qualsiasi valore diverso da 0 è considerato "// | ||
+ | |||
+ | Il programmatore può scrivere espressioni hanno un risultato numerico, come //x=33*4//; o espressioni che hanno un risultato " | ||
+ | |||
+ | Alle espressioni di confronto, come //a<b//, possono essere applicati i precedenti operatori logici. Il calcolo automatico di queste espressioni (come //a<b//) permette al programma di eseguire un' | ||
+ | |||
+ | Nelle istruzioni di scelta condizionata sarebbe opportuno usare solo il secondo tipo, ma questa non è una regola fissa. | ||
+ | Quando vengono usate le espressioni che producono un risultato numerico, il numero viene automaticamente convertito in " | ||
+ | |||
+ | === Traduzione in C++ === | ||
+ | Nel linguaggio C++ gli operatori logici AND, OR e NOT vengono tradotti con i seguenti simboli: | ||
+ | ^operatore^simbolo^ | ||
+ | | AND | && | | ||
+ | | OR | %%||%% | | ||
+ | | NOT | ! | | ||
+ | |||
+ | Per l' | ||
+ | {{ : | ||
+ | * Esempio di algoritmo che prevede la presenza di nebbia quando si verificano le seguenti condizioni: umidità relativa compresa tra il 85% e il 90%. | ||
+ | * chiedere in input il valore di umidità relativa (massimo 100) | ||
+ | * se //umidita// > 85 && //umidita// < 90 | ||
+ | * allora visualizzare in output " | ||
+ | * altrimenti visualizzare in output "non si prevede nebbia" | ||
+ | <file cpp 32b.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // visualizza le previsioni per la nebbia | ||
+ | // fornendo la percentuale di umidita' | ||
+ | // Domanda: cosa accade se inserisco un valore negativo? | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int umidita; | ||
+ | const int umiditaMin=85; | ||
+ | const int umiditaMax=90; | ||
+ | | ||
+ | std::cout << "Per favore scrivi il valore di umidita' | ||
+ | std::cin >> umidita ; | ||
+ | | ||
+ | if ( umidita > umiditaMin && umidita < umiditaMax ) // attenzione alla precedenza degli operatori... | ||
+ | std::cout << " si prevede nebbia " << | ||
+ | else | ||
+ | std::cout << " non si prevede nebbia " << std:: | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====Struttura condizionale annidata==== | ||
+ | {{ : | ||
+ | * //Esempio che visualizza il minimo di tre numeri// | ||
+ | * chiedere in input 3 valori numerici interi (primo, | ||
+ | * se primo < secondo | ||
+ | * allora: Se primo < terzo | ||
+ | * allora visualizzare in output: primo | ||
+ | * altrimenti visualizzare in output: terzo | ||
+ | * altrimenti: Se secondo < terzo | ||
+ | * allora visualizzare in output: secondo | ||
+ | * altrimenti visualizzare in output: terzo | ||
+ | |||
+ | ^ var. di input ^ tipo ^ var. di output ^ tipo ^ var. di lavoro ^ tipo ^ | ||
+ | | primo | num. intero | primo | num. intero | - | - | | ||
+ | | secondo | num. intero | secondo | num. intero | - | - | | ||
+ | | terzo | num. intero | terzo | num. intero | - | - | | ||
+ | |||
+ | <file cpp 33.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // visualizza il minimo di tre numeri | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int primo, | ||
+ | |||
+ | std::cout << " | ||
+ | std::cin >> primo >> secondo >> terzo ; | ||
+ | | ||
+ | if ( primo < secondo ) | ||
+ | if ( primo < terzo) | ||
+ | std::cout << " | ||
+ | else | ||
+ | std::cout << " | ||
+ | else | ||
+ | if ( secondo < terzo ) | ||
+ | std::cout << " | ||
+ | else | ||
+ | std::cout << " | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | === Condizione con operatore logico AND === | ||
+ | |||
+ | <file cpp 34.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // visualizza il minimo di tre numeri | ||
+ | // utilizzando gli operatori logici in alternativa alle condizioni annidate | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int primo, | ||
+ | |||
+ | std::cout << " | ||
+ | std::cin >> primo >> secondo >> terzo ; | ||
+ | if ( primo < secondo && primo < terzo ) | ||
+ | | ||
+ | else if ( secondo < terzo ) | ||
+ | std::cout << secondo ; | ||
+ | std::cout << terzo ; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==TO DO== | ||
+ | deve essere fatto un esercizio con if if else per spiegare il caso dell' | ||
+ | |||
+ | Esercizi: | ||
+ | |||
+ | - esercizio: chiedere due numeri e visualizzarli in ordine inverso | ||
+ | - esercizio: chiedere due numeri, senza un ordine, visualizzare uno dei tre messaggi: sono ordinati, sono disordinati, | ||
+ | |||
+ | =====Struttura iterativa===== | ||
+ | |||
+ | La struttura iterativa può essere studiata come composta da diversi elementi (che possono anche coincidere tra loro): | ||
+ | - un' | ||
+ | - un' | ||
+ | - un' | ||
+ | - la valutazione di un' | ||
+ | - un' | ||
+ | A seconda della posizione occupata dalla condizione di uscita all' | ||
+ | * precondizionale | ||
+ | * postcondizionale | ||
+ | Nel tipo precondizionale la condizione è prima delle istruzioni da ripetere. Nel tipo // | ||
+ | |||
+ | ==== Struttura iterativa postcondizionale ==== | ||
+ | |||
+ | Anche se esiste, si possono scrivere programmi senza usarla, quindi per ora viene omessa... | ||
+ | |||
+ | ==== Struttura iterativa precondizionale==== | ||
+ | |||
+ | // | ||
+ | |||
+ | >> La struttura iterativa // | ||
+ | |||
+ | * //while()// | ||
+ | * La condizione di uscita del rombo deve essere indicata tra le parentesi di while. L' | ||
+ | * < | ||
+ | while( ... ) | ||
+ | ... | ||
+ | </ | ||
+ | * // | ||
+ | * L' | ||
+ | * < | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | Il seguente esempio è stato tradotto in due diversi programmi, tra loro equivalenti, | ||
+ | * //Esempio che visualizza la tabellina del numero inserito// | ||
+ | * ripetere la seguente operazione per un indice (i) che va da 1 a 10 | ||
+ | * visualizzare in output il risultato dell' | ||
+ | |||
+ | ^ var. di input ^ tipo ^ var. di output ^ tipo ^ var. di lavoro ^ tipo ^ | ||
+ | | numero | num. intero | - | - | i | num. intero | | ||
+ | |||
+ | <file cpp 35.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // iterazione realizzata con while | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int numero; | ||
+ | std::cout << " | ||
+ | std::cin >> numero ; | ||
+ | int i=1; // inizializzazione del contatore | ||
+ | while ( i <= 10 ) // condizione di uscita | ||
+ | { | ||
+ | std::cout << numero * i << ' ' ; | ||
+ | i++; // incremento del contatore | ||
+ | } | ||
+ | std::cout << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file cpp 35b.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // iterazione realizzata con for | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int numero; | ||
+ | std::cout << " | ||
+ | std::cin >> numero ; | ||
+ | | ||
+ | for ( int i=1; i<=10; i++) // inizializzazione, | ||
+ | std::cout << numero*i << ' ' ; | ||
+ | | ||
+ | std:: | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * Esempio: Scrivere un programma che chieda cinque numeri e ne visualizzi la somma {{ : | ||
+ | * inizializzare totale a zero | ||
+ | * ripetere la seguente operazione per i che va da 1 a 5 | ||
+ | * chiedere in input numero | ||
+ | * incrementare totale con numero | ||
+ | * visualizzare totale | ||
+ | <file cpp 36.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // iterazione realizzata con while | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int totale=0, i=1, numero; // | ||
+ | while ( i <= 5 ) | ||
+ | { | ||
+ | std::cout << " | ||
+ | std::cin >> numero; | ||
+ | totale = totale + numero; | ||
+ | i = i + 1; | ||
+ | } | ||
+ | | ||
+ | std::cout << totale << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | <file cpp 36b.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // iterazione realizzata con for | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int numero, | ||
+ | |||
+ | for ( int i=1; i<=5; i++) | ||
+ | { | ||
+ | std::cout << " | ||
+ | std::cin >> numero ; | ||
+ | totale = totale + numero; | ||
+ | } | ||
+ | | ||
+ | std::cout << totale << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Struttura iterativa annidata==== | ||
+ | Scrivere un programma che visualizzi tutte le tabelline pitagoriche dall' | ||
+ | {{ : | ||
+ | <file cpp 37.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // visualizza la tabellina dell' | ||
+ | // la tabellina del due sulla seconda riga, e cosi via. | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int i=1; | ||
+ | while ( i<=10 ) | ||
+ | { | ||
+ | int j=1; | ||
+ | while ( j<=10 ) | ||
+ | { | ||
+ | std::cout << std:: | ||
+ | j=j+1; | ||
+ | } | ||
+ | i=i+1; | ||
+ | } | ||
+ | std::cout << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file cpp 37b.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // visualizza la tabellina dell' | ||
+ | // la tabellina del due sulla seconda riga, e cosi via. | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | |||
+ | for ( int i=1; i<=10; i++) | ||
+ | { | ||
+ | for ( int j=1; j<=10; j++) | ||
+ | std::cout << std:: | ||
+ | } | ||
+ | std::cout << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==== Struttura iterativa all' | ||
+ | * Esempio in cui si inseriscono due numeri interi: se viene inserito prima un numero più piccolo e dopo un numero più grande, si devono visualizzare tutti i numeri intermedi, mentre in caso contrario si deve visualizzare solo il numero più piccolo.{{ : | ||
+ | * Ad esempio, inserendo 5 e 9 viene visualizzato 6,7,8, mentre inserendo 9 e 5 viene visualizzato 5. | ||
+ | <file cpp provaacontare.cpp> | ||
+ | #include < | ||
+ | int main() | ||
+ | { | ||
+ | int num1,num2; | ||
+ | std::cout << "Per favore inserire due numeri interi " << std::endl; | ||
+ | std::cin >> num1 >> num2 ; | ||
+ | if (num1< | ||
+ | { | ||
+ | int i=num1+1; | ||
+ | while (i<num2) | ||
+ | { | ||
+ | std::cout << i << ", "; | ||
+ | i=i+1; | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | else | ||
+ | std::cout << num2 << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==== Struttura condizionale all' | ||
+ | * Esempio in cui si inseriscono due numeri interi e si visualizzano tutti i numeri intermedi ad eccezione del numero 7. (inserendo 3 e 8 si visualizza: 3,4,5,6,8) | ||
+ | * SENZA SOLUZIONE | ||
+ | |||
+ | ==== Numero di ripetizioni sconosciuto ==== | ||
+ | fare la somma di tutti i numeri inseriti fino a che si inserisce 0 per visualizzare il totale {{ : | ||
+ | |||
+ | <file cpp 37b.cpp> | ||
+ | // Questo programma è stato scritto da Fabio | ||
+ | // somma dei numeri senza dover sapere quanti sono | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int totale=0, numero=-1; // inizializzazioni | ||
+ | |||
+ | while(numero != 0) | ||
+ | { | ||
+ | std::cout << " | ||
+ | std::cin >> numero ; | ||
+ | totale = totale + numero; | ||
+ | } | ||
+ | std::cout << numero << std::endl; | ||
+ | } | ||
+ | </ | ||
+ | ====== Cenni alla ricorsione ====== | ||
+ | ===== Premessa ===== | ||
+ | |||
+ | Un programma che ripete più volte la stessa operazione, __in teoria__, può essere scritto secondo due approcci: | ||
+ | * l' | ||
+ | * la ricorsione | ||
+ | ===== Esempio del fattoriale di un intero N ===== | ||
+ | Chi volesse utilizzare l' | ||
+ | * ripetere per //i// da 1 a N | ||
+ | * moltiplicare tra loro tutte i valori di //i// | ||
+ | Chi volesse utilizzare l' | ||
+ | * moltiplicare N * (N-1) | ||
+ | * moltiplicare il risultato precedente per (N-2) | ||
+ | * moltiplicare il risultato precedente per (N-3) | ||
+ | * ... e così via... | ||
+ | * fino a 1 | ||
+ | Nell' | ||
+ | ===== Condizioni ===== | ||
+ | Per risolvere un problema con una ricorsione è necessario: | ||
+ | * esprimere la soluzione del passo generico //i// nei termini del passo precedente (//i-1//), ad esempio: < | ||
+ | * esprimere una condizione di terminazione, | ||
+ | <file cpp 41.cpp> | ||
+ | // calcolo del fattoriale | ||
+ | #include < | ||
+ | int main() | ||
+ | { | ||
+ | int numero, fattoriale=1; | ||
+ | std::cout << " | ||
+ | std::cin >> numero; | ||
+ | |||
+ | for (int i=1; i< | ||
+ | fattoriale = numero*fattoriale; | ||
+ | | ||
+ | std::cout << "Il fattoriale di " << numero << " vale " << fattoriale << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Verifica ===== | ||
+ | L' | ||
+ | Se l' | ||