【问题标题】:How do I pass a multi-dimensional array of variable size in C?如何在 C 中传递可变大小的多维数组?
【发布时间】:2026-02-24 05:00:01
【问题描述】:

我正在尝试将一个三维数组传递给这样的函数:

void example( double*** bar ) {
    // Stuff
}

int main() {
    double[3][2][3] foo;
    // Initialize foo
    example( foo );
    return 0;
}

这会导致 gcc 给我“无效的指针类型”。我该怎么做?我可以将整个参数设为一维数组并安排我的数据以适应它,但有没有更优雅的解决方案?

编辑:

另外,我不能总是指定每个子数组的长度,因为它们的大小可能不同。例如:

int* foo[] = { { 3, 2, 1 }, { 2, 1 }, { 1 } };

如果它有帮助,我正在尝试为神经网络中的神经元批量传递输入。每个神经元都有不同数量的输入。

【问题讨论】:

  • 关于你问题的第二部分:你可以创建一个函数void example(int *bar[])并传递foo,但是正确处理bar和正确处理foo一样困难。一种简单的解决方案是在数组中包含一个“停止标记”,例如int* foo[] = { { 3, 2, 1, -1 }, { 2, 1, -1 }, { 1, -1 }, { -2 } };(但请用符号常量替换幻数!)
  • 如果每个子数组的长度不同,你如何知道它们的长度?
  • 您只需处理子数组,直到您达到 -1;无法直接获取子数组的长度,因为该信息在运行时根本不可用,C 不会将其保存在任何地方。
  • 我自己保存的。每个神经元保持它所期望的输入数量,所以我使用它。处理所有这些的函数,理论上,我只需要弄清楚如何正确地制作双***
  • 请参阅this answer of mine 了解封装尺寸并可传递给函数的结构。

标签: c arrays multidimensional-array


【解决方案1】:

只需使用double*。多维数组连续存储在内存中,因此非常欢迎您自己尝试一下。这就是位图在 OpenGL 上的传递方式。

【讨论】:

  • 我可以把它转换成函数内的多维数组吗?
  • 没有什么能阻止你。唯一的问题是您可能会失去在运行时确定各种维度的能力。进行自己的步幅计算可能是一个更好的主意。这样,x、y、z 维度的大小都可以在运行时完成。
  • 我做了很多测试,我认为这是最适合我的测试。谢谢!
【解决方案2】:

一维int 数组在传递给函数时会衰减为int 指针。多维数组衰减为指向下一个最低维数组的指针,即

void example(double (*bar)[2][3]);

这个语法可能有点莫名其妙,所以你可以选择等效的语法:

void example(double bar[][2][3]) {
    // Stuff
}

int main() {
    double foo[3][2][3];

    example(foo);
    return 0;
}

不必给出第一个维度,它是“腐烂”的那部分。 (注意数组的维数不像Java那样在类型上给出,而是在数组名上给出。)

此语法也适用于可变长度数组 (VLA),只要您在数组之前传递维度:

void example(int x, int y, double (*bar)[x][y]) {
    // Stuff
}

int main() {
    double foo[3][2][3];

    example(2, 3, foo);
    return 0;
}

此功能需要 C99 且与 C++ 不兼容。

【讨论】:

  • 这真的很丰富!不幸的是,我没有解释每个子数组也可能有不同的长度。我已经编辑了问题以包含它。
【解决方案3】:

如果数组大小是固定的,可以使用:

void example(double bar[][2][3]) {

}

否则,您可以将大小与数组一起传递给函数:

void example(size_t x, size_t y, size_t z, double bar[x][y][z]) {

}

【讨论】:

  • 这确实会强制您进入固定大小的数组
  • @doron 更新为包含可变长度数组方法。
  • 抱歉,我忘了提到一些数组在其他数组中具有不同的大小。例如:int* foo[3] = { { 3, 2, 1 } , { 2, 1 }, { 1 } }
  • @ace,可以在运行时执行此操作吗?
  • @doron 如果你指的是 OP 的初始化语句,可能不是。
【解决方案4】:

这在 C 中无法按照您的想法完成。如果您需要一个对可变大小多维数组进行操作的函数,您要么必须将大小(除一个之外的所有)显式传递给函数,要么创建一个结构并传递它。当需要 2D 或 3D 数组时,我通常总是制作一个结构,即使它们的大小是固定的。我认为这种方式更简洁,因为结构记录了自己。

【讨论】:

  • 我也一直在考虑这个问题。我可以试试这个以及一维数组,看看哪个更容易使用。