Just when I had relaxed thinking I have a fair understanding of pointers in the context of arrays,I have fallen face down again over this following program.I had understood how for an array arr
,arr
and &arr
are both same in magnitude,but different in type,but I fail to get a solid grip over the following program's output.I try to visualize it but succeed only partially.I would appreciate if you can give a rigorous and detailed explanation for this thing so that guys like me can be done with this confusion for good.
In the following program,I have used a "2D" array demo[][2]
.I know that demo[]
will be an array of arrays
of size 2.I also know that demo
used alone will be of type (*)[2]
.Still I am at a loss about the following :
1) Why is &demo[1]
same as demo[1]
?Isn't demo[1]
supposed to be the address of the second array?What on earth is &demo[1]
then and why is it same as address of the second array?
2) I know that the second printf()
and fourth are same,as demo[1]
is nothing else but *(demo+1)
.But I've used it so to illustrate this point.How can it be equal to the third printf()
,ie,how can demo+1 be equal to *(demo+1)? demo[1]
being the same as *(demo+1)
is well-known,but how can demo+1
be equal to *(demo+1)
? How can "something" be equal to the value at that "something"?
3) And since it just proved I am not very smart,I should stop my guessing game and ask you for a conclusive answer about what are the types for the following :
&demo[1]
demo[1]
demo+1
#include<stdio.h>
int main(void)
{
int demo[4][2]= {{13,45},{83,34},{4,8},{234,934}};
printf("%p\n",&demo[1]);
printf("%p\n",demo[1]); //Should have cast to (void*),but works still
printf("%p\n",demo+1);
printf("%p\n",*(demo+1));
}
OUTPUT:
0023FF28
0023FF28
0023FF28
0023FF28
demo[1]
is the second member of the array demo
, and is an array itself. Just like any other array, when it's not the subject of the &
or sizeof
operator, it evaluates to a pointer to its first element - that is, demo[1]
evaluates to the same thing as &demo[1][0]
, the address of the first int
in the array demo[1]
.
&demo[1]
is the address of the array demo[1]
, and because the address of an array and the address of the first member of that array are necessarily the same location, &demo[1]
is equal to &demo[1][0]
, which is equal to a bare demo[1]
. This the key insight - the first element of an array is located at the same place in memory as the array itself, just like the first member of a struct
is located at the same place in memory as the struct itself. When you print &demo[1]
and demo[1]
, you're not printing a pointer to the array and an array; you're printing a pointer to the array and a pointer to the first member of that array.
demo+1
is the address of the second member of demo
. *(demo+1)
is that member itself (it's the array demo[1]
), but because that member is an array, it evaluates to a pointer to its first member. As above, its first member is necessarily collocated with the array itself. It's not that "something" is equal to the value at "something" - because when you use an array in an expression like that, it doesn't evaluate to the array itself.
&demo[1]
is a pointer to demo[1]
, which is an array of 2 int
. So its type is int (*)[2]
.demo[1]
is an array of 2 int
. Its type is int [2]
. However, when used in an expression where it is not the subject of type &
or sizeof
operators, it will evaluate to a pointer to its first member, which is a value with type int *
.demo+1
is a pointer to demo[1]
, and its type is int (*)[2]
.