【问题标题】:2D array with different size for each line in CC中每行具有不同大小的二维数组
【发布时间】:2018-07-12 20:34:57
【问题描述】:

我想知道是否可以在 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  

如果可能,怎么做?和普通的二维数组一样吗?

【问题讨论】:

  • 你只能用 malloc 做到这一点:你 malloc 每一行的大小不同。
  • 你的主要问题是知道每一行的大小
  • @PaulOgilvie:这里不需要动态分配。所需要的只是一个指针数组。
  • " 可以在 C 中创建一个具有不同线条大小的二维数组。" --> 否 - 不是真正的二维数组。但是有多种方法允许代码通过[][] 语法访问数据。

标签: c jagged-arrays


【解决方案1】:

在 C 中可以使用不同大小的数组。它们不是二维数组,而是数组或指针。您将在 C 标签常见问题解答中找到更多关于 answer 的区别。

@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] != '\0'; j++) {
        printf("%c ", arr[i][j]);
    }
    printf("\n");
}

【讨论】:

    【解决方案2】:

    IMO 最好的解决方案确实是制作以下类型的结构数组:

    struct arbitrary_len_arr {
        int len;
        int* arr;
    };
    

    这个实现的美妙之处在于,一旦你让你的二维数组使用这些结构作为每一行的指针,你就可以更新你的 arr 指针以指向你想要的任何数组长度,只要你更新它的@ 987654322@会员。所以你要做的是:

    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;
    

    可能在某个循环中。然后,您将拥有任意长度的数组。

    【讨论】:

      【解决方案3】:

      我认为您的意思是指向指针的指针。 (以后请尽量使用合适的标签标记,点击标签即可查看。)

      但是是的!没有什么能阻止你做:

      int **pointerToPointers = malloc(length*sizeof(int *));
      pointerToPointers[xUnderLength] = malloc(arbitaryLength*sizeof(int));
      

      【讨论】:

        【解决方案4】:

        当然你可以创建这样的结构,但你必须确定/保存 每行的列数。例如

        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]);
        

        我省略了calloc 返回NULL 时的错误检查,以便用更少的行来演示原理。

        请注意,我使用calloc 而不是malloc,因为calloc 将内存设置为0,这对初始化非常有用。

        【讨论】:

          【解决方案5】:

          如果你的意思是你可以声明一个维度有一个可变大小的元素,那么答案是否定的。 C 不支持动态大小的结构,因此如果不为最大元素缩放空间,就无法将它们分配到数组中。但是,有方法和手段。你可以分配一块空间,只使用你需要的东西,效率不高。您可以使用联合来拥有各种类型但大小固定的元素。最主要的是你在 C 中有一个固定的步幅值,所以元素都需要遵守那个步幅值。也就是说,如果数据要进入数组结构。

          上述解决方案提出了另一种解决方案,您的结构将指针存储到其他地方存储的数据。在我看来,这不是您要问的,但这是解决问题的方法。您可以存储指向按需分配的数据元素的链接。然后数组变得更像一个索引而不是存储结构。我通常在 MISRA 等非动态分配的环境中运行。如果我说某些东西必须“在”一个数组中,我会假设您的意思是该对象的已定义内存中的所有数据。所以答案是否定的,如果你愿意让数据被索引......好吧......如果你很高兴浪费空间,再次,是的......但没有打包可变大小的数据元素一个 C 数组对象。

          【讨论】:

          • "C 不支持动态大小的结构" --> 研究可变长度数组。
          猜你喜欢
          • 1970-01-01
          • 2012-07-17
          • 2014-09-02
          • 1970-01-01
          • 2021-11-17
          • 2022-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多