I am a teaching assistant of a introductory programming course, and some students made this type of error:
char name[20];
scanf(\"%s\",&name);
In your example, the array test
is a block of 50 ints
. So it looks like this:
| int | int | ... | int |
When you apply the unary &
operator to an array, you get the address of the array. Just like when you apply it to anything else, really. So &test
is a pointer that points to that block of 50 ints
:
(&test) -----------> | int | int | ... | int |
A pointer that points to an array of 50 ints has type int (*)[50]
- that's the type of &test
.
When you just use the name test
in any place where it's not the operand of either the sizeof
or unary-&
operators, it is evaluated to a pointer to its first element. So the test
that you pass to foo()
evaluates to a pointer to the test[0]
element:
(test) -----------------\
v
(&test) -----------> | int | int | ... | int |
You can see that these both are pointing to the same address - although &test
is pointing to the whole array, and test
is pointing to the first element of the array (which only shows up in the different types that those values have).
The name of an array, in most circumstances, evaluates to the address of its initial element. The two exceptions are when it is the operand of sizeof
or the unary &
.
The unary &
gives the address of its argument. The address of an array is the same as the address of its initial element, so (void*)&array == (void*)array
will always be true.
array
, when converted to a pointer to its initial element, has the type T *
. The type of &array
is T (*)[n]
, where n
is the number of elements in the array. Thus,
int* p = array; // Works; p is a pointer to array[0]
int* q = &array; // Doesn't work; &array has type int (*)[10]
int (*r)[10] = &array; // Works; r is a pointer to array
If You define an array like
char name[20];
name
is implicitly convertible to char*
, but &name
is of the type char (*)[20]
(a pointer to an array of 20 characters). The addresses are the same.
Check the address of (&name + 1)
. It differs form &name
by the sizeof(char [20])
.
I believe this is a gcc optimization. Think about it.
&test
points to the address of test
test
points to the first element of test
or &test[0]
[0]
is the same(for the most part) as *
So according to this &test
could be different than test
but gcc optimizes this away because there is no purpose of having an extra level of indirection at that point.
Actually, they are different, they don't have the same type at least.
But in C, the address of the array is the same as the address of the first element in the array that's why "they are not different", basically, they point to the same thing.