First of all, a[i]
is automatically translated to *(a+i)
by the compiler (see https://stackoverflow.com/a/1995156/226621 for an interesting consequence of this). So, &a[i]
is the same as &*(a+i)
, or a+i
. This means that:
&a[3]-&a[0]
is the same as
(a+3) - (a+0)
which is 3
. This also means that for p
and q
, both of which are pointers to some type T
(i.e., *p
and *q
are of type T
), and when p-q
is valid, it gives you the number of elements of type T
between p
and q
. The compiler will automatically convert the difference in values of p
and q
and divide that difference by sizeof(T)
to give you the correct number.
Therefore, when you print the individual pointer values, and then subtract those values yourself (in your head for example), you will get a number that is sizeof(T)
times "too big".
On your machine, 12 / sizeof(int) == 3
, which means that sizeof(int)
is 4.
Incidentally, to print pointer values, you should use %p
specifier:
printf("%p %p\n", (void *)&a[3], (void *)&a[0]);