What exactly is the array name in c?

Solution 1:

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

enter image description here

Now answering your question:

  1. 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:

enter image description here

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 of sizeof 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.

Solution 2:

  1. a and &a have the same values.How?

They have the same value but different types. Array objects have no padding between elements (before or after) so the address of the array and the address of the first element of the array are the same.

That is:

(void *) a == (void *) &a
  1. 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?

These are two different pointer types. Take for example, pointer arithmetic:

a + 1   /* address of the second element of the array */
&a + 1  /* address one past the last element of the array */

EDIT: due to popular demand I added below some information about conversion of arrays.

With three exceptions, in an expression an object of type array of T is converted to a value of type pointer to T pointing to the first element of the array. The exceptions are if the object is the operand of sizeof or & unary operator or if the object is a string literal initializing an array.

For example this statement:

printf("a:%d\t&a:%d\n", a, &a);

is actually equivalent to:

printf("a:%d\t&a:%d\n", &a[0], &a);

Also please note that d conversion specifier can only be use to print a signed integer; to print a pointer value you have to use p specifier (and the argument must be void *). So to do things correctly use:

printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);

respectively:

printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);

Solution 3:

  1. a corresponds to the pointer pointing at 0th element of the array. Whereas,the same is the case with &a.It just gives the starting address of the array.

As,a --> pointer pointing to starting element of array a[],it does not know about other element's location..

&a --->address location for storing array a[] which stores first element location,but knows every element's location.

Similarly,other elements location will be (a+2),(a+4) and so upto the end of the array.

Hence,you got such result.

  1. int (*p)[3] is a pointer to the array. had it been int *p[3],it would been meant entirely different. It'd have meant an array of pointers which would have been totally different from this context.

Pointer to an array will automatically take care of all the other elements in the array.In this case,your's is (p);

Whereas,the pointer to the first element of the array,i.e., a will only know about first element of the array.You'll have to manually give pointer arithmetic directions to access next elements.See,in this case---we can get second element from a by adding 2 to a,i.e. a+2,third element by adding 4 to a,i.e., a+4 and so on. // mind the difference of two as it is an integer array!