如何将指向完整数组的指针(即int(*)[])返回给主函数

3
我的函数目的是在堆上创建一个整数二维数组。在我创建指向整个数组的指针之后,我将该指针作为 void* 类型返回。我觉得还有更好的返回类型,但我似乎无法获得正确的语法。
请让我知道是否可以使用比 void* 更好的返回类型。
void* create_matrix(int x, int y){
    int i, j, count;
    int(*matrix)[x] = calloc(y, sizeof *matrix); // a pointer to a full array of size x.
    //matrix = address of array
    //*matrix = address of first element of array; *(matrix + 1) = address of first element of second array
    //**matrix = element that exists at the first element of array; *(*(matrix + 1) + 1) = second element of second array = matrix[1][1]
    count = 0;
    for(i = 0; i < y; i++){
        for(j = 0; j < x; j++){
            matrix[i][j] = ++count;
        }
    }
    for(i = 0; i < y; i++){
        for(j = 0; j < x; j++){
            printf("%d\n", matrix[i][j]);
        }
    }
    return matrix;
}

1
完整的类型取决于 x,它根据调用方式而变化,因此您无法将其声明为类型。 - Barmar
1
Hayden Labrie,也许可以使用VLA支持编写bool create_matrix(int x, int y, int (*matrix)[y][x])函数,并要求调用者传入保存指针的位置。返回一个分配成功的标志。 - chux - Reinstate Monica
2个回答

3

如果不从函数中返回指针,而是通过引用(即传递其地址)将其传递到函数中并在那里初始化,就可以做得更好。例如:

void alloc_matrix(int x, int y, int (**pmat)[x])
{
  int (*matrix)[x] = calloc(...);
  ...;
  *pmat = matrix;
}

...
int x = 5;
int y = 6;
int (*matrix)[x]; // important, declare matrix when x is already known
alloc_matrix(x, y, &matrix);

你也可以将两个维度合并到矩阵类型中,即 int (*matrix)[x][y]。但这样你需要写成 (*matrix)[i][j] 而不是 matrix[i][j],这有点不方便。虽然名义上有一个额外的间接层级,但两种变体应该产生完全相同的机器代码。

3
你可以返回一个未指定大小的数组指针:
int (*create_matrix(int x, int y))[]
{
   ...
}

这将与指向VLA的指针兼容:

int (*a)[x]=create_matrix(x,y);

数组类型是兼容的,因为大小在两个地方都不是常量。这在C标准的第6.7.6.2p6节中有规定:
“为了使两个数组类型兼容,它们都必须具有兼容的元素类型,并且如果两个大小说明符都存在并且都是整数常量表达式,则两个大小说明符必须具有相同的常量值。如果这两个数组类型用于需要它们兼容的上下文中,则当这两个大小说明符评估为不相等的值时,其行为未定义。”

谢谢!我不知道返回一个包含整数的整个数组指针的正确语法。这正是我正在寻找的! - Hayden Labrie
@HaydenLabrie,考虑使用typeof扩展(C23中的一个功能)来使返回类型的声明更容易阅读。typeof(int[])* create_matrix(int x,int y) - tstanisl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接