Say I initialise arrays and variables as such:
int arr1d[3] = { 1, 2, 3 };
int* arrptr = arr1d;
int (*ptr1d)[3] = &arr1d;
int arr2d[2][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr2d)[3] = arr2d;
So, arr1d
is an array of 3 integers. Under the hood, arr1d
is a pointer to the first element of the array, i.e. &arr1d[0]
. Hence, we can assign arr1d
to int* arrptr
.
ptr1d
points to an array of 3 integers. arr1d
is an int*
pointing to &arr1d[0]
, but why is &arr1d
of type int (*)[3]
? Naively, I thought that writing &arr1d
simply gave us an address to assign to the pointer. Is this is something specific to pointers to arrays?
Apparently, arr2d
is of type int (*)[3]
(which I learned from this post). Both ptr2d
and *ptr2d
have the same value, so why is that second dereference even necessary? My thoughts are that it may be because ptr2d
is of type int (*)[3]
(pointer to array of 3 ints), *ptr2d
is of type int*
(pointer to an int), and so **ptr2d
ultimately gets us the first value of the first array, 1. So we're not dereferencing here to walk along addresses as we see in many diagrams, we're dereferencing to access underlying types. Is this correct? Does this explain why the type of &arr1d
is also int (*)[3]
(we're going "up a level"?)
Thank you.