多维数组 [][] 与 [,] 的区别

514
double[][] ServicePoint = new double[10][9]; // <-- gives an error (1)
double[,] ServicePoint = new double[10,9]; // <-- ok (2)

它们之间有什么不同?(1)会产生一个错误,原因是什么?

而且

double d = new double[9]
ServicePoint[0] = d;

使用 (2) 会提示错误。为什么?


1
你的第二段代码到底是要做什么?它毫无意义。 - harold
分配一个相同大小的数组,有没有办法做到这一点? - william007
你的意思是类似于 double[,] d = new double[9,9]; 这样的吗?哦,等等,我明白你的意思了。如果你的意思是“有没有一种方法可以一次性初始化一个数组的数组”,那么不行,你不能这样做。 - harold
2
第一个样本([][])通常被称为'jagged array',但当你称其为'array of array'时,问题更容易理解。 - H H
1
记录一下: double d = new double[9]; 应该改为: double[] d = new double[9]; - Ronnie 'Madolite' Solbakken
5个回答

571

其中一个是数组的数组,另一个是二维数组。前者可以是不规则的,后者是均匀的。

也就是说,double[][] 可以有效地表示为:

double[][] x = new double[5][];

x[0] = new double[10];
x[1] = new double[5];
x[2] = new double[3];
x[3] = new double[100];
x[4] = new double[1];

因为数组中的每个条目都是对double数组的引用。使用不规则数组,您可以像第二个示例中所示一样对数组进行赋值:

x[0] = new double[13];

其次,由于它是一个统一的 2D 数组,您不能将一个 1D 数组赋值给行或列,因为您必须同时索引行和列,这会将其缩小到单个 double

double[,] ServicePoint = new double[10,9];

ServicePoint[0]... // <-- meaningless, a 2d array can't use just one index.

更新:

根据您的问题进行澄清,导致您的#1出现语法错误的原因是因为您有以下内容:

double[][] ServicePoint = new double[10][9];

在构造时不能指定第二个索引。关键是ServicePoint不是一个二维数组,而是一个一维数组(由数组组成),因此由于您正在创建一个一维数组(由数组组成),因此只需指定一个索引:

double[][] ServicePoint = new double[10][];

然后,当您在数组中创建每个项时,它们也是数组,因此您可以指定它们的维度(这些维度可能不同,因此称为“jagged”数组):

ServicePoint[0] = new double[13];
ServicePoint[1] = new double[20];

嗨,(1) 给了我语法错误,原因是什么? - william007
3
构建时无法指定第二个范围限制,只能指定第一个。在分配每个数组时,您可以指定第二个范围限制...我会更新并澄清: - James Michael Hare
嗨,非常感谢。这是非常有价值的信息。 - mostafakvd
为什么左侧被认为是“外部”数组? - Aaron Franke

238

首先,您正在尝试创建所谓的锯齿数组。

double[][] ServicePoint = new double[10][9].

如果定义如下,上述语句将起作用。
double[][] ServicePoint = new double[10][]

这意味着您正在创建一个大小为10的数组,它可以存储10个不同大小的数组。简单来说,就是一个数组的数组。请参见下面的图像,表示一个锯齿状数组。

enter image description here

http://msdn.microsoft.com/en-us/library/2s05feca(v=vs.80).aspx

第二个基本上是一个二维数组,语法正确且可接受。
  double[,] ServicePoint = new double[10,9];//<-ok (2)

要访问或修改二维数组,您必须传递两个维度,但在您的情况下,您只传递了一个维度,这就是错误的原因。
正确的用法应该是:
ServicePoint[0][2],指的是第一行第三列上的项目。
您的二维数组的图示表示。

enter image description here


71

double[][] 被称为 锯齿状数组,在声明中未指定内部维度。与矩形数组不同,每个内部数组可以具有任意长度。每个内部数组隐式初始化为 null 而非空数组。必须手动创建每个内部数组:参考[C# 4.0 in nutshell The definitive Reference]

for (int i = 0; i < matrix.Length; i++)
{
    matrix[i] = new int [3]; // Create inner array
    for (int j = 0; j < matrix[i].Length; j++)
        matrix[i][j] = i * 3 + j;
}

double[,] 被称为 矩形数组,使用逗号来分隔每个维度进行声明。以下代码片段声明了一个3x3的二维矩形数组,并使用数字0到8对其进行初始化:

int [,] matrix = new int [3, 3];
for (int i = 0; i < matrix.GetLength(0); i++)
    for (int j = 0; j < matrix.GetLength(1); j++)
        matrix [i, j] = i * 3 + j;

嗨,(1) 给了我语法错误,原因是什么? - william007
2
这个例子非常有用,可以展示如何使用GetLength(dimension)迭代遍历数组的每一层级。 - DeanoMachino

25

double[,] 是一个二维数组(矩阵),而 double[][] 则是一个数组的数组 (锯齿形数组),语法如下:

double[][] ServicePoint = new double[10][];

好的,这似乎只是一半的答案。它并没有错,但它只解决了OP中的一些问题。 - Servy

9

double[][]是一个数组,而double[,]是一个矩阵。如果你想初始化一个二维数组,你需要这样做:

double[][] ServicePoint = new double[10][]
for(var i=0;i<ServicePoint.Length;i++)
    ServicePoint[i] = new double[9];

请注意,使用数组嵌套的方式可以让你拥有不同长度的数组:

ServicePoint[0] = new double[10];
ServicePoint[1] = new double[3];
ServicePoint[2] = new double[5];
//and so on...

long[,] data = new long[2, 4]{ {1,2,3,4}, {7,8,9,10} };和long[][] data2 = new long[2][] { new long[4]{1,2,3,4}, new long[4]{7,8,9,10} };产生相同的结果。然而,一个是长整型数组,另一个是两个维度的长整型数组。 - Golden Lion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接