I am surprised to see this code segment print the same address for all the three pointers.
int main(int argc,char *argv[])
{
int arr[3][3];
printf("%p\n%p\n%p\n",arr,*arr,arr[0]);
return 0;
}
Why this is so ?
I am surprised to see this code segment print the same address for all the three pointers.
int main(int argc,char *argv[])
{
int arr[3][3];
printf("%p\n%p\n%p\n",arr,*arr,arr[0]);
return 0;
}
Why this is so ?
See So what is meant by the ``equivalence of pointers and arrays'' in C?
The address of an array is the address of its first element. And, arr[i]
is equivalent to *(arr + i)
for any array arr
. Therefore, arr[0]
is the same as *(a + 0)
.
Because an array's address is equal to the starting element's address.
Which means, address of arr[1]
is equal to address of arr + 1
and address of *(arr + 1)
.
C lays out multidimentional arrays flat if at least all but the last dimension is known at compile time - so an int[3][3]
is actually just and int[9]
array in memory - only the type is different.
So, since an array is silently converted to a pointer to its first element when used in most expressions *arr
is always equivalent to arr[0] for all arrays.
In this instance, arr
(two levels of indirection to int) is a pointer to the first int[3]
array, *arr==arr[0]
(1 level of indirection to int) is a pointer to the first integer in the first int[3]
array, since the whole structure is 'flat' this first int[3]
starts at exactly the same place as the int[3][3]
array.
Its a little confusing, but in memory it is just 9 integers in a row that the compiler 'knows' should be treated as blocks of 3
if the cells are those shown below:
|0|1|2|3|4|5|6|7|8|
then arr
is a pointer to |0|, arr+1
is a pointer to |3| and arr+2
is a pointer to |6|
arr[0]
is ALSO a pointer to |0|, arr[0]+1
is a pointer to |1|, arr[0]+2
is a pointer to |2| and so on...
Since arr[0]
is always identical to *arr
for any array, *arr
is ALSO a pointer to |0|
arr
is the address of the first element in the array which is also the address of the first row of the array due to how C lays out multidimensional arrays in memory.
arr[0]
returns a pointer to the first row so is equivalent to arr
*arr
= arr[0]
as with all C pointers
basically they are all the same because of the way C lays out multidimensional arrays, the address of the beginning of the array is also the address of the first row of the array.
part of this confusion is that while for a 1 dimensional array, arr[]
, arr
can be treated as a pointer as if it were defined '*arr'. This isn't true for multidimensional arrays. arr[][]
can't be treated as a double pointer, as if it were defined **arr
. they are very different data types.