多维数组
【多维数组】
如果一个一维数组中的每个元素都是同类型同大小的一维数组,情况会是什么样子呢?下图表示了一个(M+1)×(N+1)的二维数组,,二维数组实质上是对一维数组的扩展,其中的每个元素要用两个下标来表示,前一个称为行下标,后一个称为列下标。
【声明一个多维数组】
和一维数组一样,声明的主要作用就是提供给编译器足够多的信息,以便编译器在内存中开辟一块连续的,满足大小要求的内存区域,并将数组名和这块区域关联起来,这些信息包括:
(1)数组名。
(2)元素类型。
(3)数组的维数。
(4)数组的大小,多维数组的大小是各维大小之积。
一个二维数组可以用下列语句来声明:
int sz[2][3];
这声明了一个2×3的二维数组,共有2行3列计6个元素,对多维数组来说,元素的编号仍旧是从0开始的,所以,对上面这个二维数组来说,这6个元素分别为:
sz[0][0]、sz[0][1]、sz[0][2]、sz[1][0]、sz[1][1]、sz[1][2]
【初始化多维数组】
多维数组同样可以在声明的同时对其中的元素进行初始化,如:
intsz[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
或对部分元素进行初始化,如:
intsz[3][4]={{1,2},{9,10},{7,8}};
上面的语句仅初始化数组每一行的第一个元素,而未给其它元素赋初值,这种情况下,其他元素将自动初始化为0。
在声明的同时初始化其中元素时,在一行中的元素用花括号包裹,并且用逗号隔开。
当声明语句中提供有全部元素的初始值时,第一维的大小可以缺省,如:
int sz[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
只提供部分元素的初始值时,必须能让编译器判断第一维的大小,这个参数才可省略,如:
int sz[][4]={{1,2,3,4},{2,3},}; //等价于int sz[ ][4]={{1,2,3,4},{2,3}}; 编译器认为是2×4维
【多维数组的应用】
代码示例:
运行结果:
在写代码的时候发现以下问题,把上面框中的代码换成下列代码:
运行结果:
这里有个算法要注意,在操作翻转循环的时候,如果不是选择j=i+1;而是j=0开始的话,那么编译器会执行两侧翻转,那结果就和没有翻转是一样的了,就是以上显示的结果了,大家注意。
【多维数组在内存中的元素排列】
维数决定了数组中元素的组织方式及访问元素说用的下标个数,但本质上讲,所有的数组在内存中都是一维线性的。以二维数组为例,内存中是先放第一行的元素,再放第二行的元素,依次类推,下面给出了大小为3×4的二维数组A的排列顺序:
• A[0][0]-> A[0][1]->A[0][2]-> A[0][3]->
• A[1][0]-> A[1][1]->A[1][2]-> A[1][3]->
• A[2][0]-> A[2][1]->A[2][2]-> A[2][3]
多维数组的存储方式与此类似,以N维数组为例,内存中先放前N-1维索引都为0的那些元素,再放前N-2维坐标为0,第N-1维坐标为1的那些元素,下面给出3×3×3的三维数组B中元素在内存中的排列顺序:
• B[0][0][0]->B[0][0][1]-> B[0][0][2]->
• B[0][1][0]->B[0][1][1]-> B[0][1][2]->
• B[0][2][0]->B[0][2][1]-> B[0][2][2]->
• B[1][0][0]-> B[1][0][1]->B[1][0][2]->
• B[1][1][0]->B[1][1][1]-> B[1][1][2]->
• B[1][2][0]->B[1][2][1]-> B[1][2][2]->
• B[2][0][0]->B[2][0][1]-> B[2][0][2]->
• B[2][1][0]->B[2][1][1]-> B[2][1][2]->
• B[2][2][0]->B[2][2][1]-> B[2][2][2]->
由于多维数组在内存中采用的是线性存储的,元素存放的顺序也是确定的,在声明一个数组的同时对其初始化时,也可以采取下面的形式:
Int x[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
但是,仍然推荐使用前面介绍的按行初始化的方式,那样更加直观,方便阅读。