Matrix, pointers, C*

2020-04-21 08:40发布

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.

3条回答
狗以群分
2楼-- · 2020-04-21 09:00

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.

void print_matrix(int (*a)[3], int n) {

    int i, j;
    for(i = 0; i < n; i++) {
        for(j = 0; j < n; j++)
            printf("%d\t", a[i][j]);
        putchar('\n');
    }

}

If you use C99, you can pass both dimensions:

void print_matrix(int x, int y, int a[x][y]) {

    int i, j;
    for(i = 0; i < x; i++) {
        for(j = 0; j < y; j++)
            printf("%d\t", a[i][j]);
        putchar('\n');
    }

}

and call it as:

  print_matrix(3, 3, matrix);

Just to illustrate how you would access the individual "arrays":

void print_matrix(int (*a)[3], int n) {
    int i, j;
    for(i = 0; i < n; i++) {
       int *p = a+i;
        for(j = 0; j < 3; j++)
            printf("%d\t", p[j]);
        putchar('\n');
    }

}
查看更多
甜甜的少女心
3楼-- · 2020-04-21 09:04

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.

int matrix[3*3];

How to use it?

matrix[row*3+col] = 5;

How to pass it.

f(int *a,int n)
查看更多
SAY GOODBYE
4楼-- · 2020-04-21 09:05

int** is a pointer to a pointer (pointing on an int).

int[3][3], as a function argument, is converted to a pointer to an int 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 of int **a (by casting: print_matrix((int *)matrix, 3);. That's ugly but helps to understand what's going on - namely, a int[3][3] array is stored in memory exactly as a int[9] array, and if you're computing the int positions yourself, as you do, it will also work as a 1D array.

查看更多
登录 后发表回答