C中每行具有不同大小的二维数组
2D array with different size for each line in C
我想知道是否可以在 C 中创建具有不同线条大小的二维数组。
我知道二维数组是存储其他数组的数组。但是如果数组大小不同怎么办?
像这样(一个"T"是数组可用的位置)
0 1 2 3 4
0 T T
1 T T T T T
2 T T T
3 T T T T
如果可以,怎么做?就像普通的二维数组一样?
我猜你指的是指向指针的指针。 (以后请尽量使用合适的标签标识,点击标签即可查看)
但是是的!没有什么能阻止你做:
int **pointerToPointers = malloc(length*sizeof(int *));
pointerToPointers[xUnderLength] = malloc(arbitaryLength*sizeof(int));
当然你可以创建这样的结构,但你必须determine/save
每行的列数。例如
size_t cols_per_row [] = { 2, 5, 3, 4 };
int **arr2d = calloc(sizeof cols_per_row / sizeof *cols_per_row, sizeof *arr2d);
for(size_t i = 0; i < sizeof cols_per_row / sizeof *cols_per_row; ++i)
arr2d[i] = calloc(cols_per_row[i], sizeof *arr2d[i]);
我省略了 when calloc
returns NULL
的错误检查,以便在更少的行中演示原理。
请注意,我使用 calloc
而不是 malloc
,因为 calloc
将内存设置为 0,这有利于初始化。
IMO 最好的解决方案确实是制作以下类型结构的数组:
struct arbitrary_len_arr {
int len;
int* arr;
};
这个实现的美妙之处在于,一旦你让你的二维数组使用这些结构作为每一行的指针,你就可以更新你的 arr 指针以指向你想要的任何数组长度,只要你更新它的 len
成员。所以你会做的是:
struct arbitrary_len_arr* my_arr = malloc(sizeof(struct arbitrary_len_arr) * N);
其中 N
是您想要的行数。然后,当您填充它们时,您还必须相应地填充成员,如下所示:
my_arr[i].len = M;
my_arr[i].arr = malloc(sizeof(int) * M;
可能在某个循环中。然后你将拥有任意长度的数组。
不同大小的数组的数组在 C 中是可能的。简单地说,它们不是二维数组,而是数组或指针。您将从 C 标签常见问题解答中找到更多关于 的区别。
@vahero 展示了如何动态分配它,但也可以使用静态或自动存储:
char row0[] = "TT"; // size 3 because of the terminating null...
char row1[] = "TTTTT";
char row2[] = "TTT";
char row3[] = "TTTT";
char* array[] = { row0, row1, row2, row3};
或者没有额外的变量标识符:
char *arr[] = {
(char[]){ 'T', 'T', 0 },
(char[]){ 'T', 'T', 'T', 'T', 'T', 0 },
(char[]){ 'T', 'T', 'T', 0 },
(char[]){ 'T', 'T', 'T', 'T', 0 },
};
然后您可以照常使用:
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) {
for(int j=0; arr[i][j] != '[=12=]'; j++) {
printf("%c ", arr[i][j]);
}
printf("\n");
}
如果您的意思是您可以声明一个维度具有可变大小的元素,那么答案是否定的。 C 不支持动态调整大小的结构,因此如果不缩放最大元素的 space,就不能将它们分配到数组中。但是,方法和手段是有的。你可以分配一个 space 的块,只使用你需要的,效率不高。您可以使用联合来拥有各种类型但大小固定的元素。最主要的是你在 C 中有一个固定的步幅值,所以元素都需要符合这个步幅值。也就是说,如果数据要进入数组结构。
上述解决方案提出了另一种解决方案,即您的结构存储指向存储在别处的数据的指针。在我看来,这不是您要问的,但这是解决问题的方法。您可以存储指向按需分配的数据元素的链接。然后,数组更像是一个索引而不是存储结构。我通常在 MISRA 等非动态分配环境中操作。如果我说某些东西必须是 "in" 数组,我会假设您指的是该对象定义的内存中的所有数据。所以答案是否定的,如果你愿意让数据被索引......嗯是的......如果你很高兴浪费了 space,再一次,是的......但不是打包变量C 数组对象中的大小数据元素。
我想知道是否可以在 C 中创建具有不同线条大小的二维数组。
我知道二维数组是存储其他数组的数组。但是如果数组大小不同怎么办? 像这样(一个"T"是数组可用的位置)
0 1 2 3 4
0 T T
1 T T T T T
2 T T T
3 T T T T
如果可以,怎么做?就像普通的二维数组一样?
我猜你指的是指向指针的指针。 (以后请尽量使用合适的标签标识,点击标签即可查看)
但是是的!没有什么能阻止你做:
int **pointerToPointers = malloc(length*sizeof(int *));
pointerToPointers[xUnderLength] = malloc(arbitaryLength*sizeof(int));
当然你可以创建这样的结构,但你必须determine/save 每行的列数。例如
size_t cols_per_row [] = { 2, 5, 3, 4 };
int **arr2d = calloc(sizeof cols_per_row / sizeof *cols_per_row, sizeof *arr2d);
for(size_t i = 0; i < sizeof cols_per_row / sizeof *cols_per_row; ++i)
arr2d[i] = calloc(cols_per_row[i], sizeof *arr2d[i]);
我省略了 when calloc
returns NULL
的错误检查,以便在更少的行中演示原理。
请注意,我使用 calloc
而不是 malloc
,因为 calloc
将内存设置为 0,这有利于初始化。
IMO 最好的解决方案确实是制作以下类型结构的数组:
struct arbitrary_len_arr {
int len;
int* arr;
};
这个实现的美妙之处在于,一旦你让你的二维数组使用这些结构作为每一行的指针,你就可以更新你的 arr 指针以指向你想要的任何数组长度,只要你更新它的 len
成员。所以你会做的是:
struct arbitrary_len_arr* my_arr = malloc(sizeof(struct arbitrary_len_arr) * N);
其中 N
是您想要的行数。然后,当您填充它们时,您还必须相应地填充成员,如下所示:
my_arr[i].len = M;
my_arr[i].arr = malloc(sizeof(int) * M;
可能在某个循环中。然后你将拥有任意长度的数组。
不同大小的数组的数组在 C 中是可能的。简单地说,它们不是二维数组,而是数组或指针。您将从 C 标签常见问题解答中找到更多关于
@vahero 展示了如何动态分配它,但也可以使用静态或自动存储:
char row0[] = "TT"; // size 3 because of the terminating null...
char row1[] = "TTTTT";
char row2[] = "TTT";
char row3[] = "TTTT";
char* array[] = { row0, row1, row2, row3};
或者没有额外的变量标识符:
char *arr[] = {
(char[]){ 'T', 'T', 0 },
(char[]){ 'T', 'T', 'T', 'T', 'T', 0 },
(char[]){ 'T', 'T', 'T', 0 },
(char[]){ 'T', 'T', 'T', 'T', 0 },
};
然后您可以照常使用:
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) {
for(int j=0; arr[i][j] != '[=12=]'; j++) {
printf("%c ", arr[i][j]);
}
printf("\n");
}
如果您的意思是您可以声明一个维度具有可变大小的元素,那么答案是否定的。 C 不支持动态调整大小的结构,因此如果不缩放最大元素的 space,就不能将它们分配到数组中。但是,方法和手段是有的。你可以分配一个 space 的块,只使用你需要的,效率不高。您可以使用联合来拥有各种类型但大小固定的元素。最主要的是你在 C 中有一个固定的步幅值,所以元素都需要符合这个步幅值。也就是说,如果数据要进入数组结构。
上述解决方案提出了另一种解决方案,即您的结构存储指向存储在别处的数据的指针。在我看来,这不是您要问的,但这是解决问题的方法。您可以存储指向按需分配的数据元素的链接。然后,数组更像是一个索引而不是存储结构。我通常在 MISRA 等非动态分配环境中操作。如果我说某些东西必须是 "in" 数组,我会假设您指的是该对象定义的内存中的所有数据。所以答案是否定的,如果你愿意让数据被索引......嗯是的......如果你很高兴浪费了 space,再一次,是的......但不是打包变量C 数组对象中的大小数据元素。