如何在 C 中声明可变大小的二维数组?
Posted
技术标签:
【中文标题】如何在 C 中声明可变大小的二维数组?【英文标题】:How to declare a variable size 2D array in C? 【发布时间】:2012-03-12 00:12:14 【问题描述】:我的项目有问题。我必须制作一个可变大小的二维数组来存储一些预测错误......所以这是关于图像的。问题是我必须加载不同大小的图像,因此对于每个图像,我必须将具有相应像素数的二维数组放入一个文件中。我已经在你的问题中进行了搜索,但这不是我正在寻找的有谁能帮帮我吗?
谢谢
【问题讨论】:
【参考方案1】:如果您在函数范围内有现代 C 编译器(至少 C99),那么它很简单:
unsigned arr[n][m];
这称为可变长度数组 (VLA)。如果数组太大,可能会出现问题。因此,如果您有大图像,您可以这样做:
unsigned (*arr)[m] = malloc(sizeof(unsigned[n][m]));
以后
free(arr);
【讨论】:
请记住,上面提到的可变长度数组将被分配到堆栈上。与问题不太相关的第二件事是 C++ 0X 不支持此功能(但是,由于这是一个 C 问题,所以工作正常) @Yavar,这就是为什么我还提到了使用malloc
分配的版本。即便如此,它也是一种“可变修改类型”。而且 C++ 显然还有其他方法来处理多维数组,所以是的,这根本不相关。【参考方案2】:
如果您需要内存是连续的,您有几个选择。
您可以动态分配单个内存块,然后手动计算偏移量,如下所示:
size_t rows, cols;
...
int *arr = malloc(sizeof *arr * rows * cols);
...
arr[i * rows + j] = ...; // logically equivalent to arr[i][j]
您可以在主数组中设置第二个指针数组:
int **arrp = malloc(sizeof *arrp * rows);
...
for (i = 0; i < rows; i++)
arrp[i] = &arr[i * rows];
...
arrp[i][j] = ...;
记住你必须释放 两个 arr
和 arrp
。
如果你有一个 C99 实现,你可以设置一个指向 VLA 的指针,像这样:
int (*arrp)[cols] = (int (*)[cols]) arr;
...
arrp[i][j] = ...;
请注意,在这种情况下,您不需要为辅助数组分配任何内存,也不需要手动计算指向主数组的指针;您所要做的就是将arrp
设置为与arr
相同的位置,然后让指针运算规则完成所有工作。
如果图像不是那么大,您可以设置一个 VLA(同样,C99 或更高版本):
int arr[rows][cols];
但实际上这不是一个好主意;堆栈帧的大小通常非常有限。
【讨论】:
在您的第三种情况下,我认为分配更好,因为我在回答中给出了它。直接malloc
就行了,不用强制转换,只会混淆。【参考方案3】:
您需要动态分配内存。使用双指针逻辑。
例如:
int n=10; <<-u can change this.
int **a;
a=(int **)malloc(sizeof(*int)*n);
for (int i=0;i<n;i++)
a[i]=(int *)malloc(sizeof(int)*n);// or *(a+i)
【讨论】:
当然不是,但你可以让它表现得像一个数组 当您可以简单地使用二维数组时,为什么还要使用模拟? 嗯,这就是原生 C 语言的局限性。动态数组创建,或者说一般的内存分配是 C 语言的一个主要缺陷,让人们望而却步。它仍然是一门很好的语言,因为它赋予了原始力量。这个例子证明了你可以做一些低级的操作来达到预期的结果.. 但是你还是没有回答我的问题。 C 具有动态分配的多维数组。为什么你会模仿语言提供的功能? 恐怕你错了。我不了解 C99 标准,但 K&RC(原始版本)等旧版本不支持“int a[m][n];”之类的东西。以上是关于如何在 C 中声明可变大小的二维数组?的主要内容,如果未能解决你的问题,请参考以下文章