Matrici (array bidimensionali)
Un array bidimensionale, anche detto matrice, è una variabile strutturata tale che:
– gli elementi sono tutti dello stesso tipo e
– il meccanismo di accesso (diretto) ai suoi elementi consiste di due espressioni intere (indici)
– Esempi:
int C[4][3];
float f[M][N];
char b[2][3]={{'a', 'b', 'c'},{'d', 'e', 'f'}}
int A[ ][3]= { 1,2,3,4,5,6,7,8,9 };
Matrici (array bidimensionali)
Le matrici possono essere rappresentate per comodità in formato tabellare
Colonne Righe
Colonna 0 Colonna 1 Colonna 2
Riga 0 C[0][0] C[0][1] C[0][2]
Riga 1 C[1][0] C[1][1] C[1][2]
Riga 2 C[2][0] C[2][1] C[2][2]
Riga 3 C[3][0] C[3][1] C[3][2]
La seconda coppia di parentesi indica la colonna di appartenenza La prima coppia di
parentesi indica la riga di
appartenenza
3
Ogni elemento viene scritto utilizzando due coppie di parentesi quadre: la prima coppia di parentesi contiene l’indice della riga, la seconda coppia l’indice della colonna. Se inseriamo nella matrice C dei valori interi otteniamo la seguente rappresentazione
In questo caso abbiamo, per esempio C[0][0]=3 ; C[2][1]=2 ; C[3][2]=-6.
-6 1
9
Riga 3
6 2
0
Riga 2
-1 8
4
Riga 1
7 -5
3
Riga 0
righe
Colonna 2 Colonna 1
Colonna 0
colonne
Matrici (array bidimensionali)
Esempio.
Una classe composta da 32 studenti ha sostenuto durante l’anno 5 compiti in classe. Supponiamo di voler scrivere un programma che calcoli la media dei voti ottenuti dagli studenti .
Si potrebbe allora dichiarare una matrice del tipo: int A[32][5] in cui inserire i voti riportati da ciascun studente in ciascun compito.
Siccome però in una classe ci potrebbero essere più studenti o i compiti potrebbero essere di più, conviene adoperare per maggior generalità la seguente dichiarazione:
int const R=40; int const C=8; int A[R][C]; int n=32, m=5.
Matrici (array bidimensionali)
Esempio: una classe di 32 studenti ha sostenuto durante l’anno 5 compiti in classe. Supponiamo di voler scrivere un programma che stampi per ogni studente la somma e la media dei voti
ottenuti
int const R=40;
int const C=8;
int A[R][C];
int n=32;
int m=5;
Compito Studente
0 1 2 3 4 5 6 7
0 9 6 0 7 7 N
O N
U S A T A
1 5 6 6 0 6
2 8 6 7 0 0
3 4 6 5 4 4
... … … … … …
... … … … … …
32 2 4 4 5 4
... NON USATA
39
R
C
dichiariamo una matrice A[][]
di interi contenente … su ogni riga i voti
di ogni studente (32), …
su ogni colonna i voti di ogni compito
Matrici (array bidimensionali)
Esempio: una classe di 32 studenti ha sostenuto durante l’anno 5 compiti in classe. Supponiamo di voler scrivere un programma che stampi per ogni studente la somma e la media dei voti
ottenuti
int const R=40;
int const C=8;
int A[R][C];
int n=32;
int m=5;
Compito Studente
0 1 2 3 4 5 6 7
0 9 6 0 7 7 N
O N
U S A T A
1 5 6 6 0 6
2 8 6 7 0 0
3 4 6 5 4 4
... … … … … …
... … … … … …
32 2 4 4 5 4
... NON USATA
39
C
R
dichiariamo una matrice A[][]
di interi contenente …
A[3][2] è il voto del 3
ocompito del 4
ostudente
Voto 0 è un compito non consegnato
Matrici (array bidimensionali)
Tenendo presente l’ultimo esempio, scrivere un algoritmo che stampi il numero d’ordine di ogni studente con accanto il numero di esami superato e la loro media.
Descrizione algoritmo.
Per ogni riga i che rappresenta uno studente
Scandire le colonne relative alla riga i e sommare e contare ogni esame il cui risultato è >0
Stampa(i, conta, media)
Pseudocodice.
for (i=0; i<32; i++) conta¬0; somma¬0 for (j=0; j<5; j++)
if A[i][j] > 0
conta¬conta+1
somma¬somma+A[i][j]
if (somma¹0)
stampa(i, conta, somma/conta) else
stampa(messaggio)
Matrici (array bidimensionali)
Nel passaggio di un array monodimensionale ad una function è
necessario indicare soltanto il nome seguito dalle due parentesi quadre, perché passando alla function l’indirizzo del primo
elemento essa è in grado di determinare l’indirizzo di ogni elemento successivo.
Naturalmente un altro parametro deve rappresentare il numero di elementi effettivamente presenti nell’array
Matrici come argomenti di funzioni
Passaggio di un array monodimensionale ad una funzione
char vett[N] = {'D','E','V','C','P','P'};
tipo nomefunz(char vett[], int n, ...);
Gli array a uno o più dimensioni sono
allocati “linearmente”
in memoria
Per array monodimensionali il
compilatore sa calcolare l’indirizzo di ogni elemento senza bisogno di sapere la dimensione con la formula:
vett + i (metodo di accesso)
1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
RAM
vett+0 vett[0] = 'D'
vett[1] = 'D' vett[2] = 'V' vett[3] = 'C' vett[4] = 'P' vett[5] = 'P'
vett+1 vett+2 vett+3 vett+4 vett+5
Matrici come argomenti di funzioni
Passaggio di un array bidimensionale ad una funzione
char vett[N][M] = {{'D','E','V'},{'C','P','P'}};
tipo nomefunz(char vett[][M], int n, int m, ...);
Gli array a uno o più dimensioni sono
allocati “linearmente”
in memoria
Per array bidimensionali il
compilatore sa calcolare l’indirizzo di ogni elemento solo se conosce il numero di colonne con la formula:
vett + (i * M) + j (metodo di accesso)
1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
RAM
vett+0*3+0 vett[0][0] = 'D'
vett[0][1] = 'E' vett[0][2] = 'V' vett[1][0] = 'C' vett[1][1] = 'P' vett[1][2] = 'P'
vett+0*3+1 vett+0*3+2 vett+1*3+0 vett+1*3+1
Matrici come argomenti di funzioni
Sia assegnato una matrice A di interi di dimensioni massime 4x5 (il primo numero, 4, indica le righe, il secondo, 5, le colonne); essa sarà
dichiarata come int A[4][5]
il compilatore allocherà per tale array uno spazio rappresentato dalla seguente tabella:
Supponiamo che, durante l’esecuzione, vengano riempite soltanto le prime tre righe e le prime due colonne.
Se a questo punto si volesse utilizzare una procedura esempio che abbia come parametro la matrice A la chiamata sarebbe esempio(A,3,2) per indicare alla procedura che solo le prime tre righe e le prime due
colonne sono significative.
X X
X X
X X
Matrici come argomenti di funzioni
Tuttavia la intestazione della function non potrebbe essere:
void esempio (int A[ ] [ ], int n, int m);
Infatti poiché con A[ ][ ] s’intende l’indirizzo del primo elemento A[0][0], la function comincerà ad eseguire i calcoli sulla prima riga; per determinare l’indirizzo della seconda riga non è sufficiente conoscere il numero logico di colonne, che è 2, ma occorre anche saperne il numero fisico che invece è 5;
per andare sulla seconda riga il compilatore deve saltare 5 locazioni di memoria e non 3!
Solo in questo modo è in grado di determinare l’indirizzo iniziale di ogni riga successiva alla prima.
Per questa ragione la chiamata di una matrice deve includere anche il massimo numero di colonne; la function esempio dovrà avere la seguente intestazione:
void esempio (int A[ ] [5], int n, int m);
Se un array possiede più di due dimensioni, può essere richiamato da una function soltanto nel caso in cui vengono assegnate tutte le dimensioni massime esclusa la prima.
Matrici come argomenti di funzioni
Passaggio di un array bidimensionale ad una funzione
char vett[3][3];
vett[0][0]=‘D’;vett[0][1]=‘E’; vett[1][0]=‘V’;
vett[1][1]=‘C’;
Gli array a uno o più dimensioni sono
allocati “linearmente”
in memoria
Per array bidimensionali il
compilatore sa calcolare l’indirizzo di ogni elemento solo se conosce il numero di colonne con la formula:
vett + (i * M) + j (metodo di accesso)
1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
RAM