Newsgroup: it.comp.lang.c
Titolo: Array Multidimensionale

Scusate la STRA FAQ, domanda super veloce, come si dichiara un array
multidimensionale ??

 ha scritto nel messaggio
news:LJ8q6.10580$E57.4...@news4.aus1.giganews.com...


 multidimensionale ??
<tipo> array[numero_righe][numero_colonne];
HTH

Grazie Ciao

multidimensionale ??
Solo la dichiarazione?
Esempio
int array3d[100][34][45];
Lo standard C89 richiede che le dimensioni siano definite a tempo di
compilazione, lo standard C99 che a quanto ne so io non č ancora
implementato da alcun compilatore non lo richiede quindi č lecita una cosa
del tipo
int array3d[x][y][z];
dove x, y, z sono variabili.
Alcuni compilatori tipo gcc supportano le nuove regole (dimensioni definite
a run-time).
Se invece vuoi fare il tutto con l'allocazione dinamica della memoria, le
cose diventano piů lunghe.
Ci sono 2 sistemi che conosco. Per spiegarteli, facciamo finta di dover
creare un array bidimensionale di dimensioni x * y.
1) allochi dinamicamente un array di puntatori ad intero che rappresenta le
righe. Ognuno di questi puntatori punterŕ ad un array di interi, che
rappresenta la colonna.
Infine si fa puntare ogni riga alla giusta colonna.
int x,y;            // dimensioni
int **array2d;    // array di ptr alle colonne
int *temp;        // temporaneo, punta allo spazio riservato ai dati
int i;
.
.
array2d = malloc(sizeof(int *) * x);    // alloca 1 vettore di righe ognuna
di x elementi
temp = malloc(sizeof(int) * x * y);    // alloca x vettori di colonne ognuna
di y elementi
for(i = 0; i < x; i++)
    array2d[i] = temp + i*y;    // "assembla" l'array definitivo
Nell'esempio qui sopra tutte le colonne sono allocate in una botta unica, il
che minimizza il numero di chiamate a malloc, che di solito sono lente, e
semplifica la distruzione dell'array, perché devi chiamare free solo 2
volte. Se preferisci, puoi allocare lo spazio per ogni colonna singolarmente
in questo modo:
int x,y;
int **array2d;
int i;
.
.
array2d = malloc(sizeof(int *) * x);    // alloca 1 vettore di righe ognuna
di x elementi
for(i = 0; i < x; i++)
    array2d[i] = malloc(sizeof(int)*y); // alloca 1 colonna e fa sě che un
elemento dell'array delle righe punti ad essa.
Il vantaggio del secondo metodo che č ogni colonna puň avere un numero
diverso di elementi, quindi puoi farti una matrice che non sia quadrata, lo
svantaggio č che chiami malloc y+1 volte, e devi ricordarti di chiamare free
per ogni colonna.
Con entrambi puoi accedere all'array normalmente con array2d[p][q], ma c'č
uno svantaggio: bisogna allocare un vettore di righe, quindi in effetti
sprechi x*sizeof(int *) byte di memoria. Con array a piů dimensioni lo
spreco č accentuato, perché per ogni dimensione in piů bisogna allocare un
array in piů (fondamentalmente per avere 3 dimensioni crei tanti array
bidimensionali come ti ho mostrato sopra, e poi generi un ulteriore vettore
che li contenga tutti, e cosě via per 4,5,6 dimensioni :-).
Il secondo sistema evita questo consumo non necessario di memoria, perň
impedisce l'utilizzo della classica sintassi array2d[x][y] per accedere ad
un elemento.
In pratica si alloca un array monodimensionale e poi si simula il fatto che
sia pluridimensionale con qualche accorgimento al momento dell'accesso ai
dati.
int x,y;
int *array2d;    // ptr ai dati
.
.
array2d = malloc(sizeof(int)*x*y);
/* accedo all'elemento 3,4 */
array2d[3*y+4] = 27;
Per capire il funzionamento del 3*y+4, immagina di avere tutte le righe
dell'array una di seguito all'altra: il primo elemento della n-esima riga
(quello con offset 0 dall'inizio della riga, per capirci, quello che indichi
con p[n][0]) si trova a n*y elementi dal primo elemento dell'array, il
secondo dell'n riga si trova a n*y+1 e cosě via.
Questo sistema puň essere usato anche per array a piů dimensioni:
- array 2d. Siano x,y le dimensioni dell'array, si voglia cercare l'elemento
(i,j), la formula č:
    array2d[i*y+j];
- array 3d. Siano x,y,z le dimensioni dell'array, si voglia accedere
all'elemento (i,j,k)
    array3d[i*y*z+j*z+k];
E cosě via.
Questo secondo sistema ti permette di dover chiamare malloc e free una volta
sola, perň devi usare quella strana sintassi per poter lavorare sull'array.
Personalmente, io uso il 2° sistema, mascherando l'accesso dietro ad una
funzione, che date le coordinate dell'elemento richiesto, le dimensioni
dell'array ed un ptr al primo elemento mi fa tutto il calcolo. Se lavori in
C++, puoi crearti una bella classe e scrivere un metodo per accedere
all'elemento che ti serve, cosě l'accesso diventa qualcosa come
array2d.at
(2,4) = 57;
che č decisamente piů comprensibile di
array2d[2*y+4] = 57;
Oppure ancora, perň č una cosa che non ho mai fatto perché di C++ so davvero
poco, puoi sovraccaricare l'operatore () ed accedere agli elementi scrivendo
array2d(3,4) = 57;
che - se č possibile farlo, non sono sicuro ma penso di sě - č ancora piů
visivamente elegante.
Spero di non avere scritto cavolate, per sicurezza da' una controllatina
alle FAQ che trovi su 
www.programmazione.it
, se puoi dai anche un'occhiata
alle FAQ di comp.lang.c (mi pare), su cui l'argomento č spiegato davvero
bene.
Lanugo