oggi mi sento rompipall... intendevo dire "preciso".
nessuno aspetta il post kilometrico e pignolo (ma anche teorico) del barone!
A livello fisico naturalmente ogni array è sempre monodimensionale: l'accessibilità è a una sequenza di word di memoria, non è organizzata in maniera bidimensionale. Quindi una cella di memoria ha una cella "prima" ed una cella "dopo", ma non ne ha una a "sinistra" ed una a "destra".
Per questa struttura fisica della memora l'array (monodimensionale) diventa un tipo di dato comodissimo per accedere alla memoria.
memorizzo l'indirizzo base dell'array
memorizzo quale elemento dell'array voglio accedere
accedo al byte (indirizzo base + elemento_array*dimensione_in_byte_di_un_elemento_dell'array)
per chi sa il C:
Basi di C ha scritto:vettore[3] è un operatore binario che compie questa operazione *(vettore + 3*sizeof(*vettore))
cioè "accedi alla zona di memoria" identificata dalla zona di memoria del primo elemento di vettore (in C il nome dell'array in realtà è una costante che "contiene" l'indirizzo di memoria del primo elemento utile dell'array).
questo, sempre in C, permette anche di fare.
Codice: Seleziona tutto
int vettore[3]; //3 elemnti numerati da 0 a 2.
int *puntatore;
vettore[2]= 12;
puntatore= &vettore; //& messo per chiarezza, il nome di un array è già la costante-indirizzo, il C permette la sintassi con o senza "&"
if (puntatore[2] == 12) { script_log(TRUE); }
puntatore[2] equivale a *(punta + 2 * size_of(*puntatore));, e poichè puntatore contiene l'indirizzo del primo elemento di vettore accedo proprio a vettore[2].
Questo fa anche capire perchè i vettori devono avere l'indice che inizia per 0. E spiega perchè i linguaggi che hanno un indice del vettore che può iniziare non per zero sono "di serie B"
(ok, dai, di alto livello
).
Tutto questo per spiegare come funziona il "vettore bidimensionale"...
(chiedo venia, non ho la certezza se il vettore multidimensionale è memorizzato "prima tutta la prima riga" poi "tutta la seconda riga" o al contrario "prima tutta la colonna", poi "tutta la seconda colonna".
Sono quasi certo sia il primo caso, invoco Sla per la correzione. Proseguo ragionando con il primo caso)
int vettore[3][4]; // un vettore 3 righe per 2 colonne
vettore[1][2] si traduce in
*(vettore + 1*size_of(*vettore[]) + 2*size_of(*vettore))
cioè accedo all'indirizzo di memoria di:
base del vettore
+ dimensione di una riga (pari al numero delle colonne) -> quindi la dimensione di 4 elementi (un elemento "riga" è come se "puntasse" ad un vettore composto da "numero di colonne" elementi
+ dimensione di due elemeti (la dimensione dall'oggetto puntato da vettore è un intero)
Nel caso specifico indirizzo base + 4 interi + 2 interi (sesto elemento, la numerazione parte da zero!)
il mio vettore 3*4 è
**** riga 0
**** riga 1
**** riga 2
ed io accedo alla X
**** riga 0
**X* riga 1 + 3 elementi base
**** riga 2
in realtà in memoria il mio vettore è:
******X***** //una riga da 3*4 elmenti ed accedo al sesto (numero da zero!)
E così via per ogni tipo di vettore con più dimensioni.
Quindi un vettore ndimensionale può essere realizzato con uno monodimensionale a patto di conoscerne a priori la size di ogni dimensione!
Per come gestisce GML i vettori se si ridimensiona a posteriori si fa del gran casino!!!!
in GML
var x, y, z.
x= max_righe_matrice; //numero righe
y= max_colonne_matrice; //numero colonne
z= max_altezza_matrice; //numero altezza....
//inizializzo tutto a zero!!!
vettore3D[(x*y*z)-1]= 0;
script_accedi_vettore_3d(a,b,c); //occhio: qui a,b,c sono i tre indici, vanno da 0 a (max_*_matrice-1)
return ( vettore3D[a*(y*z)+b*z+z] )