Per rispondere correttamente alla tua domanda, leggere su ordine row-major, che è come gli array multidimensionale sono memorizzati in C. La Wikipedia article è un po 'troppo stringato, ma uno di questi potrebbe essere più chiaro:
http://webster.cs.ucr.edu/AoA/Windows/HTML/Arraysa2.html http://archive.gamedev.net/archive/reference/articles/article1697.html http://www.ibiblio.org/pub/languages/fortran/append-c.html
C'è anche this SO question.
In risposta diretta alla sua punti, partendo dal presupposto che si sa come funziona stoccaggio row-major:
int A[5][2][3]
dichiara una regione contigua di memoria che è lunga 5 * 2 * 3 int: cinque matrici di due matrici di tre interi ciascuna. Gli array sono memorizzati uno accanto all'altro nella memoria lineare, cosicché
&A[0][0][0] == A
&A[0][0][1] == A+1
&A[0][1][0] == A+(1*3)
&A[3][1][2] == A+(3*(2*3))+(1*3)+2
A[1]
non è tecnicamente un puntatore ma un array. È un array int [2][3]
. Ma trovo molto meno chiaro pensare che considerare A[5][2][3]
è una regione piatta della memoria, lunga trenta.
A[0][0][0] is the first integer in that region.
A[0][0][1] is the second integer.
A[0][0][2] is the third integer.
A[0][1][0] is the fourth integer in this flat region.
A[0][1][1] is the fifth integer.
And so on until A[1][0][0] is the eleventh integer.
Pertanto l'indirizzo del A[1][0][0]
è dieci interi passati A[0][0][0]
; ie, &A[1][0][0] - &A[0][0][0] == 10
. Poiché il linguaggio C è molto lento sulla differenza tra array e puntatori, A[1]
viene interpretato come se fosse un indirizzo quando lo si utilizza in un'espressione, anche se in realtà significa "il primo elemento in una matrice di cinque array di due array di tre numeri interi "che è a sua volta" una matrice di due matrici di tre numeri interi. "
Il risultato è che A[1]
non negozio un puntatore, si è un puntatore. Ogni indirizzo di memoria da &A[0][0][0]
a &A[5][2][3]-1
memorizza un numero intero nel proprio array multidimensionale.
Quello che stai pensando nei punti (2) e (3) sono arrays of pointers to arrays, che sono qualcosa di diverso.
Questo è molto più facile da spiegare con le immagini, motivo per cui dovresti trovare un vero libro di testo o un articolo sugli array C.
In generale, quando si apprendono i puntatori e gli array in C, si consiglia di dimenticare temporaneamente la lingua stessa e di fingere di essere Dennis Ritchie che inventa C su un PDP-11 con 56kb di RAM piatta. Prendi un grande foglio di carta millimetrata, numera le sue celle consecutivamente, fai finta che rappresenti la tua RAM e ogni cella sia un byte e you can work through your pointer math with pencil and paper.
C è stato inventato in quell'ambiente e la comprensione delle sue origini renderà il langauge moderno molto più sensato.
Come nota a margine, quando ho provato a scrivere questa risposta, il linguaggio di markup dello Stack Overflow ha cambiato più volte e ha rovinato gli indici nei miei esempi di array sopra. Quindi se vedi dei numeri che sembrano fuori portata per i loro array, è un errore introdotto dall'editor.
Non direttamente correlato alla domanda, ma 'printf()' formato "% d" si aspetta un 'int' e se non ne fornisci uno colpisci Comportamento indefinito, che è Cattivo. Dagli "A [1]" un decodificatore array-of-2x3-int a pointer-to-int, 'A [1] [0]' un decadimento array-of-3-int a pointer-to-int, e '& A [1] [0] [0]' un puntatore-a-int. Se sizeof (int) sizeof (int *) probabilmente vedrai la spazzatura; ma un compilatore opportunamente machiavellico potrebbe emettere il codice per cancellare il tuo hard disk e comunque conformarsi allo standard. –
mlp