1
int a[3][3]={5};
printf("&a = %u \n a = %u \n*a = %u\n&a[0][0]=%d\na[0][0]", &a, a, *a, &a[0][0], a[0][0]);

output:-

&a = 2359028
 a = 2359028
*a = 2359028
&a[0][0]=2359028
a[0][0] =5

How can these be all same? If value of a=2359028, then shouldn't *a give value at address 2359028 i.e. 5?

user229044
  • 232,980
  • 40
  • 330
  • 338
Shishir Gupta
  • 1,512
  • 2
  • 17
  • 32
  • 1
    Don't print addresses with `%u`, pointers and integers may have different width. Use `%p` instead. – Jens Gustedt May 09 '13 at 15:34
  • @JensGustedt ... and don't forget to convert them to `void *` before printing them using `%p`. – autistic May 09 '13 at 16:04
  • sick of multidimensional arrays? do your self a favour and use simulated row major or column major order single dimension arrays with a getter and setter for easy operation. see [here](http://en.wikipedia.org/wiki/Row-major_order) for the lo down better yet, use [boost implementation](http://www.boost.org/doc/libs/1_53_0/libs/multi_array/doc/user.html) – ldgorman May 09 '13 at 15:42

3 Answers3

5
  1. &a gives you the address of the array. It's of type int (*)[3][3]. Easy.

  2. a denotes the array itself and will undergo array-to-pointer conversion to become a pointer to the array's first element. The array's first element is a subarray of type int[3], so we get a pointer to that subarray. This pointer is of type int (*)[3]. This has the same address as before because the first subarray is at the start of the array.

  3. With *a, the array undergoes array-to-pointer conversion again to get the same pointer to the subarray as before. This is then dereference to get the subarray itself. Then this expression which denotes the subarray also undergoes array-to-pointer conversion, giving you a pointer to its first element. The first element is of type int, so the pointer is of type int*. The address of the first element is the same as the address of the subarray it is part of, which, as we've seen, is the same address as the entire array.

  4. &a[0][0] first gets you the first element of the first subarray, then takes the address of it. This gives you exactly the same pointer as in the previous point.

Therefore, all of these pointers have the same value.

Diagrammatically:

  0,0   0,1   0,2   1,0   1,1   1,2   2,0   2,1   2,2
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ int │ int │ int │ int │ int │ int │ int │ int │ int │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

└─────────────────────────────────────────────────────┘
            &a points at the entire array

└─────────────────┘
  a gives you a pointer to the first subarray

└─────┘
  *a gives you a pointer to the element 0,0
  and so does &a[0][0]

These regions all begin at the same address, so the pointers have the same value.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
0

In C, when an array is involved in an expression (e.g. when passed to a function or in pointer arithmetic), it is implicitly converted to a pointer. Because you are passing a to printf, it is implicitly converted to a pointer to a, which is the same as &a.

You might be confused by the fact that *a looks like a double dereference relative to &a, which returned the address of the array, so *a should by this logic result in the value of a[0][0]. But it isn't so.

szx
  • 6,433
  • 6
  • 46
  • 67
0

"...shouldn't *a give value at address 2359028 i.e. 5?"

Yes and no. *a should indeed give you the object at address a. However, in your case a has type int[3][3]. This means that at this level of indirection the object at address a (if we interpret a as a pointer) is not 5 as you incorrectly believe, it is actually the entire 1D array a[0]. The type of *a is int [3] and the value stored at *a is, again, the entire 1D subarray a[0].

So, when you try to printf *a, you are actually specifying the the entire a[0] subarray as an argument. That subarray decays to pointer, which naturally points to the same location (since the entire array a and its first subarray a[0] have the same location in memory). This is why printing a and *a as pointers (as well as &a) results in the same numerical value being printed.

If you want to get access to 5 in this case, you have to do **a. Just *a is not enough.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765