120 likes | 393 Views
Tipo ritornato. Parametri. double max( double a, double b) { return (a>b) ? a : b; }. Corpo della funzione. Funzioni. In C++ le funzioni sono caratterizzate da un nome, dal tipo della variabile ritornata e da una lista di parametri (opzionali)
E N D
Tipo ritornato Parametri double max( double a, double b) { return (a>b) ? a : b; } Corpo della funzione Funzioni • In C++ le funzioni sono caratterizzate da un nome, dal tipo della variabile ritornata e da una lista di parametri (opzionali) • La lista dei parametri (anche se vuota) deve essere esplicitata • Il valore ritornato deve essere compatibile, a meno di conversione esplicita, con il tipo della funzione Valore di ritorno
Tipo di dichiarazione C++ commenti funzione double cube(double x) parametri passati { return x*x*x; } “by value” procedura void scrivi_quadrato(int i) subroutine, non si { cout<<i*i<<endl; } usa return senza argomenti void hello () puo` anche essere { cout<<“Hello”<<endl; } void hello(void) argomenti passati void swap(int& i,int& j) i e j hanno i loro per riferimento { int t=i; i=j; j=t; } valori scambiati variabile int scanf(const char, …) chiamata con un qualsiasi numero di argomenti inline inline double cube(int x) codice inline argomenti di int power(int i, int n=2) il 2do argomento default puo` essere tralasciato Funzioni (2)
main.cc max.cc #include <iostream> double max(double, double); int main() { double m = max(1, 3); cout<<“Il massimo e` “<<m<<endl; return 0; } double max (double a, double b) { return (a>b) ? a : b; } Prototipi delle funzioni • Prima di essere usata, una funzione deve essere dichiarata (nel file che la usa) • I prototipi rendono le funzioni in C++ “type safe”, nel senso che i valori reali degli argomenti vengono all’occorrenza convertiti nei tipi formali specificati dal prototipo Prototipo di max (normalmente in max.h)
Chiamata per valore • Con il passaggioper valore la funzione non può modificare il valore dei suoi argomenti • Es: int i = 5, j=7; • Dopo la chiamata di greater (i,j) • i vale sempre 5 e j vale sempre 7 bool greater(int i, int j) { // se i>j scambia i e j if (i>j) { int temp=i; i=j; j=temp; return true; } else return false; } Argomenti passati “per valore” sono scambiati nella funzione ma nel programma chiamante hanno i valori vecchi
Puntatori come parametri • L’uso dei puntatori permette ad una funzione di modificare il valore dei suoi argomenti • Es: int i = 5, j=7; • Dopo la chiamata di greater (&i,&j) • i varrà 7 e j 5 bool greater(int *p1, int *p2) { /* se il valore puntato da p1 > valore puntato da p2 scambia i due valori*/ if (*p1>*p2) { int temp=*p1; *p1=*p2; *p2=temp; return true; } else return false; } Se passo i puntatori le modifiche Hanno effetto sul programma chiamante
Chiamata per riferimento • L’uso dei riferimenti permette ad una funzione di modificare il valore dei suoi argomenti • Con i riferimenti è sufficiente chiamare greater (i, j); • Per ragioni di efficenza, oggetti di grandi dimensioni (in termini di memoria) vengono normalmente passati “by reference”. • Per evitare che possano essere modificati dalla funzione, il riferimento viene definito const bool greater(int& i, int& j) { // se i>j scambia i e j if (i>j) { int temp=i; i=j; j=temp; return true; } else return false; } Argomenti passati “by reference” possono essere modificati dalla funzione stessa
Funzioni inline • La keyword inline suggerisce al compilatore che ogni chiamata alla funzione deve essere convertita in codice eseguibile (la definizione della funzione viene sostituita alla chiamata dovunque nell codice) • Le funzioni inlinevengono usate per ragioni di efficienza e (per non sovraccaricare il compilatore) devono essere semplici • Il compilatore può decidere autonomamente (per esempio se la funzione è troppo lunga) di ignorare la direttiva inline
main.cc pow.cc int pow(int , int); int main() { int r=3; int a1=pow(3,3); // a1=27 int a2=pow(3); // a2=9 return 0; } int pow (int a, int k=2) { if (k==2) return a*a; else return a*pow(a, k-1); } Argomenti di default • Ad ogni parametro di una funzione può essere assegnato un valore di default. Questo permette di chiamare la funzione tralasciando quei parametri il cui valore di default risulta appropriato • Solo ai parametri più a destra nella calling sequence può essere dato un default. Argomento di default
average_array.cc double media_array(const int a[], int size) { int sum=0; for (int i=0;i<size;i++) sum+=a[i]; return double(sum)/size; } double media_array(const double a[], int size) { double sum=0; for (int i=0;i<size;i++) sum+=a[i]; return sum/size; } Overloading • Funzioni diverse possono avere lo stesso nome • La funzione che viene chiamata è scelta dal compilatore in base al tipo di ritorno ed al numero e tipo degli argomenti
Overloading (2) • La lista dei tipi degli argomenti di una funzione è chiamata signature • Il tipo ritornato dalla funzione non fa parte della signature, mentre il numero e l’ordine degli argomenti è cruciale void print(int i=0) {. . .} // (1) void print(int i, double x) {. . .} // (2) void print(double y, int i) {. . .} // (3) . . . print(‘A’); // ‘A’ e` convertito a int, chiama (1) print(str[]); // errore! Non e` possibile una conversione print(15,9); // errore! Ambiguita` fra (2) e (3) print(15,9.); // OK, chiama (2) print(); // OK, chiama (1) con il default
L’algoritmo di selezione • L’utente può sempre utilizzare una conversione forzata (type cast) per ottenere una corrispondenza • Il compilatore segnala tutti i casi in cui esiste ambiguità Ricerca della corrispondenza esatta Promozioni standard degli argomenti int long I tentativi del compilatore Conversioni standard dei tipi int float Conversioni definite dall’utente traccia int