
5.2 其他常用数组
一维数组是最常用的数组,除此之外还有二维数组、多维数组、交错数组和静态数组等,将在本节详细介绍。
5.2.1 二维数组
数学中有一维直线、二维平面和三维的立体图形等,程序中的数组也有一维、二维和多维数组。一维数组是单个数据的集合,而二维数组相当于是一维数组的数组,即数组成员为一维数组。本节介绍二维数组的概念及其使用。
一维数组是一列数据,而二维数组可构成一个有着行和列的表格。同样是二月的28天,使用一维数组可以添加28个数据,而使用二维数组可以显示有着4周的列表:4行7列,每一行都是一周。
有行和列的二维数组又称作矩阵,如同矩形一样有长和宽。二维数组有行和列,它的声明与一维数组类似,其不同点在于:一维数组只需要指定数组的总长度,而二维数组需要分别指定行和列的长度。
二维数组中,行和列的长度同样放在中括号中声明,不同的是,二维数组中括号内有一个逗号,将中括号[]分为两部分,分别描述行和列。逗号的前面表示行的长度,后面表示列的长度。如声明一个3行4列的整型二维数组num,格式如下:
int[,] num=new int[3,4];
二维数组同一维数组一样可以直接赋值,每个元素同样使用逗号隔开,如定义一个二维数组num并赋值,格式如下:
int[,] num={ {2,3,8,10}, {1,4,6,11}, {5,7,9,12}, };
这是一个有着3行4列的数组,它有12个元素,将数组num表现为列表的形式如下所示:
2 3 8 10 1 4 6 11 5 7 9 12
同一维数组一样,二维数组也可以使用索引来访问单个元素,并且从0开始。不同的是,二维数组用行和列两种索引来确定一个元素,如访问数组num第一行第二个元素,即访问的是num[0,1]。规则如下。
(1)行号与列号之间用逗号隔开。
(2)行号与列号都从0开始编号。
(3)除了直接赋值的数组,数组需要使用new初始化才能使用,用法与一维数组一样。
二维数组的遍历同一维数组一样,使用循环语句。但二维数组是有行和列的,可使用循环嵌套语句,一行一行地访问;或使用foreach in语句依次访问。
使用foreach in语句访问二维数组,首先访问首行数据,一行结束后再访问下一行,直到最后一行最后一列。如使用for循环语句嵌套,来为3行4列的数组赋值,并使用foreach in语句来遍历输出,如范例4所示。
【范例4】
二维数组num有2行5列,使用for循环将数组中的元素从0到9赋值,并遍历输出,步骤如下。
(1)创建二维数组并根据行和列遍历数组为数组元素赋值,代码如下。
int[,] num = new int[2, 5]; int numValue = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 5; j++) { num[i, j] = numValue; numValue++; } }
(2)使用foreach in语句遍历输出数组元素,代码如下。
foreach (int sco in num) { Console.Write("{0} ", sco); }
(3)根据行和列,使用for循环嵌套来输出二维数组,代码如下。
Console.WriteLine(" "); Console.WriteLine("根据行和列输出二维数组:"); for (int i = 0; i < 2; i++) { for (int j = 0; j < 5; j++) { Console.Write("{0} ", num[i, j]); } Console.WriteLine(" "); }
(4)上述代码的执行结果如图5-1所示。

图5-1 二维数组
数组的维数可以是任意多个,如三维数组、四维数组等,多维数组的声明、初始化及遍历同二维数组一样。如声明一个整型三维数组three,语法如下:
int[,,] three;
从格式可以看出,三维数组在声明时,中括号内有两个逗号,将中括号分割成三个维度。同二维数组原理一样。同理,四维数组方括号内有三个逗号。
数组的赋值格式不变,但由于数组维数的不同,写法也不同。
5.2.2 交错数组
交错数组是一种不规则的特殊二维数组,交错数组与二维数组的不同在于,每一行的元素个数不同,因此无法用类似于new int[2,3]的形式来初始化。
由于交错数组元素参差不齐,因此又被称作锯齿数组、数组的数组或不规则数组。如将一年的12个月份根据每月的天数分为三行,第一行是31天的月份;第二行是30天的月份;第三行是28天的月份,如图5-2所示。

图5-2 交错数组
如图5-2所示,月份根据每月天数所列举的数组是一个交错数组,每一行的元素个数不一样。交错数组不如一维数组和二维数组常用,但也是生活中不可缺少的。
交错数组声明的格式与其他数组不同,它使用两个中括号来区分不同的维度,语法格式如下:
type[][] arrayName;
交错数组的初始化,同样需要指定每行每列的元素个数。但交错数组每一行的元素个数各不相同,因此只需要设置数组包含的行数,表示列的中括号不填写内容。
【范例5】
定义整型交错数组inter含有三行,第一行4个元素、第二行3个元素、第三行5个元素。声明赋值语句如下:
int[][] inter=new int[3][]; inter[0] = new int[4] { 1, 2, 3, 4 }; inter[1] = new int[3] { 1,2,3}; inter[2] = new int[5] { 1, 2, 3, 4, 5 };
交错数组的元素访问同样需要使用索引,即在两个中括号中分别填写对应的索引数字。
5.2.3 静态数组
C#中除了上述几种数组以外,还可以根据C#内置类来初始化几个特殊的数组,如静态数组、动态数组等。
静态数组是维数和长度不能改变的数组,之前所讲的数组都是静态数组。本节所介绍的静态类使用System.Array类来操作,包括对数组的排序、获取长度和维数、元素倒序等。
在C#中有一些定义好的常用功能,这些功能被放在类中,可以直接使用。如将数组的排序功能定义为一个方法,放在类中,则若需要对一个数组执行排序,可以直接调用类的方法,而不再需要使用一系列的循环和选择语句。
属性是类的成员,相当于类中的变量。但属性定义了变量的获取方式,可以直接获取指定的数据。System.Array类有如表5-1所示的属性。
表5-1 System.Array类的属性

之前曾经介绍,通过Length属性获得数组的长度。使用属性是一种简单的操作,对于数组num来说,num.Length即表示该数组的长度。对于确定的数组,不需要为属性赋值和定义,可以直接使用。
类中除了属性,还有方法。方法是一种描述了特定功能的语句块,可以直接使用。System.Array类中关于数组的方法,如表5-2所示。
表5-2 System.Array类的方法

类中的方法是可以直接使用的,例如使用数组名称和元素的索引来获取某个元素的值,但使用GetValue()方法同样可以达到目的。
【范例6】
定义一维整型数组arrays并赋值,输出数组的长度、维度及各元素的值;将arrays数组使用Sort()方法排序,输出排序后的各元素值,代码如下。
int[] arrays = new int[9] { 5, 8, 2, 6, 4, 1, 9, 7, 3 }; Console.WriteLine("数组个数:{0}; 数组维数:{1} ", arrays.Length, arrays. Rank); foreach (int i in arrays) //遍历输出元素 { Console.Write("{0} ", i); } Console.WriteLine(""); Array.Sort(arrays); //一维数组元素排序 foreach (int i in arrays) //遍历排序后的数组 { Console.Write("{0} ", i); }