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;
arris defined as an array of 3int, therefore&arrhas type pointer to array of 3int(spelledint (*)[3]as a C type name), andpis 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.
