1

Output:

a=1606416992, &a=1606416992,
*a=1, &(*a)=1606416992

Program:

#include "stdio.h"
main()
{
    int a[4]={1,2,3,4};
    printf("a=%u, &a=%u, *a=%d, &(*a)=%u\n",a,&a,*a,&(*a));
}

I know array name is the pointer to first element of the array. But my doubt is pointer should be stored somewhere and it should have an address location. If so how come at location "1606416992" element "1" is stored and same "1606416992" is the address location of pointer to array?

Please help to clarify.

Batuhan Coşkun
  • 2,961
  • 2
  • 31
  • 48
A.J
  • 725
  • 10
  • 33
  • Not really a stack overflow question, more a tutorial site question. But arrays are not really pointers. The syntax sort-of pretends that they are though. `a` gives you a pointer to the stack memory which it occupies. – Dave Oct 13 '13 at 10:34
  • if 'a' gives me a pointer to the stack memory... how come address of 'a'(&a) and first address of stack memory (&(*a)) are same? – A.J Oct 13 '13 at 10:43
  • because `&a` is, in truth, nonsensical. The elements of the array are on the stack, and the address of those elements is all that's known. Contrast that with a normal pointer, where the elements are on the heap or stack, and there is an actual variable which has a value which points to those elements. In the latter case, you can get the address of that variable, but with arrays, that variable does not exist. It was a language choice, therefore, that `&a` would have the same meaning as `a` (I'm not sure why. Maybe there are some subtle differences in meaning) – Dave Oct 13 '13 at 10:48
  • actually, thinking about it, I guess the choice was made to keep consistency. Consider `int a;` vs `int a[1];`: it would be weird to be able to take a pointer to one but not the other. – Dave Oct 13 '13 at 10:50
  • @Dave; `&a` and `a` doesn't have same meaning. – haccks Oct 13 '13 at 10:54
  • @haccks unless you're using code like `&(&a)[1]` (or using `sizeof`, for the same reason), they do. The only difference is what the size of the pointed-to variable is reported as. – Dave Oct 13 '13 at 11:20

3 Answers3

5

An array name decays into a pointer to the first element when used in an expression. However, there are 3 exceptions to this rule:

  • The array appears as the operand of sizeof();
  • The array's address is taken with the & operator;
  • The array is a string or wide-string literal initializer.

In your code, both a and &(*a) are the same thing, since *a is equivalent to a[0], thus, &(*a) is the same address as a.

&a has the same address as a because with &, the array does not decay into a pointer. Therefore, &a denotes the address of the array, namely, the address where the first element can be found. With &a, you're not taking the address of pointer to first element, you're taking the address of the array, since a is not a pointer to first element in that special case.

EDIT As mentioned in other answers, you should use %p to print pointer values, after casting to void *:

printf("a=%p, &a=%p, *a=%d, &(*a)=%p\n",(void *) a, (void *) &a,*a,(void *) &(*a));
Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
1

Array name is array not pointer but decays to pointer when passes to a function as argument (excluding some exception).

When a passed to printf then it decays pointer to its first element. &a is the address of entire array a. Since each variable occupies one or more bytes of memory: the address of the first byte is said to be the address of the variable, address of array is the starting address of stack memory which is also the address of first element of a.

Passing &(*a) is similar to passing a (dereferencing a and again referencing it).
Also it should be noted here that %u expects unsigned int. To print value of pointer use %p and casting will be needed.

printf("a=%u, &a=%u, *a=%d, &(*a)=%u\n", (void *)*a, (void *)&a,*a, (void *)&(*a));
haccks
  • 104,019
  • 25
  • 176
  • 264
1

Output of a and &a holds same value. But, they are different by type.

a reference to a has type 'pointer to type' but for &a it is 'pointer-to-array-of-n-type' where n is the size of the array.

Lets try to understand the same in the below code:

#include <stdio.h>

int main()
{

   int a[4]={1,2,3,4};

   int *ptr1=a;

   int (*ptr2)[4]=&a;

   printf("a points to first element of array :%p\n",(void*)a);
   printf("&a points to whole array. Start address is same as 'a': %p\n",(void*)&a);
   printf("Incrementing 'a' steps to the next element in array New Value: %p\n",(void*)(a+1));
   printf("Incrementing '&a' steps over the entire array. New Value: %p\n",(void*)(&a+1));

   printf("ptr1: %p, ptr2:%p\n",(void*)ptr1,(void*)ptr2);

   return 0;
}

Output:

a points to first element of array :0x7fff3da3d560
&a points to whole array. Start address is same as 'a': 0x7fff3da3d560
Incrementing 'a' steps to the next element in array New Value: 0x7fff3da3d564
Incrementing '&a' steps over the entire array. New Value: 0x7fff3da3d570
ptr1: 0x7fff3da3d560, ptr2:0x7fff3da3d560

ptr1 is of type: pointer to an integer. In this program, defined as pointer to array name. Hence, holds address of array's first element. ptr1 = &a[0]

ptr2 is of type: pointer to array of 4 ints. In this program, defined as pointer to the whole array. Incrementing ptr2 leads it to step over entire array. Generally useful only when operating with array of arrays.

Visualize storage of array a :

+-----------------+-----------------+-----------------+-----------------+
|        1        |        2        |        3        |        4        |
+-----------------+-----------------+-----------------+-----------------+
0x7fff3da3d560    0x7fff3da3d564    0x7fff3da3d568    0x7fff3da3d56c    0x7fff3da3d570
▲ ▲   ▲      ▲    ▲        ▲                                            ▲  ▲
| |   |      |    |        |                                            |  |
|(a)  |      |    (a + 1)  |                                            |  |
|     (ptr1) |             (ptr1 + 1)                                   |  (ptr2 + 1) 
|------------|----------------------------------------------------------|
|            |                                                          | 
|            (ptr2)                                                     |
|                                                                       |
(&a) = 0x7fff3da3d560                                                   (&a + 1) = 0x7fff3da3d570
smRaj
  • 1,246
  • 1
  • 9
  • 13