I have code like this:
void print_matrix(int **a, int n) {
int i, j;
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++)
printf("%d\t", *(a+i*n+j));
putchar('\n');
}
}
int main () {
int matrix[3][3];
insert (matrix); /* Function that reads Matrix from stdin */
print_matrix(matrix, 3);
return 1;
}
I receive GCC error:
expected ‘int **’ but argument is of type ‘int (*)[3]
I read all related topics but I still couldn't find answer to my question, so before you mark it as duplicate please read it.
Pointers are not Arrays, I understand that. I've read somewhere that elements are not sequential, in that case, this could happen: 111 222 333 -> 111 is address of first int array, 222 is address of second int array, and 333 is address of third int array. But if this is the case, I don't understand why GCC gives me an error.
First I would like someone to confirm me that what I've read is true. Then I would really appreciate if someone could give me answer.
Note that I understand that *(a+i*n+j)
is incorrect in case that memory for matrix is not sequential.
Best regards.
When you pass
int[3][3]
, the function receives a pointer to the(int*)[3]
which is a pointer to an array of 3 int's. Because an array gets converted into a pointer to its first element when you pass it to a function.So adjust the function accordingly. One way is to receive it as a pointer to an array. You array indexing is wrong too. You can index just like how you would index a real the array.
If you use C99, you can pass both dimensions:
and call it as:
Just to illustrate how you would access the individual "arrays":
If you want n to vary (and be square), it is best to allocate and use a single dimension array and multiply when you want a different row.
How to use it?
How to pass it.
int**
is a pointer to a pointer (pointing on an int).int[3][3]
, as a function argument, is converted to a pointer to anint
array - see Is an array name a pointer?So the types don't match, as the compiler is telling you.
Note: if you're doing pointer arithmetic in your function, you can pass
int *a
instead ofint **a
(by casting:print_matrix((int *)matrix, 3);
. That's ugly but helps to understand what's going on - namely, aint[3][3]
array is stored in memory exactly as aint[9]
array, and if you're computing theint
positions yourself, as you do, it will also work as a 1D array.