7

我在 C++ 聊天中与某人进行了与语言无关的讨论,他说数组数组和多维数组是两件事。

但据我所知,多维数组只不过是其他数组的数组,它们都具有相同的大小。他特别说

好吧,它们有点在 C 中,您可以在其中使用嵌套数组模拟多维,但这只是因为 C 实际上不支持多维数组

有人可以解释一下“多维数组”的规范计算机科学定义是什么以及为什么 C(或抽象定义“数组数组”)不符合该定义吗?

4

5 回答 5

8

以 .NET 数组为例,它很好地说明了这一点:

C#在以嵌套方式定义的锯齿状数组之间存在区别:

int[][] jagged = new int[3][];

每个嵌套数组可以有不同的长度:

jagged[0] = new int[3];
jagged[1] = new int[4];

(请注意,其中一个嵌套数组根本没有初始化,即null。)

相比之下,多维数组定义如下:

int[,] multidim = new int[3, 4];

在这里,谈论嵌套数组是没有意义的,实际上尝试访问multidim[0]将是编译时错误——您需要提供所有维度来访问它,即multidim[0, 1].

正如上面的声明所揭示的,它们的类型也不同。

此外,它们的处理方式完全不同。例如,您可以使用 type 的对象迭代上述锯齿状数组int[]

foreach (int[] x in jagged) …

但是对多维数组的迭代是使用以下类型的项目完成的int

foreach (int x in multidim) …

从概念上讲,交错数组是数组的数组(……数组数组的数组……无限)T而多维数组是具有集合访问模式的数组T(即索引是元组)。

于 2012-06-24T13:08:01.643 回答
1

我希望多维数组能够提供诸如“给我维数”或“给我某个列”或“给我某个子视图”之类的操作。C 数组不提供这些操作。

于 2012-06-24T13:03:44.720 回答
1

来自维基百科:

多维数组

指定元素所需的索引数称为数组类型的维度、维度或等级。(此命名法与线性代数中的维度概念相冲突,[5] 它是元素的数量。因此,在计算上下文中,具有 5 行和 4 列的数字数组(即 20 个元素)被称为具有维度 2 , 但在数学中表示一个维度为 4×5 或 20 的矩阵。此外,“秩”的计算机科学含义与其在张量代数中的含义相似,但与矩阵秩的线性代数概念不同。)

许多语言只支持一维数组。在这些语言中,多维数组通常由 Iliffe 向量表示,即对少一维数组的引用的一维数组。特别地,二维数组将被实现为指向其行的指针向量。因此,数组 A 的第 i 行和第 j 列中的元素将通过双索引(典型符号中的 A[i][j])访问。这种模拟多维数组的方式允许创建参差不齐或参差不齐的数组,其中每一行可能具有不同的大小——或者,通常,每个索引的有效范围取决于所有前面索引的值。

这种多维数组的表示在 C 和 C++ 软件中非常普遍。但是,C 和 C++ 将使用线性索引公式来声明多维数组,例如通过 int A[10][20] 或 int A[m][n],而不是传统的 int **A .[6]:第 81 页

有关支持多维数组的语言示例,请参见此处

于 2012-06-24T13:08:19.640 回答
1

C 没有多维数组,但 C 有数组数组。

在标准中,使用了多维数组的措辞,C 多维数组实际上是数组的数组。来自 Kernighan & Ritchie:

“在 C 语言中,二维数组实际上是一维数组,每个元素都是一个数组。”

一些语言支持多维数组作为第一类类型。“Expert C Programming”一书展示了支持数组数组和多维数组的 Ada 示例。

于 2012-06-24T13:18:36.670 回答
1

我明白他的意思。他实际上从实现的角度来看它们有所不同,但两者实际上都可以说是多维数组。

“数组数组”类型使用线性索引,因为它实际上是作为一维数组实现的,尽管在语言级别它是通过多个索引引用的。例如,在 C 中:

int a[5][5];

实际上具有与以下相同的结构:

int a[25];

编译器将翻译如下访问:

a[i][j]

到:

a[i * jDimensionWidth + j]

其中 jDimensionWidth = 5 在上面的例子中。甚至可以像这样访问它:

int* b = (int*) a;
printf("%d\n",b[12] == a[2][2]); // should output 1

正如他所说,“多维数组”类型是通过 Iliffe 向量实现的,其中索引不能线性化,因为地址也不是线性的,因为向量通常作为堆对象实现。这种多维数组不符合方程(对于二维数组):

addr(a[i + 1]) = addr(a[i]) + (a[i].width * sizeof(a[i][j].datatype))

这是由“数组数组”类型实现的。

于 2012-06-24T13:19:47.780 回答