meatballs
is an array, and it has type int[5]
. However C doesn't allow passing arrays by value, so array decays into pointer for function call. This is equivalent of pointer to first element of array &meatballs[0]
, and it has type int*
.
&meatballs
is a pointer to an array, and it has type int(*)[5]
. Since it's a pointer it can be passed to a function.
As you can see, both 1. and 2. return same address, but they have different types: pointer to integer array vs pointer to single integer.
Note: Types void*
and int*
don't necessarily have the same representation(1), and for %p
only valid type is void*
(2) or you will get undefined behaviour(3). Always convert pointer to void*
when printing addresses:
printf("%p %p", (void*)meatballs, (void*)&meatballs);
- Last situation is same as first, but you are using wrong type specifier
%d
. Resulting type is again int*
as in case 1, but it is interpreted as int
. This is clear undefined behaviour, and output is garbage.
To print integer array element, use any of the following methods:
printf("%d %d %d", meatballs[i], *(meatballs + i), *meatballs);
First two will print array element at index i
, and last will print first element. I recommend using the meatballs[i]
in most cases, as it's most clear.
References to C standard (draft):
- N1570, 6.2.5 paragraph 28
A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.48)... ...Pointers to other types need not have the same representation or alignment requirements.
- N1570, 7.21.6 paragraph 8
p The argument shall be a pointer to void. ...
- N1570, 7.21.6 paragraph 9
... If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.