Reputation: 27
In the following piece of code, I am getting the first two values of addresses same(call it x). I have run it on gcc compiler of ubuntu v18.04.4 LTS.
int a[2][2] = {0};
printf("%p %p %d\n", a, *a, **a);
This mean that:
Now, from 1. , address of *a is x (as a points to *a and is storing x) and address of the number 0 is also x (as *a points to a[0][0] which is 0 and *a is storing x). So my question is what exactly is stored at the location x? Or have I mistaken something in making the conclusions?
Upvotes: 1
Views: 98
Reputation: 223872
Your assertion that a
contains an address seems to indicate that you think a
is a pointer. It is not a pointer but an array. They are related, but they are not the same thing.
An array, in most contexts, decays to a pointer to its first member. In this case, this means that in an expression a
is the same as &a[0]
and *a
is the same as a[0]
which is the same as &a[0][0]
. This also means that the address of an array is the same as the address of its first member, which is what you're seeing when you print a
and *a
.
This would probably be better illustrated with a diagram:
----- ------- ---- ---
0x100 | 0 | a[0][0] a[0] a
----- -------
0x104 | 0 | a[0][1]
----- ------- ----
0x108 | 0 | a[1][0] a[1]
----- -------
0x10c | 0 | a[1][1]
----- ------- ---- ---
From here, you can see that a
starts at address 0x100 (x
in your example) and contains a total of 4 int
values. Also note that the subarray a[0]
has the same address as a
, as does the initial int
element a[0][0]
.
Generalizing this, the address of an array and the address of its first element, even though the types are different, are the same. So:
a
is an array whose address is 0x100. It contains element of type int[2]
.a[0]
is an array whose address is 0x100. It contains element of type int
.a[0][0]
is an int
whose address is 0x100.Upvotes: 2
Reputation: 310980
I have not understood what is the magic 'x'
.;)
You declared a two-dimensional array
int a[2][2] = {0};
Array designators used in expressions (with rare exceptions as for example using them in the sizeof operator) are implicitly converted to pointers to their first elements.
So the expression a
used in this call
printf("%p %p %d\n", a, *a, **a);
is converted to the pointer of the type int ( * )[2]
to the first element of the array. That is it is the address of the memory extent occupied by the array.
Using the indirection operator * the expression *a
yields the first element of the type int[2]
of the original array a
.
Again this array designator *a
in the call of printf is implicitly converted to pointer of the type int *
to its first element that has the type int
. This pointer will contain the same address of the memory extent occupied by the original array.
In this expression **a
there are applied two indirection operators. The first indirection operator yields the first element of the two-dimensional array that is it yields an array of the type int[2]
. This array used as an operand of the second indirection operator at once is implicitly converted to pointer to its first element that has the type int *
. The second indirection operator yields the object pointed to by the pointer that is the object of the original array a[0][0]
that is outputted by the printf call shown above. As this element was explicitly initialized by 0 then 0 is outputted as the value of the element.
To make it more clear the first indirection operator *a
is equivalent to using the subscript operator a[0]. And the second indirection operator applied to this expression *a[0]
is equivalent to the expression a[0][0]
.
Upvotes: 2