Supponiamo di avere un array 2d (per semplicità, il processo di dimensionalità superiore è lo stesso)
int array[3][3];
L'array visualizzato in memoria è unidimensionale, ma logicamente possiamo pensarlo in questo modo
array
----------------------------
| [0][0] | [0][1] | [0][2] |
----------------------------
| [1][0] | [1][1] | [1][2] |
----------------------------
| [2][0] | [2][1] | [2][2] |
----------------------------
Quando chiami array[1][1]
, stai recuperando il valore in quella posizione (che ho scelto di seguito per essere 12)
----------------------------
| 0 | 0 | 0 |
----------------------------
| 0 | 12 | 0 |
----------------------------
| 0 | 0 | 0 |
----------------------------
Questo ci permetterebbe di costruire un codice come il seguente
int value = array[1][1];
std::cout << value << std::endl;
Output
12
Quando chiami &array[1][1]
, stai recuperando il puntatore su quella posizione
Il seguente codice recupera il puntatore al "centro" dell'array
int* ptr = &array[1][1];
(*ptr) = 10;
Quale cambierebbe il valore in quella posizione in 10
. Ciò comporterebbe l'aspetto della matrice
----------------------------
| 0 | 0 | 0 |
----------------------------
| 0 | 10 | 0 |
----------------------------
| 0 | 0 | 0 |
----------------------------
Fondamentalmente, il processo per interpretare ptr = &array[1][1][1]
è lo stesso, ma hai a che fare con una matrice di dimensionalità più elevata.
È il puntatore al secondo elemento dell'array in ogni dimensione. Il tuo insegnante sarebbe stato corretto se il tuo codice dicesse ptr = &array[0][0][0]