如何将具有用户决定大小的动态分配的连续二维数组传递给 C11 中的函数?

How to pass a dynamically allocated contiguous 2D array with user-decided size to a function in C11?

在我的主函数中,我分配了一个二维连续数组,其行数和列数由用户决定:

#include <stdio.h>
#include <stdlib.h>

int main() {
int d=0;

scanf("%d", &d);

int(*matrix)[d]= malloc(d*sizeof(*matrix));

}

然后我想将这个矩阵和 d 值传递给一个函数,该函数将用从 1 到 d*d 的数字填充它,然后打印它:

void fillMatrix(int d, /*matrix*/)

我应该如何将矩阵传递给函数?我对函数的其余部分本身没有问题,但我似乎无法正确传递矩阵,然后将其填充为带有线数组 [i][j] 的通用二维数组= 价值。从 CLion 告诉我的情况来看,我似乎在处理它是一个 int(*)[d] 的事实时出错了,因为它经常告诉我,当我尝试实际调用该函数时,我正在传递一个不兼容的指针。

一些我尝试过但没有奏效的事情:

#include <stdio.h>
#include <stdlib.h>

void fillMatrix(int, int*);

int main() {
    int d=0;

    scanf("%d", &d);

    int(*matrix)[d]= malloc(d*sizeof(*matrix));

    fillMatrix(d, (int *) matrix);
}

void fillMatrix(int d, int *matrix){
    int i=0, j=0, k=1;

    for(i=0;i<d;i++){
        for(j=0;j<d;j++){
            matrix[i][j]= k;
            k++;
        }
    }
}

在这里,当我尝试执行 matrix[i][j]= k; 时,出现错误“下标值不是数组、指针或向量”,将矩阵更改为 *matrix 也无济于事

#include #include

void fillMatrix(int, int*);

int main() {
    int d=0;

    scanf("%d", &d);

    int(*matrix)[d]= malloc(d*sizeof(*matrix));

    fillMatrix(d, matrix);
}

在这里,调用函数时,出现错误“不兼容的指针类型将 'int (*)[d]' 传递给 'int *' 类型的参数”

当我尝试写入 void fillMatrix(int, int[][]); 时,出现错误“数组的元素类型 'int []' 不完整”

最后,如果我这样做:

#include <stdio.h>
#include <stdlib.h>

void fillMatrix(int, int[][0]);

int main() {
    int d=0;

    scanf("%d", &d);

    int(*matrix)[d]= malloc(d*sizeof(*matrix));

    fillMatrix(d, matrix);
}

void fillMatrix(int d, int matrix[][0]){
    int i=0, j=0, k=1;

    for(i=0;i<d;i++){
        for(j=0;j<d;j++){
            matrix[i][j]= k;
            k++;
        }
    }

    for(i=0;i<d;i++){
        for(j=0;j<d;j++){
            printf("%d ", matrix[i][j]);
        }

        printf("\n");
    }
}

它不会打印正确的 k 值。

最正确的形式是这样的:

int(*matrix)[d][d] = malloc( sizeof(int[d][d]) );

很明显,我们正在声明一个指向 int 方形二维数组的指针。然而,这种形式不经常使用的原因是因为取消引用变得很麻烦:(*matrix)[i][j]。要跳过这个额外的取消引用,一个方便的技巧是从指针声明中删除一个维度(这也是您当前代码所做的):

int(*matrix)[d] = malloc( sizeof(int[d][d]) );

现在我们可以按预期做一个可读的matrix[i][j]

至于如何声明一个函数,声明为使用二维数组即可,因为这就是你想要的:

void fillMatrix (size_t size, int matrix[size][size]);

现在这会衰减为指向第一个元素的指针,这种指针的类型是什么?由于第一个元素的类型为 int [size] 并且指向它的指针为 int(*)[size],我们最终得到的类型与 main 中使用的类型完全相同,100% 兼容。

完整示例:

#include <stdio.h>
#include <stdlib.h>

void fillMatrix (size_t size, int matrix[size][size])
{
  int k=1;

  for(size_t i=0; i<size; i++)
  {
    for(size_t j=0; j<size; j++)
    {
      matrix[i][j] = k++;
    }
  }
}

void printMatrix (size_t size, int matrix[size][size])
{
  for(size_t i=0; i<size; i++)
  {
    for(size_t j=0; j<size; j++)
    {
      printf("%2.d ", matrix[i][j]);
    }
    puts("");
  }
}

int main (void)
{
  size_t size=5;
  int(*matrix)[size] = malloc( sizeof(int[size][size]) );

  fillMatrix(size, matrix);
  printMatrix(size, matrix);
  
  free(matrix);
}

进一步研究: