To make a pointer to a whole array we proceed like that:
int arr[3] = {1,2,3};
int (*p)[3] = &arr;
How come i get an incompatibility error when trying to do the same with a 2D array?
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3] = &arr;
The problem here is &.
I'm sure this is a simple question that might have already been answered but i don't find any answer to this specific issue concerning the use of &.
CodePudding user response:
In C, "pointer" is a category of types. To get a particular type, you have to specify what type of object the pointer points to.
Accordingly, the unary &
does not generically compute a pointer. It creates a pointer to the type of its operand.
Similarly, in C, "array" is a category of types. To get a particular type, you have to specify the element type, the number of dimensions, and the sizes of at least the last n-1 dimensions.
Thus, with
int arr[3] = {1,2,3}; int (*p)[3] = &arr;
arr
is defined as an array of 3int
, therefore&arr
has type pointer to array of 3int
(spelledint (*)[3]
as a C type name), andp
is declared with that type
so everything is consistent.
How come i get an incompatibility error when trying to do the same with a 2D array?
Because your "the same" is not analogous.
With
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}}; int (*p)[3] = &arr;
, arr
has type array of 3 array of 3 int
, and &arr
has type pointer to array of 3 array of three int
(a.k.a. int (*)[3][3]
). This is not the same type that p
has. The appropriate declaration of p
for this version of arr
would be
int (*p)[3][3] = &arr;
CodePudding user response:
You've got p
in the second example as a pointer to a 1D array, not a pointer to a 2D array. For that, you need the following:
int (*p)[3][3] = &arr;
CodePudding user response:
arr
has type int [3][3]
, so &arr
has type int (*)[3][3]
. So you can use:
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3][3] = &arr;
You can then access p
as (*p)[i][j]
.
But it would be more typical to use:
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3] = arr;
In this case, int [3][3]
is compatible with an int (*)[3]
pointer, and you can use p[i][j]
when accessing it.
An analogous situation exists with one-dimensional arrays. If you have int x[3]
, then the usual pointer type to use is int *p
, in which case you would do p = x
and access it as p[i]
.
But if you really want the extra level of indirection, you could use:
int (*p)[3] = &x;
Then instead of p[i]
, you would now need to use (*p)[i]
when accessing it.