【问题标题】:create a multdimentional array to store many arrays of different sizes in C在 C 中创建一个多维数组来存储许多不同大小的数组
【发布时间】:2019-09-22 01:59:39
【问题描述】:

我问了这个问题,但我把它删除了,因为它不清楚。我有三个循环产生 0、1 个数据。我想将它们存储为一个矩阵,所以我认为它应该存储在一个多维数组中,我称之为Third

for (i = 0; i < m; i++) {
    for (int l = 0; l < n2; ++l) {
        for (x = 0; x < all[i].n; ++x) {
            f = (int)VECTOR(v2)[l];
            if (a[x].vto == f) {
                printf("%d", 1);
            } else {
                printf("%d", 0);
            }
        }
    }
    for (int y = 0; y < n1; ++y) {
        for (x = 0; x < all[i].n; ++x) {
            q = (int)VECTOR(v1)[y];
            if (a[x].vfrom == q) {
                printf("%d", 1);
            } else {
                printf("%d", 0);
            }
        }
    }
    printf("\n");  
}

之前代码的打印结果是,我想将其存储在此表单中:

100010001111
111000000111100100010010001001
111000000000111000000000111100100100010010010001001001
110000001100000011101010010101
111100010001

我的目标是将打印的结果存储在一个数组中,例如

Third = [[[100][010][001][111]] [[111000][000111][100100][010010][001001]]...[[111][100][010][001]]]

所以如果我想访问数组Third,我会访问Third[3] = [ [110000] [001100] [000011] [101010] [010101] ]Third[3][1] = [001100]Third[3][1][2] = 1

我很乐意澄清任何不清楚的地方。感谢您的帮助

编辑 1: 代码太大,无法完整添加。我询问了实现我正在寻找的一般方法,即如何构造一个多维数组或数组数组来存储来自任何三个嵌套循环(不是我的循环)的数据结果。

我修复了当前代码,所以现在数组 Third 包含所有数据,但我认为这不是存储数据以便以后以 Third[3] = [ [110000] [001100] [000011] [101010] [010101] ] 访问它的正确方法

这是我所做的:

    int second[n1 + n2][n1 * n2];
    int first[n1 * n2];
    int Third[m][n1 + n2][n1 * n2];

    for (i = 0; i < m; i++) {
        Data *a = all[i].datas;
        igraph_edge(&graph, i, &from, &to);
        igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
        igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);

        int n2 = igraph_vector_size(&v2);
        int n1 = igraph_vector_size(&v1);
        int f, q, x, l, y;

        for (l = 0; l < n2; ++l) {
            for (x = 0; x < all[i].n; ++x) {
                f = (int)VECTOR(v2)[l];
                if (a[x].vto == f) {
                    first[x] = 1;
                } else {
                    first[x] = 0;
                }
                second[l][x] = first[x];
                Third[i][l][x] = second[l][x]; 
                printf("%d", Third[i][l][x]); 
            }
       }

       for (y = 0; y < n1; ++y) {
           for (x = 0; x < all[i].n; ++x) {
               q = (int)VECTOR(v1)[y];
               if (a[x].vfrom == q) {
                   first[x] = 1;
               } else {
                   first[x] = 0;
               }
               second[y+n2][x] = first[x];
               Third[i][y+n2][x] = second[y+n2][x];
               printf("%d", Third[i][y+n2][x]); 
           }
        }
        printf("\n");  
    }

在编译之前的代码时,我得到了

100010001111
111000000111100100010010001001
111000000000111000000000111100100100010010010001001001
110000001100000011101010010101
111100010001

我不确定这是否是正确的做法?谢谢

编辑 2:

我想知道下面这样的声明是否正确?是固定大小的三维数组Third 还是(根据需要)根据n1n2 动态变化,这取决于i 的迭代。

    int second[n1 + n2][n1 * n2];
    int first[n1 * n2];
    int Third[m][n1 + n2][n1 * n2];

    for (i = 0; i < m; i++) {
        Data *a = all[i].datas;
        igraph_edge(&graph, i, &from, &to);
        igraph_neighbors(&graph, &v1, from, IGRAPH_ALL); //initialize the vector v2 where it's values and it's size vary depending on i
        igraph_neighbors(&graph, &v2, to, IGRAPH_ALL); //initialize the vector v2 where it's values and it's size vary depending on i

        int n2 = igraph_vector_size(&v2); // the size changes depending on i, i.e the change from an iteration to another
        int n1 = igraph_vector_size(&v1); // the size changes depending on i, i.e the change from an iteration to another
        int f, q, x, l, y;

        for (l = 0; l < n2; ++l) {
            for (x = 0; x < all[i].n; ++x) {
                f = (int)VECTOR(v2)[l];
                if (a[x].vto == f) {
                    first[x] = 1;
                } else {
                    first[x] = 0;
                }
                second[l][x] = first[x];
                Third[i][l][x] = second[l][x]; 
            }
        }
    }

