C语言 以下是 2D 数组吗?



我想使用指针动态分配 2D 数组。

int *arr = (int *)malloc(rows * cols * sizeof(int));

这有效,但这个单指针数组在技术上是 2D 数组吗?

谢谢!

从技术上讲,它只是一个 1D 数组。但它可以通过基于行主要排序计算索引来用作 2D 数组:

int index = row * cols + col;
int val = arr[index];

这就是声明 2D 数组时幕后发生的事情:

int arr[rows][cols]
int val = arr[row][col];

以下是 2D 数组吗?

int *arr = (int *)malloc(rows * cols * sizeof(int));

不。arr是一个指针。 该指针使用适合存储 2D 数组的内存地址进行初始化。


我想使用指针动态分配 2D 数组。

这取决于"2D"的类型

"2D 阵列"的概念经常被松散地使用。 让我们探讨一些可能的解释。

若要分配指向 2D 数组的指针,请使用以下命令。如果rows,cols是常量或代码为 C99,或具有可变长度数组的 C11:

int (*arr_true)[rows][cols] = malloc(sizeof *arr_true);
(*arr_true)[0][0] = this;
(*arr_true)[0][1] = that;
// etc.

为宽度cols2D 数组分配内存。 如果cols是常量或代码是 C99,或者具有可变长度数组的 C11:

int *arr_mem[cols] = malloc(sizeof *arr_mem * rows);
arr_mem[0][0] = this;
arr_mem[0][1] = that;
// etc.

为包含row*cols元素的数组分配内存。

int *arr_flat = malloc(sizeof *arr_flat *rows * cols);
arr_flat[0 *cols + 0] = this;
arr_flat[0 *cols + 1] = that;
// etc.

将指针数组分配给int指针

int *arr_classic = malloc(sizeof *arr_classic *rows);
for (size_t r = 0; r<rows; r++) {
arr_classic[r] = malloc(sizeof *arr_classic[r] *cols);
}
arr_classic[0][0] = this;
arr_classic[0][1] = this;
// etc.

尺寸计算的改进思路。

考虑用于计算大小的数学。 如果rows,colsintrows * cols可能会溢出int范围,导致未定义的行为。 使用size_t完成的相同计算可能不会在数学上溢出,应首选。

最后,malloc(size_t sz)期待一个size_t

int *arrA = malloc(rows * cols * sizeof(int)); // possible int*int overflow
int *arrB = malloc(sizeof(int) * rows * cols); // preferred
int *arr = (int *)malloc(rows * cols * sizeof(int));

arr是指向具有rows * cols * sizeof(int)分配字节的内存位置的指针。
对于语言来说,您将内存位置解释为什么并不重要,这取决于您。 一维数组、二维数组、字符串等在C语义中,它可能是一个1D数组,但这仍然不是全部事实,因为由您来解释和管理您认为合适的内存。

不,指针从来都不是数组。请参阅 comp.lang.c FAQ 的第 6 节。

您可以使用此技术分配内存块,然后可以将其视为二维数组,指针arr指向其初始元素。 一种更简单更好的编写方法是:

int *arr = malloc(rows * cols * sizeof (*arr));

这将分配一个rows*colsint元素的一维数组。不能使用arr[i][j]表示法为其编制索引;您需要自己计算索引:arr[i * rows + j].

如果要分配一个动态二维数组(或者更准确地说,是一个类似于一个的数据结构(,则需要创建一个int**指针数组,并初始化每个元素以指向新分配的int元素数组。(然后你需要清理它,你完成了它。 例如:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
int cols = 20;
int rows = 10;
// Allocate memory for an array of pointers to rows
int **arr_2d = malloc(rows * sizeof *arr_2d);
if (arr_2d == NULL) {
abort(); // horribly crude error handling
}
// Allocate memory for each row
for (int row = 0; row < rows; row ++) {
int *arr_1d = malloc(cols * sizeof *arr_1d);
if (arr_1d == NULL) {
abort(); // horribly crude error handling
}
arr_2d[row] = arr_1d;
}
// Assign data 
for (int row = 0; row < rows; row ++) {
for (int col = 0; col < cols; col ++) {
arr_2d[row][col] = row*col;
}
}
// Dump data
for (int row = 0; row < rows; row ++) {
printf("Row %2d:", row);
for (int col = 0; col < cols; col ++) {
printf(" %3d", arr_2d[row][col]);
}
putchar('n');
}
// Deallocate each row
for (int row = 0; row < rows; row ++) {
free(arr_2d[row]);
}
// Deallocate the array of row pointers
free(arr_2d);
}

相关内容

  • 没有找到相关文章

最新更新