The key to understanding this is to know that arrays usually "decay" into pointers to the first element, whenever they are used in an expression. Except for some special cases. The rule of array decay and the exceptions are found in the C standard (C17 6.3.2.1/3):
Except when it is the operand of the sizeof
operator, or the unary &
operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.
As we can see, sizeof
and &
are exceptions to the rule.
This means that a
in sizeof(&a)
does not decay to a pointer. We can know this because sizeof
and unary &
are both unary operators with the same precdence, but with right-to-left operator associativity. Meaning that &a
gets interpreted first and there is no array decay when &
is used.
So we get the address of the array. In your case, the size of an int pointer of type int(*)[10]
. What size a pointer got has nothing to do with the size of an int
, but it is likely to be either 4 or 8 bytes on 32 and 64 bit systems respectively.
In case of sizeof(*a)
, then just like in the &a
case, the rigth-to-left associativity of unary operators means that *a
gets interpreted first. And so the array does decay into a pointer to the first element, before sizeof
is applied. So *a
gives the size of the first element, which is the size of an int
.
And finally in case of sizeof(a)
there is no array decay since a
is used with sizeof
and no other operator is present. Meaning we get the size of the whole array.
&a
is an address which is8
bytes if you runIA-64
(64
bit) and will be4
in case ofx86
(32
bit) – Secretin