C 返回VLA和用法

C 返回VLA和用法,c,function,return,malloc,variable-length-array,C,Function,Return,Malloc,Variable Length Array,我有以下功能: int* create_matrix_2(int rows, int cols) { double (*A)[rows][cols] = malloc(sizeof(int[rows][cols])); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { *A[row][col] =

我有以下功能:

int* create_matrix_2(int rows, int cols)
{
    double (*A)[rows][cols] = malloc(sizeof(int[rows][cols]));

    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < cols; col++)
        {
            *A[row][col] = row * cols + col;
        }
    }

    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < cols; col++)
        {
            printf("%lf, " , *A[row][col]);
        }
        printf("\n");
    }
    return A;
}
编辑#1:

我尝试使用alk建议的代码,但在编译时它给了我很多错误。下面是一个单独的程序,其中包含您建议的代码和一个主函数: 我得到以下错误:

2d\u数组\u测试\u新建.c:在函数“main”中:
2d_array_test_new.c:18:2:警告:从不兼容的指针类型传递“create_matrix”的参数3[默认情况下已启用]
如果(-1==创建_矩阵(高度、宽度和矩阵))
^
2d_array_test_new.c:10:5:注意:应为“int**”,但参数的类型为“int(**)[(sizetype)(height)][(sizetype)(width)]”
int创建矩阵(大小,大小,int**);
^
2d_阵列_测试_新建。c:顶层:
2d_数组_测试_新建。c:37:5:错误:“创建矩阵”的类型冲突
int创建矩阵(行大小,列大小,int(**a)[rows][cols])
^
2d_array_test_new.c:10:5:注意:前面的“create_matrix”声明在这里
int创建矩阵(大小,大小,int**);
^
2d_array_test_new.c:在函数“create_matrix”中:
2d_array_test_new.c:45:11:错误:“EINVAL”未声明(首次在此函数中使用)
errno=EINVAL;
^
2d_array_test_new.c:45:11:注意:每个未声明的标识符对于它出现在其中的每个函数只报告一次
2d_array_test_new.c:40:6:警告:变量“errno”已设置但未使用[-Wunused但已设置变量]
int errno;
^
错误似乎主要与返回类型有关。如何正确写入该数组的类型?

  • 参考第一条警告:

    这里

    int(*matrix2)[height][width]
    int*
    根本不一样

  • 参考第二条警告:

    这取决于定义

    double (*A)[rows][cols] = malloc(sizeof(int[rows][cols]));
    
    int*create_matrix_2()
    返回
    A

    int*
    double(*A)[rows][cols]
    也不一样

我建议您这样更改功能:

int (*matrix2)[height][width] = create_matrix_2(height, width);

for (int row = 0; row < height; row++)
{
    for (int col = 0; col < width; col++)
    {
        printf("%d" , (*matrix2)[row][col]);
    }
    printf("\n");
}
#include <errno.h> /* for errno and EINVAL */
#include <stdlib.h> /* for malloc() */


int create_matrix_2(size_t rows, size_t cols, int(**a)[rows][cols])
{
  int result = 0;

  if (NULL == a)
  {
    result = -1;
    errno = EINVAL;
  }
  else
  {
    (*a) = malloc(sizeof **a);
    if (NULL == (*a))
    {
      result = -1;
    }
    else
    {
      for (size_t row = 0; row < rows; row++)
      {
        for (size_t col = 0; col < cols; col++)
        {
          (**a)[row][col] = row * cols + col;
        }
      }

      for (size_t row = 0; row < rows; row++)
      {
        for (size_t col = 0; col < cols; col++)
        {
          printf("%d, " , (**a)[row][col]);
        }

        printf("\n");
      }
    }
  }

  return result;
}
#include <stdlib.h>
#include <stdio.h>  


int create_matrix_2(size_t rows, size_t cols, int(**a)[rows][cols]);


