// ex6_2_1.cpp #include <iostream.h> // stampa gli elementi da 0 a n-1 di un vettore intero void stampaVettore (int a[], int n) { for (int i = 0; i < n; i++) cout << "a[" << i << "]: " << a[i] << "\n"; } void main() { const int N = 7; int a[N]; for (int i = 0; i < N; i++) a[i] = i - N/2; stampaVettore (a, N); }
output:
a[0]: -3
a[1]: -2
a[2]: -1
a[3]: 0
a[4]: 1
a[5]: 2
a[6]: 3
Come si vede, nell'argomento della funzione non è necessario inserire il numero degli elementi. Un'altra osservazione importante è la seguente: quando passiamo un vettore ad una funzione, non sappiamo il numero degli elementi di tale vettore, per cui dobbiamo passare sempre anche tale numero.
Vediamo un esempio che inserisca in vettore la successione di Fibonacci e la stampi; essa è la seguente:
// ex6_2_2.cpp #include <iostream.h> // inserisce in un vettore la successione di Fibonacci void creaFibonacci (int v[], int n) { v[0] = v[1] = 1; // per ipotesi for (int i = 2; i < n; i++) v[i] = v[i-1] + v[i-2]; } // stampa un vettore dal termine inf al sup void stampa (int v[], int inf, int sup) { for (int i = inf; i <= sup; i++) cout << "v[" << i << "]: " << v[i] << "\n"; } void main() { const int MAX = 40; int fibonacci[MAX + 1]; creaFibonacci (fibonacci, MAX + 1); int inf, sup; cout << "stampare i termini" "\nda: "; cin >> inf; cout << "a: "; cin >> sup; if (!(inf > sup || sup > MAX || inf < 0)) stampa (fibonacci, inf, sup); }
esempio di output:
stampare i termini
da: 3
a: 7
v[3]: 3
v[4]: 5
v[5]: 8
v[6]: 13
v[7]: 21
La procedura di passare ad una funzione due indici (inferiore e superiore, ad esempio) insieme ad un array è molto comune, e verrà ripresa in diversi futuri programmi di esempio.
Presentiamo ora un programma che ``mischia'' un mazzo di 52 carte da poker e le stampa (tale esempio è basato su ex3_6_2.cpp
):
// ex6_2_3.cpp // mischia un mazzo di carte da poker // basato su ex3_6_2.cpp #include <iostream.h> #include <time.h> #include <stdlib.h> const int N_CARTE = 52; // non passiamo il numero di elementi del vettore // in quanto esso e' noto a priori (N_CARTE) void mischiaCarte (int mazzo[]) { // inizializza il generatore dei numeri casuali srand( time(0) ); for (int i = 0; i < N_CARTE; i++) { bool ok; do { // sceglie un numero da 1 a N_CARTE (52) int carta = rand() % N_CARTE + 1; ok = true; for (int j = 0; j < i; j++) if (mazzo[j] == carta) { for (int i = 0; i < N_CARTE; i++) { bool ok; do { // sceglie un numero da 1 a N_CARTE (52) int carta = rand() % N_CARTE + 1; ok = true; for (int j = 0; j < i; j++) if (mazzo[j] == carta) { ok = false; break; } mazzo[i] = carta; } while (!ok); } ok = false; break; } mazzo[i] = carta; } while (!ok); } } void stampaCarte (int mazzo[]) { for (int i = 0; i < N_CARTE; i++) { int carta = (mazzo[i] % 13) + 1; int seme = (mazzo[i] - 1) / 13; // seme: 0=cuori 1=quadri 2=fiore 3=picche // carta: 1=asso 11=fante(J) 12=regina(Q) 13=re(K) switch (carta) { case 1: cout << "A di "; break; case 10: cout << "10 di "; break; case 11: cout << "J di "; break; case 12: cout << "Q di "; break; case 13: cout << "K di "; break; default: cout << carta << " di "; } switch (seme) { case 0: cout << "C\t"; break; case 1: cout << "Q\t"; break; case 2: cout << "F\t"; break; case 3: cout << "P\t"; break; } if (i % 5 == 4) cout << "\n"; else cout << "\t"; } } void main() { int mazzo[N_CARTE]; // mettiamo a zero tutti gli elementi di mazzo[] for (int i = 0; i < N_CARTE; i++) mazzo[i] = 0; mischiaCarte (mazzo); stampaCarte (mazzo); }
esempio di output:
A di Q | Q di P | 7 di P | 2 di P | K di F | |
2 di Q | K di P | 8 di F | 10 di C | J di Q | |
K di Q | 9 di C | 7 di C | 2 di F | J di C | |
6 di F | 7 di Q | A di C | 8 di P | 5 di Q | |
5 di P | A di F | 5 di C | 5 di F | 3 di Q | |
Q di C | Q di Q | 9 di P | 3 di C | 4 di C | |
Q di F | 4 di F | K di C | 10 di F | 2 di C | |
7 di F | 6 di P | 10 di P | J di F | 4 di P | |
9 di Q | 9 di F | J di P | 8 di C | 3 di F | |
6 di C | 6 di Q | A di P | 4 di Q | 3 di P | |
8 di Q | 10 di Q |
La funzione che mischia le carte non è del tutto ovvia, ad una prima impressione; le operazioni che compiamo sono le seguenti: estraiamo un numero a caso e controlliamo che esso non sia già stato assegnato alle altre carte del mazzo: in questa maniera possiamo ottenere un elenco di 52 numeri tutti diversi l'uno dall'altro. Per effettuare questo controllo, non dobbiamo far altro che scorrere il nostro vettore dalla prima posizione fino a quella della carta da estrarre; abbiamo utilizzato dunque due indici (i
e j
) i quali scorrono il vettore il primo una ed una sola volta, il secondo 51 volte (la prima carta estratta è sicuramente buona ...). Come sempre, questo procedimento non è il più efficiente che si possa costruire, ma funziona ed è adatto ai nostri scopi; inoltre per soli 52 numeri interi da estrarre, con l'attuale sviluppo tecnologico , qualunque personal computer impiega tempi brevissimi a completare le operazioni (per intenderci, ho provato il programma su di una macchina con un processore Intel Pentium II e mediamente il programma è stato eseguito in 8 millisecondi; ho provato poi a fargli estrarre 52000 numeri ,un numero che per certi scopi non è poi molto grande, e siamo già sui 10 minuti di attesa).
Anche le funzioni aventi vettori come argomenti possono essere sovrapposte; per esempio sovrapponiamo la funzione sin
della libreria math.h
facendole calcolare il seno di ciascun elemento di un vettore:
// ex6_2_4.cpp #include <iostream.h> #include <math.h> const double PI = 3.14159265358979323846264338327; const int N_ELEM = 9; void sin (double v[], int n) { for (int i = 0; i < n; i++) v[i] = sin(v[i]); } void stampa (double v[], int n) { for (int i = 0; i < n; i++) cout << v[i] << "\n"; } void main() { double v[N_ELEM]; for (int i = 0; i < N_ELEM; i++) v[i] = PI/4 * i; sin (v, N_ELEM); stampa (v, N_ELEM); }
output:
0
0.707107
1
0.707107
1.22461e-16
-0.707107
-1
-0.707107
-2.44921e-16
Il vettore in questo esempio è stato costruito con i multipli di PI/4
, il quale è una buona approssimazione di ; tale approssimazione non è però in certi casi sufficiente, infatti risulta essere:
, che è matematicamente non vero.
sqrt
e permetta di calcolare la radice quadrata di ciascun elemento di un array;