I am having troubles with the following code:
int a[] = {1, 2, 3, 4};
fprintf(stdout,
"a : %lu\n"
"*a : %d\n"
"&a : %ld\n"
"**(&a) : %d\n",
(unsigned long int)a,
*a,
(unsigned long int)&a,
**(&a)
);
Output:
a : 140726063647232
*a : 1
&a : 140726063647232
**(&a) : 1
i know that &a
is a pointer to the 1 D array. And &a
's type is int (*)[4]
.
I am confused with how comes **(&a): 1
.
Another way to look at it is through the resulting type after each address of or dereference operation. A basic rule for array access is Array-pointer conversion. C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) which applies on access to any array (subject to the 4 exceptions listed [3 in the C18 standard --
_Alignof
is no longer listed]).The key is to understand that an array, on access, is converted to a pointer to the first element (subject to limited exception - not relevant here). If you take the address of an array, the address is the same as that of the first element, but the type of pointer is completely different.
When you dereference
a
, you get the first element:Why?
*a
is short for the full derefernce operation with an offset of0
, e.g.*(a + 0)
which is equivalent toa[0]
in index notation.When you dereference your pointer-to-array
int[4]
, you get your array back:which then, by operation of, 6.3.2.1(p3) is converted to a pointer to the first element. Dereference again and you get the first element:
It's worth learning now as it will save you a lot of bewilderment later.