Let's assume we have a 2d-array like (for simplicity sake, the process for higher dimensionality is the same)
int array[3][3];
The array viewed in memory is one dimensional, but logically we can think of it like this
array
----------------------------
| [0][0] | [0][1] | [0][2] |
----------------------------
| [1][0] | [1][1] | [1][2] |
----------------------------
| [2][0] | [2][1] | [2][2] |
----------------------------
When you call array[1][1]
, you are retrieving the value at that location (which I chose below to be 12)
----------------------------
| 0 | 0 | 0 |
----------------------------
| 0 | 12 | 0 |
----------------------------
| 0 | 0 | 0 |
----------------------------
This would allow us to construct code like the following
int value = array[1][1];
std::cout << value << std::endl;
Output
12
When you call &array[1][1]
, you are retrieving the pointer to that location
The following code would retrieve the pointer to the "center" of the array
int* ptr = &array[1][1];
(*ptr) = 10;
Which would change the value in that location to 10
. This would result in the array to look like
----------------------------
| 0 | 0 | 0 |
----------------------------
| 0 | 10 | 0 |
----------------------------
| 0 | 0 | 0 |
----------------------------
Basically, the process for interpreting ptr = &array[1][1][1]
is the same, but you are dealing with an array of higher dimensionality.
It is the pointer to the second element of the array in each dimension. Your teacher would've been correct if your code said ptr = &array[0][0][0]
[1]
is the second element not the first element of an array. Arrays in C start at zero.