"...shouldn't *a give value at address 2359028 i.e. 5?"
Yes and no. *a
should indeed give you the object at address a
. However, in your case a
has type int[3][3]
. This means that at this level of indirection the object at address a
(if we interpret a
as a pointer) is not 5
as you incorrectly believe, it is actually the entire 1D array a[0]
. The type of *a
is int [3]
and the value stored at *a
is, again, the entire 1D subarray a[0]
.
So, when you try to printf
*a
, you are actually specifying the the entire a[0]
subarray as an argument. That subarray decays to pointer, which naturally points to the same location (since the entire array a
and its first subarray a[0]
have the same location in memory). This is why printing a
and *a
as pointers (as well as &a
) results in the same numerical value being printed.
If you want to get access to 5
in this case, you have to do **a
. Just *a
is not enough.