【问题讨论】:

  • 我很乐意澄清任何不清楚的地方。请以minimal reproducible example开头。
  • 另外,它在哪里崩溃?你的调试器告诉你什么?
  • 您应该有一个能够容纳最大数组的“矩形”数组(并且浪费了空间,但通常不是问题)。或者你有一个指向数组的指针数组,然后你可以分别定义每个数组并将指针存储在指向数组的指针数组中。
  • 我不知道你在这里复制代码时缩进是否损坏,但如果你修复它会更好。
  • 我所知道的分段错误的最佳调试方法是在您怀疑可能发生的任何两行代码之间复制此行:printf("%s: %i\n", __FILE__, __LINE__); getchar();。这样,您应该可以快速找到它的断裂点。

标签: c arrays for-loop multidimensional-array segmentation-fault


【解决方案1】:

你想要这个:

Third = [ [[100][010][001][111]] [[111000][000111][100100][010010][001001]]...[[111][100][010][001]] ];

我会假设您想要的数据类型是bool,但可以是任何类型。

这在 C 中无法完全实现,因为数组的所有元素都必须属于同一类型,当我们谈论数组时,这包括它的大小。


选项 1:

但是我们有例如*argv[],它是一个指针数组,但由于指针可以像数组一样表现,我们实际上有这样的东西(遵循相同的语法):

*argv[] = [ [program\0][arg1\0][arg2\0] ] // Don't forget the ending NULL, but it's not relevant here.

类似于你想要的东西可能是:

void *third[n];

假设您将所有第二个数组定义为

bool second_0[4][3];
bool second_1[5][6];
...
bool second_n[4][3];

然后你可以像这样在third 中加入他们:

third[0] = &second_0;
third[1] = &second_1;
...
third[n] = &second_n;

您可以像这样使用third:假设您要将元素[i][j][k] 提取到一个临时变量中,假设数组second_i 的大小为second_i[n][m]

bool tmp = (*(bool (*)[n][m])third[i])[j][k];

用法不是很好,但它是您可以拥有的最接近您想要的东西。


选项 2(首选):

你可以有一个像这样的大数组:bool third[100][20][30];,它可以保存比你最大的预期第二个数组更多的数字,并将未使用的值保留为 0。它将使用更多内存,但不需要任何强制转换或指针,并且会更快,因为所有内存都是连续的。

如果你使用这个选项,你需要一个额外的变量

ptrdiff_t third_sizes[ARRAY_SIZE(third)][2];

存储每个第二个数组的大小,以便您可以跟踪您使用的部分(第一个选项您也需要它)。 ARRAY_SIZE() 应该这样定义:

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

编辑 2 的答案:

简短:不,C 中不存在动态大小的数组。这是不可能的。

当您创建一个数组并使用一个变量来确定其大小时,程序只会在创建数组时获取该变量的值,这将是固定大小。更新变量时它不会更新大小。

对于一些问题有动态大小的解决方案,例如链表(如果您需要更多信息,请在谷歌上找到),但不是数组。另一种实现动态大小数组之类的方法是将上面的“选项1”与malloc()free()混合使用,但我会尽可能避免它,因为性能和可能错误。有人说malloc() 是邪恶的。 (不是不​​使用,而是别无选择时使用)。

我仍然会选择上面的“选项 2”。

【讨论】:

  • 再次感谢。我做了类似于你的第二个选项的事情,我声明了三维数组 Third[m][n1+n2][n1*n2]。 m 是固定的,但 n1 和 n2 总是根据 m 的值而变化。我知道如何调用 Third[x][y][z] 中的值,但我仍然有如何调用数组 Third[x] 的问题!
  • @Noah16 你的数组也是固定宽度的。我给你举个例子:n = 3; int m[n]; n = 4;这些语句之后的数组大小仍然是3。
  • @Noah16 要调用数组Third[x],只需写下Third[x]。这对于将数组传递给函数(实际上是指向它们的第一个元素的指针)很有用,但请记住,您不能在 C 中分配数组。您需要逐个元素地执行所有操作,或者使用诸如 memcpy() 之类的函数。
  • 我一直将 c 与我曾经在它们上工作的 python 和 R 进行比较。谢谢
  • @Noah16 如果您在此之后仍然有任何问题,请用您所拥有的内容更新您的问题(不要覆盖您已经拥有的内容,追加它)。
猜你喜欢
  • 1970-01-01
  • 2013-06-18
  • 2017-05-18
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
相关资源
最近更新 更多