• Non ci sono risultati.

Matrici (array bidimensionali)

N/A
N/A
Protected

Academic year: 2021

Condividi "Matrici (array bidimensionali)"

Copied!
20
0
0

Testo completo

(1)

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 };

(2)

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)

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)

(4)

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)

(5)

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)

(6)

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

o

compito del 4

o

studente

Voto 0 è un compito non consegnato

Matrici (array bidimensionali)

(7)

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)

(8)

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

(9)

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

(10)

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

(11)

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

(12)

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

(13)

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

vett+0*3+0 vett[0][0] = 'D'

vett[0][1] = 'E' vett[0][2] = 'V' vett[1][0] = 'C'

vett+0*3+1 vett+1*3+0 vett+1*3+1

Matrici come argomenti di funzioni

(14)

Passaggio di un array multidimensionale ad una funzione char vett[N1][N2]...[NP] = ...

tipo nomefunz(char vett[][N2]...[NP], ...);

Metodo di accesso:

vett + (i1 * N2 * ... * NP) + (i2 * N3 * ... * NP) + + ... + (ip-1 * NP) + ip

Il passaggio come parametro di funzione di un array multidimensionali richiede la specifica di tutte le dimensioni meno la prima

Il passaggio come parametro di funzione di una matrice richiede la specifica della dimensione di colonna

Esempio:

const int N=100; cont int M=150;

int A[N][M], B[N][M], n=75, m=75;

somma(A[][M], B[][M], n, m);

Matrici come argomenti di funzioni

(15)

Scriviamo una libreria per matrici che implementi le funzioni:

– LeggiMat() - legge una matrice generica di dimensione n x m – StampaMat() - stampa una matrice generica di dimensione n x m

con formato:

nome[0][0]=23 nome[0][1]=12 ...

nome[1][0]=3 ...

– GeneraMat () - inizializza una matrice di dimensione n x m con valori random

Libreria per Matrici

(16)

const int rigmax=10;

const int colmax=10;

void GeneraMat(char, int [][colmax], int, int);

void LeggiMat(char, int [][colmax], int, int);

void StampaMat(char, const int [][colmax], int, int);

int main() {

int A[rigmax][colmax],B[rigmax][colmax];

int righe,colonne;

srand(time(0));

printf("Righe ( max 10)=\n”); scanf(“%d”,righe);

printf("Colonne( max 10)=\n"); scanf(“%d”,colonne);

LeggiMat('B',B,righe,colonne);

printf(“\n”);

GeneraMat('A',A,righe,colonne);

printf(“\n”);

StampaMat('A',A,righe,colonne);

return 0;

}

Libreria per Matrici

(17)

void GeneraMat(char nomemat,int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++)

for (j=0; j<colonne; j++) { mat[i][j]=rand()%100 - 50;

cout<<nomemat<<"["<<i<<"]["<<j<<"]="<<mat[i][j]<<endl;

} }

void LeggiMat(char nomemat,int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++)

for (j=0; j<colonne; j++) {

cout<<nomemat<<"["<<i<<"]["<<j<<"]=";

cin>>mat[i][j];

} }

Libreria per Matrici

void GeneraMat(char nomemat,int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++)

for (j=0; j<colonne; j++) { mat[i][j]=rand()%100 - 50;

cout<<nomemat<<"["<<i<<"]["<<j<<"]="<<mat[i][j]<<endl;

} }

void LeggiMat(char nomemat,int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++)

for (j=0; j<colonne; j++) {

cout<<nomemat<<"["<<i<<"]["<<j<<"]=";

cin>>mat[i][j];

} }

void GeneraMat(char nomemat,int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++)

for (j=0; j<colonne; j++) { mat[i][j]=rand()%100 - 50;

printf(“%c[%d][%d]=%d ”,nomemat,i,j, mat[i][j]);

}

printf(“\n”);

}

void LeggiMat(char nomemat,int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++)

for (j=0; j<colonne; j++) {

printf(“%c[%d][%d]= \n”,nomemat,i,j);

scanf(“%d”,mat[i][j]);

}

}

(18)

void StampaMat(char nomemat,const int mat[][colmax], int righe,int colonne) {

int i,j;

for (i=0;i<righe;i++) {

for (j=0; j<colonne; j++)

printf(“%c[%d][%d]=%d ”,nomemat,i,j);

}

printf(“\n”);

}

Libreria per Matrici

(19)

Esempio

Assegnata una matrice di A dimensioni MxN stampare le somme totali di ogni riga.

Per gestire una matrice abbiamo sempre la necessità di utilizzare due cicli nidificati, uno che scorre le righe ed un altro le colonne:

for (i=0; i<M ; i++) for (j=0; j<N ; j++)

poiché dobbiamo determinare la somma degli elementi di una riga qualsiasi dobbiamo scrivere

somma¬ somma +A[i][j]

in cui i deve rimanere costante e j deve variare; l’istruzione precedente deve allora essere inserita nel secondo for, mentre subito dopo il primo for dobbiamo

inizializzare la variabile somma.

(20)

In definitiva l’algoritmo che risolve il problema è il seguente:

for (i=0; i<M ; i++) somma=0;

for (j=0; j<N ; j++)

somma ¬ somma + A[i][j];

stampa(i ,somma);

Riferimenti

Documenti correlati

[r]

Corso di Laurea in Ingegneria Civile Analisi Matematica I. Esercizi sulle approssimazioni

Trovare tutte le soluzioni delle equazioni dierenziali 1.. Cominciamo dalla

Punteggi da 18 a 23: Esenzione dalla sola prova scritta per gli argomenti del programma svolti no al 29 ottobre 1999 (spazi vettoriali reali, spazi euclidei, archi regolari,

38 disegno: il lato 43 deve essere orientato in senso

[r]

[r]

Esercizio per casa: da riconsegnare entro il 7 dicembre 2011 (per piacere, usare SOLO il foglio col testo, eventualmente fronte-retro).. Determinare tutte le soluzioni intere