I am having a tough time understanding the type and use of the name of the array in C. It might seems a long post but please bear with me.
I understand that the following statement declares a
to be of type int []
i.e array of integers.
int a[30];
While a
also points the first element of array and things like *(a+2)
are valid. Thus, making a
look like a pointer to an integer. But actually the types int []
and int*
are different; while the former is an array type and later is a pointer to an integer.
Also a variable of type int []
gets converted into a variable of type int*
when passing it to functions; as in C
arrays are passed by reference (with the exception of the sizeof
operator).
Here comes the point which makes me dangle. Have a look at the following piece of code:
int main()
{
int (*p)[3];
int a[3] = { 5, 4, 6 };
p = &a;
printf("a:%d\t&a:%d\n",a,&a);
printf("%d",*(*p + 2));
}
OUTPUT:
a:2686720 &a:2686720
6
So, how does the above code work? I have two questions:
a
and &a
have the same values. Why?int (*p)[3];
do? It declares a pointer to an array, I know this. But how is a pointer to an array different from the pointer to the first element of the array and name of the array?Can anyone clarify things up? I am having a hell of a lot of confusions.
I know that I should use %p
as a placeholder instead of using %d
for printing the value of pointer variables. As using the integer placeholder might print truncated addresses. But I just want to keep things simple.
Other answers already explained the issue. I am trying to explain it with some diagram. Hope this will help.
When you declare an array
int a[3] = {5, 4, 6}
the memory arrangement looks like
Now answering your question:
a
and&a
have the same values.How?
As you already know that a
is of array type and array name a
becomes a pointer to first element of array a
(after decay),i.e it points to the address 0x100
. Note that 0x100
also is the starting address of the memory block (array a
). And you should know that, in general, the address of the first byte is said to be the address of the variable. That is, if a variable is of 100 bytes, then its address is equal to the address of its first byte.
&a
is address of the entire memory block, i.e it is an address of array a
. See the diagram:
Now you can understand why a
and &a
both have same address value although both are of different type.
What exactly it does
int (*p)[3];
Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
See the above figure, it is explained clearly how pointer to an array is different from the pointer to an array element.
When you assign &a
to p
, then p
points to the entire array having starting address 0x100
.
NOTE: Regarding to the line
... as in
C
arrays are passed by references (with exception ofsizeof
function).
In C, arguments are passed by value. No pass by reference in C. When an ordinary variable is passed to a function, its value is copied; any changes to corresponding parameter do not affect the variable.
Arrays are also passed by value, but difference is that the array name decays to pointer to first element and this pointer assigned to the parameter (here, pointer value is copied) of the function; the array itself isn't copied.
In contrast to ordinary variable, an array used as an argument is not protected against any change, since no copy is made of the array itself, instead copy of pointer to first element is made.
You should also note that sizeof
is not a function and array name does not act as an argument in this case. sizeof
is an operator and array name serves as an operand. Same holds true when array name is an operand of the unary &
operator.