// ex8_2_1 #include <iostream.h> void stampa (int* v, int n, int colonne) { for (int i = 0; i < n; i++) if ((i+1) % colonne == 0) cout << v[i] << "\n"; else cout << v[i] << "\t"; } void stampa (int* v, int n) { for (int i = 0; i < n; i++) if ((i+1) % 5 == 0) cout << v[i] << "\n"; else cout << v[i] << "\t"; } void main() { int array[10]; for (int i = 0; i < 10; i++) array[i] = i+1; stampa (array, 10, 5); stampa (array, 10); }
output:
1 | 2 | 3 | 4 | 5 | |
6 | 7 | 8 | 9 | 10 | |
1 | 2 | 3 | 4 | 5 | |
6 | 7 | 8 | 9 | 10 |
Piuttosto che avere due funzioni del tutto simili, possiamo utilizzare la tecnica degli argomenti default per il terzo argomento:
void stampa (int* v, int n, int colonne = 5) { for (int i = 0; i < n; i++) if ((i+1) % colonne == 0) cout << v[i] << "\n"; else cout << v[i] << "\t"; } |
Cosa vuol dire int colonne = 5
? Significa che se viene fornito il terzo argomento in fase di chiamata allora il valore 5
non viene preso in considerazione; se invece vengono passati due soli parametri locali allora automaticamente colonne
viene inizializzato con il valore 5
.
Non c'è nessun limite al numero di elementi default che una funzione può avere; ci sono solo due regole da rispettare: gli argomenti default non devono creare ambiguità con altre funzioni sovrapposte; possono avere valori default solo gli argomenti all'estrema destra nella dichiarazione di funzione, senza saltarne nessuno. Vediamo qualche esempio. Le seguenti due dichiarazioni di funzioni sono errate se utilizzate nello stesso programma:
void funzione (int arg1, int arg2 = 0); void funzione (int arg1); |
funzione(7)
il compilatore non potrebbe scelgliere la funzione da utilizzare; ricordiamo che in ogni caso il C++ non ammette ambiguità nelle chiamate di funzione. Anche la seguente dichiarazione è errata:
void funzione (int arg1 = 0, int arg2); |
void funzione (int arg1 = 5, int arg2 = 12); |
funzione (); // arg1 = 5, arg2 = 12 funzione (3); // arg1 = 3, arg2 = 12 funzione (3, 7); // arg1 = 3, arg2 = 7 |
// ex8_2_3 #include <iostream.h> #include <string.h> enum Linea { CONTINUA, TRATTEGGIATA, PUNTOLINEA}; enum Colore { NERO, BIANCO, ROSSO, VERDE, BLU }; struct Circonferenza { double x, y; // posizione del centro double raggio; char* nome; Colore coloreLinea, coloreRiempimento; Linea stileLinea; bool soloContorno; Circonferenza ( double Raggio, const char* Nome = "senzanome", double X = 0, double Y = 0, Colore ColoreLinea = NERO, Colore ColoreRiempimento = BIANCO, Linea StileLinea = CONTINUA, bool SoloContorno = true ) { raggio = Raggio; nome = new char[strlen(Nome) + 1]; strcpy (nome, Nome); x = X; y = Y; coloreLinea = ColoreLinea; coloreRiempimento = ColoreRiempimento; stileLinea = StileLinea; soloContorno = SoloContorno; } }; void stampa (const Circonferenza& c) { cout << "\nnome: " << c.nome << "\n" << "(" << c.x << " , " << c.y << ")" << " raggio: " << c.raggio << "\n" << "colore linea: " << c.coloreLinea << "\n" << "colore riempimento: " << c.coloreRiempimento << "\n" << "stile linea: " << c.stileLinea << "\n" << "solo contorno: " << c.soloContorno << "\n"; } void main() { Circonferenza c1 ( 2.5, "circ.1", 2, -1.5, ROSSO, VERDE, TRATTEGGIATA, false); Circonferenza c2 (6, "circ.2", 7, 1.2); Circonferenza c3 (5); stampa (c1); stampa (c2); stampa (c3); }
output:
nome: circ.1
(2 , -1.5) raggio: 2.5
colore linea: 2
colore riempimento: 3
stile linea: 1
solo contorno: 0
nome: circ.2
(7 , 1.2) raggio: 6
colore linea: 0
colore riempimento: 1
stile linea: 0
solo contorno: 1
nome: senzanome
(0 , 0) raggio: 5
colore linea: 0
colore riempimento: 1
stile linea: 0
solo contorno: 1
L'esempio precedente potrebbe essere parte di una qualunque libreria grafica; gli argomenti con valori default ci offrono la possibilità di creare una Circonferenza
senza fornire tutti i parametri: l'unico argomento che deve necessariamente essere passato è il raggio, per ovvi motivi.
ex8_2_3
si costruisca una struttura Rettangolo
e una funzione stampa
di uscita delle caratteristiche del rettangolo passatogli; Rettangolo
deve essere passato per riferimento costante: perché?