Reputation:
Pointers and arrays are closely associated with each other, so, if we have a 2-D array
int a[3][4]={
1,2,3,4,
5,6,7,8,
9,10,11,12};
Both
printf("%p\n", a);
and
printf("%p\n", *a);
print the same address. What I understand is maybe a
is pointing to the base address of a
while *a
is pointing to the first sub-array of the two-dimensional array a
.
So, what is the difference between the two?
Upvotes: 4
Views: 294
Reputation: 123458
Given the declaration
int a[3][4];
the following are true:
Expression Type Decays to Value
---------- ---- --------- -----
a int [3][4] int (*)[4] Base address of array
&a int (*)[3][4] n/a Base address of array
*a int [4] int * Base address of first subarray
(equivalent to a[0])
a[i] int [4] int * Base address of i'th subarray
&a[i] int (*)[4] n/a Base address of i'th subarray
*a[i] int n/a Value of a[i][0]
a[i][j] int n/a Value of a[i][j]
&a[i][j] int * n/a Address of a[i][j]
The address of the first element of the array is the same as the address of the array itself, so the expressions a
, &a
, *a
, a[0]
, &a[0]
, and &a[0][0]
all yield the same value (the address of the first element of the array), but they will have different types (int (*)[3][4]
vs. int (*)[4]
vs. int *
).
Edit
Except when it is the operand of the sizeof
or unary &
operators, an expression of type "N-element array of T
" will be converted ("decay") to an expression of type "pointer to T
" and the value of the expression will be the address of the first element of the array.
So the expression *a
is equivalent to a[0]
; both expressions have type "4-element array of int
". Since they're not operands of the sizeof
or unary &
operators, those expressions "decay" to type "pointer to int
".
That's what the "Decays to" column shows.
See section 6.3.2.1 of the online C 2011 language standard.
Upvotes: 4
Reputation: 148890
a
is a 2D array of size 3x4. That means:
sizeof(a) == 3*4*sizeof(int)
a[i]
is a 1D array of size 4 (for 0<=i<3)a[i][j]
is an int ( 0<=i<3 and 0<=j<4)a
decays to &a[0]
*a
is a[0]
: it is a 1D array of size 4. That means :
sizeof(*a) == 4*sizeof(int)
(*a)[i]
is an int (0<=i<4)*a
decays to &a[0][0]
So a
and *a
are different objects that decay to pointers to the same address which is also &a
. But a
decays to a pointer to int[4]
, whereas *a
decays to a pointer to int
(thanks to undur_gongor for noticing).
Upvotes: 3
Reputation: 949
It is very simple. *a
is an array of integers. In your case *a
in nothing but the array [1,2,3,4]
. Individual elements of this array can be accessed by (*a)[i]
, where i
is the index of the required element.
And a
is pointer to this array of integers. a[0]
will give you the first array (it is same as *a
), a[1]
will give you the second array(which is [5,6,7,8]
).
For example if you want to access 5th element(which is 5
), it will a[1][0]
.
Upvotes: 0
Reputation: 15954
The difference between the pointers (that the arrays decay to) is not the address but the type.
As you have seen, both pointers point to the same address. But a
points to sub-arrays whereas *a
points to int
s.
This makes a difference, e.g. when doing address arithmetic. a + 1
is something different than *a + 1
.
Upvotes: 1
Reputation: 63124
What i get is may be a is pointing to the base address of a while *a is pointing to the first sub-array of two-dimensional array a.
That's almost it.
a
on its own decays to a pointer (of type int(*)[3]
) to its first subarray when you pass it to printf
.*a
designates a
's first subarray (of type int[3]
), and decays to a pointer (of type int*
) to the first element of that subarray.In the end, they share the same value because an array has the same address as its first element, recursively.
Upvotes: 5