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.
 
    