appunti3s:programmazione_procedurale
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
appunti3s:programmazione_procedurale [2013/06/17 21:07] – external edit 127.0.0.1 | appunti3s:programmazione_procedurale [2020/06/08 22:19] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Programmazione procedurale ====== | ||
+ | Fino a questo momento ogni problema è stato affrontato individuando prima un algoritmo risolutore e poi traducendolo con un programma. | ||
+ | {{ : | ||
+ | Quando il problema da risolvere è abbastanza grande e complicato, il programma diventa più lungo e difficile da scrivere. In questi casi conviene dividere il problema in problemi più piccoli e semplici da risolvere. Per ogni sottoproblema si ottiene un sottoprogramma (o funzione) che lo risolve. Il programma finale desiderato (che risolve il problema iniziale) si può ottenere rimettendo insieme i diversi sottoprogrammi ottenuti. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Una volta che delle funzioni sono state scritte per risolvere una parte di un problema, queste possono anche essere riutilizzate per risolvere altri problemi simili. La maggior parte dei programmatori riutilizza infatti delle funzioni scritte da altri programmatori, | ||
+ | |||
+ | ===== Procedure e funzioni ===== | ||
+ | I termini // | ||
+ | |||
+ | Nella programmazione procedurale, | ||
+ | |||
+ | Come accade nelle funzioni matematiche, | ||
+ | |||
+ | Sarebbe utile eseguire i seguenti programmi in modalità [[appunti3s: | ||
+ | |||
+ | <file cpp 12.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // Serve a calcolare il triplo di un numero | ||
+ | // scrivendo tutto il codice nella funzione principale. | ||
+ | #include < | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | int mioNumero; | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | |||
+ | std::cout << "il triplo di " << mioNumero << " vale " | ||
+ | << 3*mioNumero << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Divisione in sottoproblemi ==== | ||
+ | Il precedente programma era stato scritto usando solo una funzione (main). | ||
+ | |||
+ | {{: | ||
+ | |||
+ | ===== Passaggio per valore ===== | ||
+ | La prima parte verrà svolta (come prima) dalla funzione main() mentre per la seconda parte verrà creata una nuova funzione: calcolaTriplo(). | ||
+ | Leggendo il nuovo codice sorgente si noterà che è diviso in due parti: | ||
+ | * in basso vi è la solita definizione di //main()//, la funzione principale, che come al solito restituisce un valore intero al sistema operativo. | ||
+ | * in alto vi è la definizione di // | ||
+ | Le due parti sono collegate tra di loro, infatti si può notare la presenza, dentro main(), della // | ||
+ | <file cpp 13.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // Come nel programma precedente calcola il triplo di un numero, ma | ||
+ | // ora usando una semplice funzione chiamata calcolaTriplo(). | ||
+ | // Questo modo di passare il valore crea una nuova variabile locale (int x) | ||
+ | // questa funzione restituisce un int (return) | ||
+ | |||
+ | #include < | ||
+ | |||
+ | // definizione della funzione calcolaTriplo() con parametro formale ' | ||
+ | int calcolaTriplo(int x) | ||
+ | { | ||
+ | return 3*x; | ||
+ | } | ||
+ | |||
+ | // | ||
+ | int main() | ||
+ | { | ||
+ | int mioNumero, | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | | ||
+ | mioTriplo = calcolaTriplo(mioNumero); | ||
+ | // parametro effettivo ' | ||
+ | | ||
+ | std::cout << "il triplo di " << mioNumero << " vale " | ||
+ | << mioTriplo << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | {{: | ||
+ | - Dentro main() c'è una chiamata di calcolaTriplo() e il valore da passare viene scritto tra parentesi. | ||
+ | - Dentro calcolaTriplo() c'è l' | ||
+ | Dentro la // | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Dentro la funzione calcolaTriplo() la variabile x non sembra essere mai inizializzata, | ||
+ | < | ||
+ | int x = mioNumero; | ||
+ | // la sua inizializzazione tramite valore passato tra parentesi | ||
+ | </ | ||
+ | Questo codice serve solo per capire come avviene l' | ||
+ | |||
+ | Nella // | ||
+ | |||
+ | ==== Valore restituito ==== | ||
+ | |||
+ | Al termine della funzione // | ||
+ | Infatti, leggendo il codice del main(), si può immaginare di sostituire, al posto della chiamata della funzione // | ||
+ | |||
+ | NOTA: questa nota deve essere letta solo da chi conosce il linguaggio C. A volte i programmatori C usano il valore restituito da una funzione per stabilire se questa è stata eseguita senza errori (restituendo 0) oppure se ha prodotto un errore (restituendo ad esempio 5). In C++, invece, il valore restituito non dovrebbe essere usato per questo scopo, perché, per stabilire se ci sono stati errori, si dovrebbero usare le // | ||
+ | |||
+ | ===== Visibilità delle variabili===== | ||
+ | |||
+ | Ecco una tabella che mostra la traccia dei valori contenuti nelle aree di memoria utilizzate durante l' | ||
+ | ^ mioNumero ^ mioTriplo ^ x ^ | ||
+ | | 9 | - | | ||
+ | | 9 | - | 9 | | ||
+ | | 9 | 27 | - | | ||
+ | |||
+ | * Le variabili dentro la chiamata di una funzione (mioNumero) sono dette parametri effettivi (actual parameters) | ||
+ | * Le variabili dentro la definizione di una funzione (x) sono dette parametri formali (formal parameters) | ||
+ | Questo tipo di tabella che tiene la traccia dei valori assunti dalle variabili durante l' | ||
+ | Da questo di deduce che ognuna delle funzioni viene eseguita utilizzando aree di memoria separate, che non sono reciprocamente visibili e per questo motivo tali variabili sono dette //variabili locali//. La comunicazione tra le due funzioni avviene solo grazie al passaggio della copia del valore (dentro //x//) e grazie al comando //return//. | ||
+ | |||
+ | Facendo un paragone, la funzione main() è come un datore di lavoro che chiama la funzione calcolaTriplo() ad eseguire un certo lavoro. Quando la chiama le fornisce anche una copia del dato su cui dovrà lavorare. Al termine, la funzione calcolaTriplo() restituisce al suo datore il risultato del suo lavoro. | ||
+ | |||
+ | ==== Debugger ==== | ||
+ | Prima di andare avanti nella lettura è necessario leggere questa [[appunti3s: | ||
+ | |||
+ | Per l' | ||
+ | Tali software di debug permettono quindi di capire cosa accade durante l' | ||
+ | |||
+ | I software di debug esistono sia con interfaccia grafica sia con interfaccia testuale: | ||
+ | * Si può usare un IDE (come // | ||
+ | * Si può usare la linea di comando di //gdb//, come in questo esempio: | ||
+ | - compilare il sorgente.cpp in debug mode < | ||
+ | - avviare il debugger, specificando anche l' | ||
+ | - inserire un breackpoint alla riga 5 digitando: < | ||
+ | - avviare esecuzione, che si interromperà al break, digitando:< | ||
+ | - al prompt creare un //automatic display// digitando: < | ||
+ | - procedere con passo 1, digitando: < | ||
+ | - basta premere invio per continuare con passo 1... | ||
+ | - Per uscire, digitare: < | ||
+ | |||
+ | |||
+ | === Esempi con errori === | ||
+ | |||
+ | Questo programma contiene un' | ||
+ | |||
+ | <file cpp 13error1.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // Serve a dimostrare l' | ||
+ | // usando due funzioni, ma contiene un ERRORE.... | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int calcolaTriplo() | ||
+ | { | ||
+ | return 3*mioNumero; | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int mioNumero, | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | | ||
+ | mioTriplo = calcolaTriplo(); | ||
+ | | ||
+ | std::cout << "il triplo di " << mioNumero << " vale " | ||
+ | << mioTriplo << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | dovrebbe produrre il seguente errore: | ||
+ | < | ||
+ | | ||
+ | |||
+ | <file cpp 13error2.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // e' simile al precedente, ma contiene un ERRORE... | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int calcolaTriplo(int x) | ||
+ | { | ||
+ | return 3*x; | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int mioNumero, | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | | ||
+ | mioTriplo = calcolaTriplo(mioNumero); | ||
+ | | ||
+ | std::cout << "il triplo di " << mioNumero << " vale " | ||
+ | << x << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Si dovrebbe ottenere questo errore | ||
+ | < | ||
+ | In function ‘int main()’: | ||
+ | : error: ‘x’ was not declared in this scope | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Introduzione alle direttive ===== | ||
+ | Questo argomento viene ripreso e approfondito nel prossimo capitolo, nel paragrafo [[appunti3s: | ||
+ | |||
+ | Che cosa significa la parola " | ||
+ | Si tratta di un file che si può trovare su ogni sistema operativo dove è installato un compilatore. | ||
+ | Se non si conosce la sua collocazione si può fare una ricerca... | ||
+ | iostream è un file (senza estensione) che contiene solo semplice testo. Aprendolo si troveranno dei commenti e delle dichiarazioni di classi, operatori, variabili, oggetti e funzioni che sarebbe necessario scrivere prima del main() quando si vogliono usare certe funzioni. | ||
+ | |||
+ | Questo tipo di file sono detti " | ||
+ | |||
+ | Usando la direttiva #include si evita di scrivere tutte le cose che contengono. | ||
+ | |||
+ | Esistono numerosi altri file di intestazione, | ||
+ | |||
+ | ==== Esempio con string ==== | ||
+ | |||
+ | In C++ esiste un tipo di dato chiamato // | ||
+ | |||
+ | Una variabile di tipo std%%:: | ||
+ | < | ||
+ | Come già detto, però, l' | ||
+ | <file cpp 14.cpp> | ||
+ | // questo programma è stato scritto da Fabio | ||
+ | // mostra che l' | ||
+ | // e che essi verranno letti al successivo utilizzo di Extractor | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | std::string parola; | ||
+ | |||
+ | std::cout << "primo input: scrivi due parole con lo spazio in mezzo" << std::endl; | ||
+ | std::cin >> parola; | ||
+ | std::cout << parola << std::endl; // non ha letto la seconda parola | ||
+ | |||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | Ogni volta che si inserisce uno spazio si deve effettuare una nuova lettura per non perdere i dati in input. Quindi bisognerebbe aggiungere queste istruzioni | ||
+ | < | ||
+ | std::cin >> parola; | ||
+ | std::cout << parola << std:: | ||
+ | </ | ||
+ | Questo esempio mostra l'uso di una funzione che legge anche più parole separate da uno spazio. | ||
+ | <file cpp 14bis.cpp> | ||
+ | // questo programma è stato scritto da Fabio | ||
+ | // mostra che l' | ||
+ | // digitato dall' | ||
+ | // mostra il funzionamento delle funzioni cin.ignore() e getline(); | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | string parola; | ||
+ | | ||
+ | cout << " | ||
+ | getline(cin, | ||
+ | cout << parola << endl; | ||
+ | | ||
+ | cout << " | ||
+ | cin >> parola; | ||
+ | cout << parola << endl; // rimane uno " | ||
+ | // Se si usasse di nuovo getline() | ||
+ | // verrebbe letto solo quest' | ||
+ | | ||
+ | cin.ignore(); | ||
+ | // (newline) che l' | ||
+ | // Quindi tra un cin e un getline() e' necessario usare un ignore() | ||
+ | | ||
+ | cout << " | ||
+ | getline(cin, | ||
+ | cout << parola << endl; | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Un' | ||
+ | |||
+ | <file cpp 15.cpp> | ||
+ | // Questo programma e` stato scritto da Fabio. | ||
+ | // Dimostra l' | ||
+ | // effettuando più chiamate della stessa funzione. | ||
+ | // | ||
+ | // Serve a calcolare la media di 4 numeri. | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int calcolaMedia(int x, int y) | ||
+ | { | ||
+ | return (x+y)/2; | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int numero1, | ||
+ | |||
+ | std::cout << "Per favore scrivi due numeri interi separati da uno spazio: " | ||
+ | << std::endl; | ||
+ | std::cin >> numero1 >> numero2 ; | ||
+ | int media1 = calcolaMedia(numero1, | ||
+ | | ||
+ | std::cout << "Per favore scrivi due numeri interi separati da uno spazio: " | ||
+ | << std::endl; | ||
+ | std::cin >> numero3 >> numero4; | ||
+ | int media2 = calcolaMedia(numero3, | ||
+ | |||
+ | std::cout << | ||
+ | |||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Dichiarazioni ===== | ||
+ | Ora che è chiara l' | ||
+ | - definizione di calcolaTriplo() | ||
+ | - definizione di main() | ||
+ | |||
+ | Provando ad invertire l' | ||
+ | |||
+ | La funzione calcolaTriplo() può essere // | ||
+ | dove si possono individuare tre parti: | ||
+ | - dichiarazione di calcolaTriplo() | ||
+ | - definizione di main() | ||
+ | - definizione di calcolaTriplo() | ||
+ | |||
+ | L' | ||
+ | |||
+ | <file cpp 16.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // Come nel programma precedente calcola il triplo di un numero, ma | ||
+ | // serve a dimostrare la differenza tra dichiarazione e definizione di una funzione | ||
+ | |||
+ | #include < | ||
+ | |||
+ | // dichiarazione della funzione calcolaTriplo() | ||
+ | int calcolaTriplo(int x); | ||
+ | |||
+ | // | ||
+ | int main() | ||
+ | { | ||
+ | int mioNumero, | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | |||
+ | mioTriplo = calcolaTriplo(mioNumero); | ||
+ | // parametro effettivo ' | ||
+ | |||
+ | std::cout << "il triplo di " << mioNumero << " vale " | ||
+ | << mioTriplo << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | // definizione di calcolaTriplo() (che deve rispettare la dichiarazione) | ||
+ | int calcolaTriplo(int x); | ||
+ | { | ||
+ | return 3*x; | ||
+ | } | ||
+ | </ | ||
+ | Un' | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | <file cpp 17.cpp> | ||
+ | // questo programma e` stato scritto da Fabio | ||
+ | // Serve a calcolare la media (valore intero) tra due interi | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int media(int x, int y); // dichiarazione | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int numero1, | ||
+ | |||
+ | std::cout << "Per favore scrivi due numeri interi separati da uno spazio: " | ||
+ | << std::endl; | ||
+ | std::cin >> numero1 >> numero2 ; | ||
+ | | ||
+ | std::cout << | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | int media(int x, int y) // definizione | ||
+ | { | ||
+ | return (x+y)/2; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Classificazione delle funzioni===== | ||
+ | |||
+ | In base al valore restituito, esistono due diversi tipi di funzioni: | ||
+ | * quelle che restituiscono un risultato (es: un valore) a chi le chiama; | ||
+ | * < | ||
+ | * quelle che non restituiscono nessun risultato a chi le chiama (tipo mancante: //void//). | ||
+ | * < | ||
+ | |||
+ | Il primo tipo di funzioni può essere chiamato in uno di questi due semplici modi: | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | Il secondo tipo può essere chiamato in questo modo: | ||
+ | * < | ||
+ | |||
+ | Il primo tipo consente anche di essere utilizzato con chiamate più articolate, come: | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | ==== L' | ||
+ | Per quanto riguarda il primo tipo, si tratta di funzioni che sono progettate per fare una cosa: | ||
+ | - restituire un risultato (es: un valore) | ||
+ | Per quanto riguarda il secondo tipo, si può facilmente immaginare che una funzione che __non__ restituisce un risultato dovrà avere sicuramente un qualche altro tipo di **effetto** nella memoria o nell' | ||
+ | |||
+ | Questo effetto potrebbe produrlo anche una funzione del primo tipo. Questo è solo un caso particolare del primo tipo di funzioni, che, quindi, producono due effetti: | ||
+ | - restituiscono un risultato | ||
+ | - producono un effetto sulla memoria | ||
+ | Quando interessa esclusivamente il secondo effetto, queste funzioni (del primo tipo) possono essere usate ignorando completamente il valore che restituiscono e chiamate come se fossero del secondo tipo. | ||
+ | |||
+ | ==== Esempio ==== | ||
+ | |||
+ | Si può riscrivere il precedente esempio in modo che la funzione sia di tipo void? | ||
+ | |||
+ | Se il solito esempio venisse scomposto in due problemi di tipo diverso, si potrebbe realizzare una funzione che si occupa di leggere i dati in input e un' | ||
+ | Si suggerisce di confrontare il vecchio esempio con il seguente e di annotare cosa cambia nella definizione della funzione e cosa cambia nella chiamata della funzione. | ||
+ | |||
+ | {{: | ||
+ | |||
+ | <file cpp 18.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // Come nel programma precedente calcola il triplo di un numero, ma | ||
+ | // la funzione calcolaTriplo() è di tipo void. | ||
+ | // Questa funzione non restituisce nessun valore (non c' | ||
+ | |||
+ | #include < | ||
+ | |||
+ | void calcolaTriplo(int x) // definizione della funzione con parametro formale ' | ||
+ | { | ||
+ | std::cout << 3*x << std::endl; | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int mioNumero, | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | | ||
+ | std::cout << "il triplo di " << mioNumero << " vale " | ||
+ | << mioTriplo << endl; | ||
+ | |||
+ | calcolaTriplo(mioNumero); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Quest' | ||
+ | |||
+ | <file cpp 18error.cpp> | ||
+ | // Questo programma e` stato scritto da Fabio. | ||
+ | // Contiene una funzione di " | ||
+ | // infatti (manca return) | ||
+ | // ed inoltre mostra un ERRORE dovuto all' | ||
+ | |||
+ | #include < | ||
+ | |||
+ | void calcolaTriplo(int x) | ||
+ | { | ||
+ | x= 3*x; // Ha effetto sul parametro reale? | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int mioNumero; | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | std::cout << "il triplo di " << mioNumero << " vale "; | ||
+ | |||
+ | calcolaTriplo(mioNumero); | ||
+ | std:: | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Provare sostituire la definizione della funzione con la seguente definizione | ||
+ | < | ||
+ | void calcolaTriplo(int& | ||
+ | // eccetera... | ||
+ | </ | ||
+ | ==== Ispettori e modificatori ==== | ||
+ | |||
+ | Un altro tipo di classificazione delle funzioni le divide in funzioni ispettrici (inspector) e modificatrici (mutator) (o metodi // | ||
+ | |||
+ | === Ispettori === | ||
+ | |||
+ | Queste non modificano il contenuto delle variabili passate, quindi di solito, per avere un effetto al loro esterno, devono restituire un valore (quindi non possono essere di tipo void); di solito sono usate per __prelevare un valore__ (senza apportare modifiche) perciò in passato venivano chiamati anche metodi // | ||
+ | |||
+ | Si possono riconoscere facilmente in quanto è buona abitudine terminare la loro dichiarazione con //const//. In questo modo infatti il compilatore aiuta a trovare errori di programmazione. | ||
+ | < | ||
+ | int fun(int x) const; | ||
+ | int fun(const NomeClasse& | ||
+ | const NomeClasse& | ||
+ | </ | ||
+ | |||
+ | === Mofidicatori === | ||
+ | |||
+ | Queste possono modificare il contenuto delle variabili passate, quindi possono produrre un effetto al loro esterno anche se sono di tipo void; di solito sono usate per __impostare un valore__ perciò in passato venivano chiamati anche metodi // | ||
+ | |||
+ | Ovviamente queste si riconoscono dall' | ||
+ | |||
+ | < | ||
+ | void fun(Classe& | ||
+ | </ | ||
+ | Per completare la discussione su ispettori e modificatori si devono conoscere i [[appunti3s: | ||
+ | Si preferisce rimandare questa discussione, | ||
+ | |||
+ | ===== Esempi ===== | ||
+ | |||
+ | Nel programma 13.cpp la variabile mioTriplo NON era veramente necessaria. Si può riscrivere il programma scrivendo la chiamata della funzione calcolaTriplo() come se fosse una variabile intera, che viene visualizzata su %%std:: | ||
+ | | ||
+ | <file cpp 19.cpp> | ||
+ | // Questo programma e` stato scritto da Fabio. | ||
+ | // Dimostra l'uso di una funzione dentro l' | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int calcolaTriplo(int x) | ||
+ | { | ||
+ | return 3*x; | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int mioNumero; | ||
+ | |||
+ | std::cout << "Per favore scrivi un numero intero: "; | ||
+ | std::cin >> mioNumero; | ||
+ | |||
+ | // la chiamata della funzione (triplicare) dentro Insertion | ||
+ | std::cout << "il triplo di "<< | ||
+ | << calcolaTriplo(mioNumero) << std::endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | <file cpp 20.cpp> | ||
+ | // Questo programma è stato scritto da Fabio. | ||
+ | // Dimostra la differenza tra concetto di dichiarazione e di definizione | ||
+ | |||
+ | #include < | ||
+ | |||
+ | // dichiarazione della funzione | ||
+ | int calcolaMedia(int x, int y); | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | int numero1, | ||
+ | |||
+ | std::cout << "Per favore scrivi due numeri interi separati da uno spazio: " | ||
+ | << std::endl; | ||
+ | std::cin >> numero1 >> numero2; | ||
+ | std::cout << "Per favore scrivi due numeri interi separati da uno spazio: " | ||
+ | << std::endl; | ||
+ | std::cin >> numero3 >> numero4; | ||
+ | |||
+ | media = calcolaMedia(calcolaMedia(numero1, | ||
+ | std::cout << | ||
+ | |||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | // definizione della funzione | ||
+ | int calcolaMedia(int x, int y) | ||
+ | { | ||
+ | return (x+y)/2; | ||
+ | } | ||
+ | </ | ||
+ | ==== Dichiarazione e definizione ==== | ||
+ | La // | ||
+ | In breve, tutto quello che è viene semplicemente " | ||
+ | Una classe può essere usata solo dopo aver effettuato (oltre alla sua definizione) anche la definizione delle funzioni che essa contiene. | ||
+ | |||
+ | === Dichiarazione === | ||
+ | Annuncia (al compilatore) l' | ||
+ | La // | ||
+ | Vedere [[appunti3s: | ||
+ | * La // | ||
+ | * La // | ||
+ | * La // | ||
+ | * La // | ||
+ | * La // | ||
+ | * La dichiarazione di una classe contiene solo il nome della classe, e anch' | ||
+ | * nota: per approfondire le dichiarazioni, | ||
+ | |||
+ | === Definizione === | ||
+ | |||
+ | {{: | ||
+ | |||
+ | La // | ||
+ | |||
+ | * La // | ||
+ | * Per i precedenti motivi la definizione è unica (non si può ripetere). | ||
+ | * La // | ||
+ | * La // | ||
+ | * La // | ||
+ | * La // | ||
+ | |||
+ | |||
+ | ==== Variabili ==== | ||
+ | |||
+ | Per quanto riguarda le variabili non si distingue tra // | ||
+ | |||
+ | < | ||
+ | è sia dichiarazione che definizione. | ||
+ | Dopo aver visto alcuni esempi, si può stabilire una regola per le dichiarazioni di variabili: | ||
+ | |||
+ | < | ||
+ | |||
+ | specificatore + tipo + operatore + nome + operatore + inizializzazione | ||
+ | |||
+ | ==== Funzioni ==== | ||
+ | esempio di // | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | |||
+ | esempio di // | ||
+ | |||
+ | < | ||
+ | { | ||
+ | // codice... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | >> Le funzioni membro definite dentro la def. della classe sono **implicitamente** " | ||
+ | ==== Classi ==== | ||
+ | esempio di // | ||
+ | < | ||
+ | Class Cosa; // esempio di forward declaration | ||
+ | </ | ||
+ | |||
+ | esempio di // | ||
+ | < | ||
+ | Class Cosa | ||
+ | { | ||
+ | public: | ||
+ | Cosa(); | ||
+ | private: | ||
+ | int x; | ||
+ | void fun(std:: | ||
+ | }; | ||
+ | </ | ||
+ | L'// | ||
+ | Il codice che usa oggetti del tipo appartenente ad una determinata classe (detto anche codice client o client code) deve includere l' | ||
+ | ===== Verifica ===== | ||
+ | - In cosa consiste la fase di compilazione e cosa produce? | ||
+ | - Che differenza c'è tra un errore di compilazione e un bug? Fare un esempio. | ||
+ | - Che cosa significa l' | ||
+ | - Che cosa significa l' | ||
+ | - Quale delle due istruzioni è obbligatoria? | ||
+ | - Come si riconosce il nome di una funzione() dal nome di una variabile? | ||
+ | - Come si può migliorare la funzione int calcolaMedia(); | ||
+ | |||
+ | - Quanti tipi di funzioni esistono in base al tipo di dato restituito? | ||
+ | - Cosa sono i parametri formali e i parametri effettivi? | ||
+ | - Cosa significa passaggio per valore dei parametri? | ||
+ | |||
+ | |||
+ | Esercizi: data la dichiarazione di una funzione, scrivere la chiamata | ||
+ | - double areaRettangolo(double base, double altezza); | ||
+ | - double radiceQuadrata(double numero); | ||
+ | - bool segnoPositivo(double numero); | ||
+ | - float distanza(float x, float y); | ||
+ | - void saluto(); | ||
+ | - void numeroCasuale(); | ||
+ | |||
+ | Esercizi: usare le seguenti funzioni < | ||
+ | - float pow(float a, float b); | ||
+ | - float sqrt(float a); | ||
+ | - float fmax(float a, float b); %%//%% restituisce il massimo | ||
+ | - trovare il massimo di tre numeri usando fmax()... | ||
+ | |||
+ | Esercizi: usare le seguenti funzioni < | ||
+ | - int find( char c, size_t pos = 0 ) const; | ||
+ | - int size() const; | ||
+ | |||
+ | Programmi procedurali da scrivere: | ||
+ | - scrivere una funzione che calcola l'area del rettangolo | ||
+ | - verificare pre-condizioni sui dati in ingresso prima di usarli (raggio positivo) | ||
+ | - verificare post-condizioni sui dati in uscita (area positiva) | ||