C语言多维数组,以及多维数组中的二维数组

C 语言中的多维数组(multidimensional array)其实就是元素为数组的数组。n 维数组的元素是 n-1 维数组。例如,二维数组的每个元素都是一维数组,一维数组的元素当然就不是数组了。

多维数组声明时,每个维度用一对方括号来表示:
char screen[10][40][80];           // 一个三维数组

数组 screen 包含 10 个元素,从 screen[0] 到 screen[9]。每个元素又是一个二维数组,它有 40 个元素,这 40 个元素均是一维数组,然后每个一维数组内都有 80 个字符。整体来说,screen 数组有 32000(10×40×80)个 char 类型元素。

想要获取该三维数组 screen 内的某个 char 元素,必须指定 3 个索引值。例如,下面的语句把字符Z写入该数组的最后一个元素位置:
screen[9][39][79] = 'Z';

二维数组(矩阵)

二维数组常常被称为矩阵(matrix)。它应用频繁,因此我们来更详细地讨论下矩阵。把矩阵想成列和行的排列方式,更有助于理解它。下面定义的矩阵 mat 有三行和五列:
float mat[3][5];

这三个元素 mat[0]、mat[1] 和 mat[2] 是矩阵 mat 的三行。每行都是由五个 float 元素所组成的数组。因此,该矩阵包含 3×5=15 个 float 元素,如下表所示:
  [0] [1] [2] [3] [4]
mat[0] 0.0 0.1 0.2 0.3 0.4
mat[1] 1.0 1.1 1.2 1.3 1.4
mat[2] 2.0 2.1 2.2 2.3 2.4


上图中所指定的值可以利用嵌套循环语句赋值得到的。第一个索引值指定行,第二个索引值定位到该行中的某列:
for ( int row = 0; row < 3; ++row )
  for ( int col = 0; col < 5; ++col )
    mat[row][col] = row + (float)col/10;

在内存中,这三行被连续存储在一起,因为它们都是 mat 数组的元素。这样的话,该数组中的 float 值以递增的顺序存储在一起。

声明多维数组

在数组声明中,如果执行定义操作的话,数组类型可以是不完整的。也就是说,可以声明数组,却不指定其长度这种声明所引用的数组,必须在程序其他地方指定它的长度。然而,必须声明一个数组元素的完整类型。对于一个多维数组的声明而言,只有第一个维度可以不指定长度,所有其他维度都必须指定长度。例如,在声明二维数组时,必须要指定列的数量。

如果前面例子的数组 mat 有外部链接(例如,它的定义在所有函数外部),那么其他源代码文件只要做如下声明,就可以使用 mat:
extern float mat[ ][5];     // 外部声明

初始化多维数组

可以利用初始化列表来初始化多维数组,还有一些需要特别注意的地方:不必为每个维度都写一对大括号,可以使用多维元素指示符

为展示各种可能性,我们假定一个数组定义和初始化如下:
int a3d[2][2][3] =    { { { 1, 0, 0 }, { 4, 0, 0 } },
                      { { 7, 8, 0 }, { 0, 0, 0 } } };

这个初始化列表包含了三个层次的列表大括号,并且用下面的值初始化二维数组 a3d[0] 和 a3d[l] 的元素:
  [0] [1] [2]
a3d[0][0] 1 0 0
a3d[0][1] 4 0 0

  [0] [1] [2]
a3d[1][0] 7 8 0
a3d[1][1] 0 0 0

因为所有只要没与初始化器的元素,就会被初始化为默认的 0,所以下面的定义具有一样的效果:
int a3d[ ][2][3] = { { { 1 }, { 4 } }, { { 7, 8 } } };

该初始化列表也显示出三个层次的大括号。不需要指定第一个维度为 2,因为最外面的初始化列表包含两个初始化器。

也可以省略某些大括号。如果某对大括号包含了比对应数组维度中元素数量还多的初始化器,那么多出来的初始化器会被关联到存储序列中的下一个数组元素中。因此,下面这两个定义是等价的:
int a3d[2][2][3] = { { 1, 0, 0, 4 }, { 7, 8 } };
int a3d[2][2][3] = { 1, 0, 0, 4, 0, 0, 7, 8 };

最后,可以利用元素指示符达到相同的初始化目的,如下所示:
int a3d[2][2][3] = { 1, [0][1][0]=4, [1][0][0]=7, 8 };

上述定义等同于:
int a3d[2][2][3] = { {1}, [0][1]={4}, [1][0]={7, 8} };

如果只有一小部分的元素需要被初始化为 0 以外的值,那么使用元素指示符是一个不错的做法。