Fondamenti di Informatica A - Massimo Bertozzi LE FUNZIONI
Fondamenti di Informatica A - Massimo Bertozzi Concetto di funzione ✗ Tutti i linguaggi di alto livello permettono l'utilizzo di funzioni o procedure. ✗ Una funzione è un insieme di istruzioni del linguaggio. ✗ L'utilizzo di funzioni permette di aggiungere operazioni più complesse di quelle fornite dal linguaggio. ✗ Programmazione procedurale ✗ Funzioni di alto o basso livello
Fondamenti di Informatica A - Massimo Bertozzi Motivazioni ✗ Fattorizzazione: una funzione può essere definita una singola volta ma usata un numero qualunque di volte ✗ Facilità di modifica: viene ridotta la ridondanza. ✗ Migliore leggibilità: si possono isolare i dettagli del codice.
Fondamenti di Informatica A - Massimo Bertozzi Livelli di software
Fondamenti di Informatica A - Massimo Bertozzi Approccio top-down Quando si deve affrontare un problema complesso è utile scomporlo in sottoproblemi: Contare il numero di parole in un file: Aprire il file Fino a quando ci sono parole Leggere una parola Incrementare il contatore Chiudere il file Stampare il contatore
Fondamenti di Informatica A - Massimo Bertozzi Approccio top-down (2) Leggere una parola: Fino a quando ci sono caratteri Leggere carattere È una lettera? Ripeti Else Esci
Fondamenti di Informatica A - Massimo Bertozzi Funzioni predefinite ✗ Il C++ mette a disposizione numerose funzioni di utilità generale. ✗ Per il loro utilizzo occorre: ✗ includere l'header opportuno ✗ #include ✗ conoscere la sintassi ✗ (istruire il linker)
Fondamenti di Informatica A - Massimo Bertozzi Definizione Una definizione di funzione in C++ ha la seguente struttura: Tipo Nome_funzione(lista parametri formali); Tipo Nome_funzione(lista parametri formali){ Corpo della funzione; } La funzione può essere chiamata con: Nome_funzione(lista argomenti);
Fondamenti di Informatica A - Massimo Bertozzi Esempio ✗ int helloworld(char lang[]){ ✗ if(strcmp(lang,”it_ITA”) ✗ cout << “Ciao” << endl; ✗ else ✗ cout << “Hello” << endl; ✗ return 0; ✗ }
Fondamenti di Informatica A - Massimo Bertozzi I prototipi In C++ è sempre opportuno dichiarare la funzione prima del suo utilizzo prototipo I prototipi di funzione permettono di indicare al compilatore i parametri e il tipo di valore restituito ✗ Rendono più agevole la gestione dei sorgenti ✗ Permettono il controllo della sintassi ✗ Sono indice di buona programmazione
Fondamenti di Informatica A - Massimo Bertozzi Argomenti ✗ Gli argomenti di una funzione consentono il passaggio di dati alla funzione stessa ✗ Devono essere consistenti con la definizione della funzione (come tipo) ✗ Sono separati da “,” ✗ Non esiste limite al loro numero (...)
Fondamenti di Informatica A - Massimo Bertozzi Argomenti (2) Sono possibili differenti modalità di passaggio degli argomenti: ✗ Passaggio per valore: ✗ È il caso piú comune ✗ Occorre non confondere variabile e argomento ✗ Passaggio per riferimento: ✗ Consente l'utilizzo di variabili esterne ✗ Passaggio per indirizzo: ✗ Piú efficiente nell'utilizzo di memoria (const)
Fondamenti di Informatica A - Massimo Bertozzi Corpo della funzione ✗ Il corpo della funzione è completamente racchiuso tra ``{'' e ''}'' ✗ Può essere vuoto: ✗ Utile nelle prime fasi di sviluppo programmi, ✗ Funzioni stub. ✗ Può contenere sia istruzioni che dichiarazioni di variabili
Fondamenti di Informatica A - Massimo Bertozzi Valori restituiti ✗ Le funzioni possono restituire direttamente un solo valore mediante l'istruzione return. ✗ Il valore restituito deve essere compatibile con la definizione della funzione. ✗ Qualora sia necessario restituire piú valori si devono utilizzare argomenti passati per riferimento o per indirizzo.
Fondamenti di Informatica A - Massimo Bertozzi Tipo void ✗ Il tipo void è uno dei tipi di dato fornito dal C++ ✗ utilizzato anche per prototipi delle funzioni: ✗ funzione che non restituisce alcun valore ✗ funzione che non accetta parametri; ✗ Nel caso di funzione che non restituisce alcun valore, l'istruzione return non è necessaria void mia_func(void);
Fondamenti di Informatica A - Massimo Bertozzi Chiamata di una funzione ✗ La chiamata di una funzione (o invocazione di una funzione) trasferisce il controllo alla funzione stessa. ✗ Una funzione che restituisce un valore è un'espressione e quindi può comparire ovunque si può mettere un'espressione. ✗ È comunque possibile ignorare il valore restituito.
Fondamenti di Informatica A - Massimo Bertozzi Chiamata di una funzione (2) ✗ Quando viene invocata una funzione: 1. viene creata una copia degli argomenti passati 2. viene memorizzato il punto in cui è stata chiamata 3. viene trasferito il controllo ✗ Quando la funzione termina: 1. viene (eventualmente) memorizzato il valore restituito 2. vengono distrutte le variabili locali della funzione e le copie degli argomenti 3. il programma riparte dal punto in cui la funzione era stata invocata
Fondamenti di Informatica A - Massimo Bertozzi Chiamata di una funzione (3) ✗ Il meccanismo di invocazione di una funzione ha le seguenti conseguenze: ✗ le variabili locali di una funzione vengono ogni volte inizializzate e distrutte ✗ soluzione: operatore static ✗ non è possibile la modifica degli argomenti passati ✗ soluzione: puntatori e variabili passate per riferimento
Fondamenti di Informatica A - Massimo Bertozzi I riferimenti ✗ I riferimenti (reference) sono un tipico costrutto del C++ ✗ Un riferimento è un nome alternativo per un oggetto (variabile) ✗ Non sono un tipo di dato ✗ Sono spesso utilizzati quando una funzione deve poter modificare gli argomenti passati
Fondamenti di Informatica A - Massimo Bertozzi I riferimenti (2) ✗ Un riferimento deve essere sempre inizializzato mediante un lvalue: int ii=0; int& rr=ii; // definizione e inizializzazione riferimento int & dd=2; // errato!! (non per lo spazio) rr++; // sinonimo di ii++;
Fondamenti di Informatica A - Massimo Bertozzi Riferimenti come parametro di funzioni ✗ I riferimenti possono essere utilizzati come parametro per funzioni che devono poter modificare i valori degli argomenti: void incr(int& aa){aa++;} void f(){ int x=1; incr(x); //x=2 }
Fondamenti di Informatica A - Massimo Bertozzi Argomenti predefiniti ✗ In C++ è possibile definire un valore di default per gli argomenti. ✗ Posso avere chiamate alla stessa funzione con un numero differente di argomenti. ✗ Se un parametro ha un valore di default anche i successivi lo devono avere. ✗ In linea generale occorre definire i valori nel prototipo.
Fondamenti di Informatica A - Massimo Bertozzi Sovraccaricamento (overloading) ✗ È possibile definire funzioni aventi lo stesso nome ma che: ✗ richiedono un differente tipo di argomenti ✗ restituiscono un tipo di dato differente ✗ richiedono un numero differente di argomenti int max(int, int); int max(int, int, int); float max(float, float);
Fondamenti di Informatica A - Massimo Bertozzi La ricorsione ✗ Una funzione che chiama se stessa si definisce ricorsiva. ✗ La ricorsione è una tecnica ampiamente utilizzata che permette di semplificare la struttura dei programmi. ✗ In generale l'implementazione di un algoritmo in maniera ricorsiva è piú corta della versione non ricorsiva.
Fondamenti di Informatica A - Massimo Bertozzi La ricorsione (2) ✗ Esempio: il calcolo del fattoriale unsigned long fact(unsigned int n){ if(n==1) return 1; return n*fact(n-1); } unsigned long fact_nr(unsigned int n){ int ris=1; for(;n!=1;n--) ris*=n; return ris; }
Fondamenti di Informatica A - Massimo Bertozzi La ricorsione: condizione di uscita ✗ Ogni funzione ricorsiva deve sempre prevedere una condizione di uscita: void non_esco(void){ static int count=1; cout << count; ++count; non_esco(); }
Fondamenti di Informatica A - Massimo Bertozzi La ricorsione: efficienza ✗ La semplicità della ricorsione può portare il programmatore a non tener conto dell'efficienza: unsigned long fibonacci(unsigned int n){ if(!n) return 0; if(n==1) return 1; return fibonacci(n-2)+fibonacci(n-1); } //
Fondamenti di Informatica A - Massimo Bertozzi La ricorsione: efficienza (2) ✗ L'implementazione ricorsiva vista in precedenza non è efficiente. ✗ Si può dimostrare che se S è il tempo necessario al calcolo del numero di fibonacci di indice N (f N ), il calcolo di f N+1 richiede circa 1,6xS. ✗ Ad esempio se il calcolo di f N richiede 1 s, il calcolo di f N+18 richiederà un'ora.
Fondamenti di Informatica A - Massimo Bertozzi La ricorsione: efficienza (3) unsigned long Fibos[NGRANDE]={0,1}; unsigned long fibonacci(unsigned int n){ if(!n) return 0; if (Fibos[n]) return Fibos[n]; return Fibos[n]=fibonacci(n-2)+fibonacci(n-1); } ✗ l'insieme di queste tecniche prende il nome di dynamic programming