int main(void)
{
  int result = EXIT_SUCCESS;

  int (*matrix2)[height][width] = NULL;
  if (-1 == create_matrix_2(height, width, &matrix2))
  {
    perror("create_matrix_2() failed");
    result = EXIT_FAILURE;
  }
  else
  {
    for (size_t row = 0; row < height; row++)
    {
      for (size_t col = 0; col < width; col++)
      {
        printf("%d, " , (*matrix2)[row][col]);
      }

      printf("\n");
    }

    free(matrix2);
  }

  return result;
}
double (*create_matrix_2(int rows, int cols))[rows][cols]   // wont compile
#包括/*用于errno和EINVAL*/
#包括/*用于malloc()*/
int创建矩阵2(行大小,列大小,int(**a)[rows][cols])
{
int结果=0;
如果(NULL==a)
{
结果=-1;
errno=EINVAL;
}
其他的
{
(*a)=malloc(sizeof**a);
如果(空==(*a))
{
结果=-1;
}
其他的
{
对于(行大小=0;行<行;行++)
{
对于(大小\u t col=0;col
这样称呼它:

int (*matrix2)[height][width] = create_matrix_2(height, width);

for (int row = 0; row < height; row++)
{
    for (int col = 0; col < width; col++)
    {
        printf("%d" , (*matrix2)[row][col]);
    }
    printf("\n");
}
#include <errno.h> /* for errno and EINVAL */
#include <stdlib.h> /* for malloc() */


int create_matrix_2(size_t rows, size_t cols, int(**a)[rows][cols])
{
  int result = 0;

  if (NULL == a)
  {
    result = -1;
    errno = EINVAL;
  }
  else
  {
    (*a) = malloc(sizeof **a);
    if (NULL == (*a))
    {
      result = -1;
    }
    else
    {
      for (size_t row = 0; row < rows; row++)
      {
        for (size_t col = 0; col < cols; col++)
        {
          (**a)[row][col] = row * cols + col;
        }
      }

      for (size_t row = 0; row < rows; row++)
      {
        for (size_t col = 0; col < cols; col++)
        {
          printf("%d, " , (**a)[row][col]);
        }

        printf("\n");
      }
    }
  }

  return result;
}
#include <stdlib.h>
#include <stdio.h>  


int create_matrix_2(size_t rows, size_t cols, int(**a)[rows][cols]);


int main(void)
{
  int result = EXIT_SUCCESS;

  int (*matrix2)[height][width] = NULL;
  if (-1 == create_matrix_2(height, width, &matrix2))
  {
    perror("create_matrix_2() failed");
    result = EXIT_FAILURE;
  }
  else
  {
    for (size_t row = 0; row < height; row++)
    {
      for (size_t col = 0; col < width; col++)
      {
        printf("%d, " , (*matrix2)[row][col]);
      }

      printf("\n");
    }

    free(matrix2);
  }

  return result;
}
double (*create_matrix_2(int rows, int cols))[rows][cols]   // wont compile
#包括
#包括
int创建矩阵2(行大小,列大小,int(**a)[rows][cols]);
内部主(空)
{
int结果=退出成功;
int(*matrix2)[高度][宽度]=NULL;
如果(-1==创建矩阵(高度、宽度和矩阵2))
{
perror(“创建矩阵2()失败”);
结果=退出故障;
}
其他的
{
用于(行大小=0;行<高度;行++)
{
用于(大小\u t列=0;列<宽度;列++)
{
printf(“%d,”,(*matrix2)[行][col]);
}
printf(“\n”);
}
免费(2);
}
返回结果;
}
示例

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

void * create_matrix_2(int rows, int cols){
    int (*A)[rows][cols] = malloc(sizeof(int[rows][cols]));

    for (int row = 0; row < rows; row++){
        for (int col = 0; col < cols; col++){
            (*A)[row][col] = row * cols + col;
        }
    }

    for (int row = 0; row < rows; row++){
        for (int col = 0; col < cols; col++){
            printf("%d, " , (*A)[row][col]);
        }
        printf("\n");
    }
    return A;
}

int main(void){
    int width = 5, height = 3;
    int (*matrix2)[height][width] = create_matrix_2(height, width);

    for (int row = 0; row < height; row++){
        for (int col = 0; col < width; col++){
            printf("%d " , (*matrix2)[row][col]);
        }
        printf("\n");
    }
    free(matrix2);
    return 0;
}
#包括
#包括
void*创建矩阵(整数行,整数列){
int(*A)[rows][cols]=malloc(sizeof(int[rows][cols]);
对于(int row=0;row
简而言之,你不能

问题是从函数返回的类型必须在编译时修复,并且不能依赖于其参数的数值(在运行时提供)

但是,您可以做的是更改
create_matrix2()
以返回一个空指针。在C语言中,(几乎)任何指针都可以隐式转换为
void
指针,反之亦然

   void *create_matrix2(int rows, int columns)
   {
       /* as you've implemented it, except that A should be int not double */
   }

   int main()
   {
        int rows = 2, cols = 3;
        int (*m)[rows][cols] = create_matrix2(rows, cols);

         /*  use *m as a pointer to an array with 2 rows and 3 cols */
   }
然后,它传递出你所追求的幻觉

这种情况的危险性——也是我刚才使用“错觉”一词的原因——是与
void
指针之间的转换阻止了编译器进行类型检查。因此,这将绕过编译器,但由于从数组末尾脱落,会导致未定义的行为

   int main()
   {
        int rows = 2, cols = 3;
        int (*m)[rows][cols] = create_matrix2(rows-1, cols-1);   /*  whoops - deliberate typos here */

         /*  use *m as a pointer to an array with 2 rows and 3 cols */
   }

因为这有效地告诉编译器将动态分配的数组视为比函数中实际分配的行和列更多。

首先,代码存在一些问题。有一个双数组指针指向一个int的2D数组,这没有任何意义

另外,由于
A
是指向二维数组的指针,因此不能执行
*A[row][col]
。因为[]的优先级高于*,所以代码等价于
*(A[row][col])
。这意味着“给我2D矩阵的行数,然后…”。代码最终将远远超出界限

声明指向动态分配的多维数组的数组指针时的技巧是省略最内部的维度。这样,您就可以像使用常规多维数组一样使用语法

double (*A)[cols] = malloc(sizeof(double[rows][cols]));
...
A[x][y] = ...;
A[x][y]
将表示“在我的数组A中,其中每个项都是大小列的数组,访问数组编号x,然后在该数组中索引y”