Reputation: 679
Before anyone closes this question because there's another related one, hear me out. I've already looked at the other question and I didn't get it. I would like to create a pointer to a multi dimensional array but I don't know how. I thought I was supposed to do it like this:
int test_arr[2][4];
int *ptr_array = test_arr;
But when I do that, I get a warning saying:
incompatible pointer types initializing 'int *' with an expression of type 'int [2][4]'
I have no idea what I'm doing wrong. Can someone help me please?
Upvotes: 1
Views: 1199
Reputation: 12669
You need to understand the basics.
[Below in post, read 1D
as 1
dimension and 2D
as 2
dimension]
First, lets take an example of pointer to 1D
array:
Take an int
type and a pointer pointing to it:
int x = 1;
int *px = &x;
The type of x is int
and the type of &x
is int *
and type of px
is int *
i.e. it can hold the address of an int
type variable. Hence the assignment is valid.
Take a 1D
int
array and a pointer pointing to it:
int arr[2] = {1,2};
int *parr = arr;
Note that the type of px
and parr
is same i.e. int *
and assigning arr
to parr
is completely valid although the arr
is a 1D
array.
This is because of the fact that, in C, an array of type converted to pointer of type that points to the initial element of the array object but there are few exceptions to this rule and one of them is when used unary &
operator.
The type of arr
is int [2]
but in the above statment (parr
declare and initialisation statement) it is converted to pointer pointing to initial element of array which is an integer i.e. arr
is converted to int *
type in the int *parr = arr;
statement. Hence, it is valid to assign arr
to parr
or to any variable of type int *
.
As, I have mentioned that there are few exceptions to the rule (array of type converted to pointer of type....) and one of the exception is when used unary &
operator. So type of &arr
will be int (*)[2]
. That means you can assign &arr
to any variable of type int (*)[2]
.
int (*parr2)[2] = &arr;
i.e. parr2
is a pointer to an array of 2
integer.
The difference between this
int *parr = arr;
and
int (*parr2)[2] = &arr;
is that parr
can hold address of any int
pointer but parr2
can hold the address of any array of 2
integers. Both are pointing to same address but their types are different.
If you understood the above mentioned things completely then read below otherwise read the above part again.
Now lets come to 2D
array.
Take a 2D
array and a pointer pointing to it:
int arr[2][2];
int (*ptr)[2] = arr;
In the above ptr
declare and initialisation statement, the type of arr
is int (*)[2]
. Why??
Recall the rule mentioned above - array of type converted to pointer of type that points to the initial element of the array object.
arr
is array of 2
1D
arrays of size 2
(2
int
elements). So, it's first element is array of 2
int
and, by rule, it will be converted to pointer to the initial element i.e. pointer to
1D
array of 2
int
which is int (*)[2]
.
Hence, you can assign arr
to a pointer variable of type int (*)[2]
.
The type of &arr
is int (*)[2][2]
, so this is also perfectly fine:
int (*ptr2)[2][2] = &arr;
So, there are two ways you can have pointer to 2D
arr
but remember that the types of ptr
and ptr2
is different. This matters, for e.g., if you add 1
to pointer ptr
it will be incremented by size of int [2]
but if you add 1
to ptr2
it will be incremented by size of int [2][2]
.
How to access the array members using pointer:
In case of 1D
array:
int arr[2] = {1,2};
int *parr = arr;
int (*parr2)[2] = &arr;
// access arr members via parr pointer
printf ("%d\n", parr[0]); // this will give value of first member of array arr
// access arr members via parr2 pointer
printf ("%d\n", (*parr2)[0]); // this will give value of first member of array arr
Similarly, in case of 2D
array:
int test_arr[2][4];
int (*ptr_array)[4] = test_arr;
int (*ptr_array2)[2][4] = &test_arr;
// access test_arr members via ptr_array pointer
printf ("%d\n", ptr_array[0][0]); // this will give value of first member of array test_arr
// access test_arr members via ptr_array2 pointer
printf ("%d\n", (*ptr_array2)[0][0]); // this will give value of first member of array test_arr
Based on above explanation, try yourself creating multidimensional array (> 2D
array) pointers and play with them.
Hope, above explanation resolves your all confusions related to pointer to a 2D
array and you understood now why compiler is giving incompatible pointer types .... warning on statement int *ptr_array = test_arr;
. It's all about type compatibility during initialisation/assignment.
Upvotes: 1
Reputation: 2420
In order to do pointer arithmetic the pointer has to know the size of what it is pointing to.
int test_arr[2][4];
is equivalent to 2 elements of type int[4]
. So whenever you add 1 to the pointer, it will jump the size of 4 integers. If you had int*
it would increment the size of a single integer only.
Like said in the comments, what you want is: int (*ptr_array)[4] = test_arr;
I know, the syntax is a little weird, but that's how you do it.
Upvotes: 2