c - 如何使用动态分配的任意维数组?

标签 c arrays multidimensional-array

典型的一维数组可以在声明中静态或自动分配。

enum { n=100 };
int arr1[n];

或者通过指针动态分配和访问。

int *arr1m=malloc(n*sizeof*arr1m);
int *arr1c=calloc(n, sizeof*arr1c);

这两种样式都使用相同的语法访问元素。

int i = n/2;
arr1[i] = arr1c[i] = arr1m[i] = 42;

但是当您添加第二个维度时,要实现相同的语法需要一些努力。

int arr2[n][n];
int *arr2c=calloc(n*n,sizeof*arr2c);
arr2[5][5] = arr2c[5*n+5] = 23;

如果您将其构造为 Iliffe-vector,则只能得到双括号组。 .

int **arr2l=calloc(n,sizeof*arr2l);
for (int j=0; j<n; j++)
    arr2l[j]=calloc(n,sizeof**arr2l);
 arr2[6][6] = arr2l[6][6] = 72;

但是随着维度的增加,这会变得越来越麻烦。

另一个困难是在访问元素之前检查动态数组的边界(这样您就不会接触到未正确分配的内存)。 真实 数组可以使用sizeof 运算符来确定边界,但这些动态数组都没有携带它们的大小。

我如何定义一个结构,它像数组一样具有快速、连续的布局,但使用一致的语法来访问具有索引列表的元素,该索引列表对 2D 数组和 3D 数组的作用相同;并且都是动态的,具有动态可用的大小,以便它们可以传递给函数并从函数返回?

最佳答案

不用重新造轮子,C从C99开始就有了,叫做变长数组,VLA。它只有“普通”d 维数组的语法,只是边界可能是可变的,并且它们在文件范围内是不允许的。

由于此类对象可能会变得相对较大,因此您不应在堆栈上分配它们,而应使用类似malloc

的方法
double (*A)[n][m] = malloc(sizeof(double[k][n][m]));

然后编译器会帮助您毫无问题地进行所有索引计算。如果你想将这些动物传递给函数,你只需要先小心地声明边界:

void func(size_t k, size_t n, size_t m, double A[k][n][m]);

这使人类读者和编译器都清楚您的意图。我更喜欢这个而不是等效的形式

void func(size_t k, size_t n, size_t m, double (*A)[n][m]);

关于c - 如何使用动态分配的任意维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30023867/

相关文章:

c - read(2)ing 结构时如何正确避免 "cast increases required alignment"警告?

c - 线程标志以阻止其他线程和多线程碰撞

java - 如何使用多维数组列表?

c - 使用 void 在 C 中分配和释放二维数组

c++ - inportb() 和 inport() 函数有什么区别?

c - 类似于 c 中的 dict

java - 如何从字符串数组中打印随机单词? java

java - 将多维数组作为文本传递给 Java 中的方法调用

c++ - 如何创建一个新的字符串数组

检查数组索引是数字还是字母?