首页 > 编程笔记

C#二维数组的创建和使用

二维数组是一种特殊的多维数组,多维数组是指可以用多个索引进行访问的数组。C# 声明多维数组时,用多个[ ]或者在中括号内加逗号。有 n 对中括号或者中括号内有 n 个元素,就是 n 维数组。

下面以最常用的二维数组为例讲解多维数组。

C# 二维数组的创建

C# 一维数组中提到的快捷酒店有很多房间,这些房间可以构成一维数组。如果这个酒店有 500 个房间,并且所有房间都在同一个楼层里,那么拿到 499 号房钥匙的旅客可能就不高兴了,因为从 1 号房走到 499 号房要花很长时间。因此,每个酒店都不只有一个楼层,而是很多楼层,每一个楼层都会有很多房间,从而形成一个立体的结构,把大量的房间均摊到每个楼层,这种结构就是二维表结构。

在计算机中,二维表结构可以使用二维数组来表示。使用二维表结构表示快捷酒店每一个楼层的房间号的效果如图1所示。

用二维表结构表示的楼层房间号
图1:用二维表结构表示的楼层房间号

二维数组常用于表示二维表,表中的信息以行和列的形式表示,第一个下标代表元素所在的行,第二个下标代表元素所在的列。

二维数组的声明语法格式如下。

type[,] arrayName;
type[][] arrayName;

细节说明:
例如,声明一个 int 类型的二维数组,可以使用下面两种形式。

形式1如下:
int[,] myarr;  //声明一个int类型的二维数组,名称为myarr
形式2如下:
int[][] myarr;  //声明一个int类型的二维数组,名称为myarr
同一维数组一样,二维数组在声明时也没有分配内存空间,同样要先使用关键字 new 来分配内存空间,然后才可以访问每个元素。

对于二维数组,有以下两种为数组分配内存空间的方式。

1) 直接为每一维分配内存空间

例如,定义一个二维数组并直接为其分配内存空间,代码如下:
int[,] a = new int[2, 4]; //定义一个2行4列的int类型二维数组
上面代码定义了一个 int 类型的二维数组 a,二维数组 a 中包括两个长度为 4 的一维数组,内存空间分配如图2所示。

C#二维数组内存空间分配(第一种方式)
图2:二维数组内存空间分配(第一种方式)

2) 分别为每一维分配内存空间

例如,定义一个二维数组并分别为每一维分配内存空间,代码如下:
int[][] a = new int[2][];  //定义一个两行的int类型二维数组
a[0] = new int[2];  //初始化二维数组的第一行有两个元素
a[1] = new int[3];  //初始化二维数组的第二行有3个元素
使用第二种方式为二维数组分配的内存空间如图3所示。

C#二维数组内存空间分配(第二种方式)
图3:二维数组内存空间分配(第二种方式)

说明:上面代码中,由于为每一维分配的内存空间不同,因此 a 相当于一个不规则二维数组。

C# 二维数组的初始化

二维数组有两个索引(即下标),构成由行列组成的一个矩阵,如图4所示。

二维数组索引与行列的关系
图4:二维数组索引与行列的关系

二维数组的初始化主要分为3种:为单个二维数组元素赋值、为每一维数组元素赋值和同时为整个二维数组赋值。下面分别介绍。

1) 为单个二维数组元素赋值

为单个二维数组元素赋值即首先定义一个二维数组,并指定行数和列数,然后为二维数组中的每个元素赋值,代码如下。
int[,] myarr = new int[2, 2];  //定义一个int类型的二维数组
myarr[0, 0] = 0;  //为二维数组中第1行第1列的元素赋值
myarr[0, 1] = 1;  //为二维数组中第1行第2列的元素赋值
myarr[1, 0] = 1;  //为二维数组中第2行第1列的元素赋值
myarr[1, 1] = 2;  //为二维数组中第2行第2列的元素赋值
使用这种方式对二维数组进行赋值时,通常使用嵌套的循环实现。

例如,上面代码可以修改成如下形式:
int[,] myarr = new int[2, 2];   //定义一个int类型的二维数组
for (int i = 0; i < 2; i++)     //遍历二维数组的行
{
     for (int j = 0; j < 2; j++) //遍历二维数组的列
     {
          myarr[i, j] = i + j;   //为遍历到的二维数组中第i行第j列的元素赋值
     }
}

2) 为每一维数组元素赋值

为二维数组中的每一维数组元素赋值时,首先需要使用数组类型[ ][ ]形式声明一个数组,并指定数组的行数,然后再分别为每一维数组元素赋值代码如下:
int[][] myarr = new int[2][];  //定义一个两行的int类型二维数组
myarr[0] = new int[] { 0, 1 }; //初始化二维数组第1行的元素
myarr[1] = new int[] { 1, 2 }; //初始化二维数组第2行的元素

3) 同时为整个二维数组赋值

同时为整个二维数组赋值时需要使用嵌套的大括号,将要赋值的数据放在里层大括号中,每对大括号之间用逗号,隔开。

C# 代码如下:
int[,] myarr = new int[2,2] { { 12, 0 }, { 45, 10 } };
或使用如下形式:
int[,] myarr = new int[,]{ { 12, 0 }, { 45, 10 } };
还可以使用如下形式:
int[,] myarr = {{12,0},{45,10}};
以上 3 种形式实现的效果是一样的,都是定义了一个 2 行 2 列的 int 类型二维数组,并进行了初始化。其中,后两种形式会自动计算数组的行数和列数。

C# 二维数组的使用

创建一个控制台应用程序,模拟制作一个简单的客车售票系统。假设客车的座位数是 9 行 4 列,使用一个二维数组记录客车售票系统中的所有座位号,并在每个座位号上都显示“【有票】”,然后用户输入一个座位号,按回车键,即可将该座位号显示为“【已售】”。

完整的 C# 代码如下:
static void Main(string[] args)
{
     Console.Title = "简单客车售票系统";  //设置控制台标题
     string[,] zuo = new string[9, 4];   //定义二维数组
     for (int i = 0; i < 9; i++) //for循环开始
     {
          for (int j = 0; j < 4; j++)     //for循环开始
          {
               zuo[i, j] = "【有票】";    //初始化二维数组
          }
     }
     string s = string.Empty;             //定义字符串变量
     while (true)                         //开始售票
     {
          Console.Clear(); //清空控制台信息
          Console.WriteLine("\n        简单客车售票系统" + "\n"); //输出字符串
          for (int i = 0; i < 9; i++)
          {
               for (int j = 0; j < 4; j++)
               {
                    System.Console.Write(zuo[i, j]); //输出售票信息
               }
               Console.WriteLine();                  //输出换行符
           }
           Console.Write("请输入座位行号和列号(如0,2)输入q退出:");
           s = Console.ReadLine();                  //售票信息输入
           if (s == "q") break;                    //输入“q”退出系统
           string[] ss = s.Split(',');             //拆分字符串
           int one = int.Parse(ss[0]);              //得到座位行数
           int two = int.Parse(ss[1]);              //得到座位列数
           zuo[one, two] = "【已售】";              //标记售出票状态
     }
}
上面代码中用到了字符串的 Split 方法,该方法用来根据指定的符号对字符串进行分割,这里了解即可。

程序运行效果如图5所示。

模拟客车售票系统
图5:模拟客车售票系统

C# 不规则数组的定义

前面讲的二维数组是行和列固定的矩形方阵,如 4×4、3×2 等。另外,C# 中还支持不规则的数组。例如,在二维数组中,不同行的元素个数完全不同。

请看下面的 C# 代码:
int[][] a = new int[3][]; //创建二维数组,指定行数,不指定列数
a[0] = new int[5];  //第一行分配5个元素
a[1] = new int[3];  //第二行分配3个元素
a[2] = new int[4];  //第三行分配4个元素
上面代码中定义的不规则二维数组所占的内存空间如图6所示。

不规则二维数组占用的内存空间
图6:不规则二维数组占用的内存空间

获取二维数组的列数

二维数组的行数可以使用 Length 属性获得,但由于 C# 中支持不规则数组,因此二维数组中每一行中的列数可能不会相同。如何获取二维数组中每一维的列数呢?答案还是使用 Length 属性。因为二维数组的每一维都可以看作一个一维数组,而一维数组的长度可以使用 Length 属性获得。

例如,下面的 C# 代码定义了一个不规则二维数组,并通过遍历其行数、列数,输出二维数组中的内容。
static void Main(string[] args)
{
     int[][] arr = new int[3][];    //创建二维数组,指定行数,不指定列数
     arr[0] = new int[5];           //第一行分配5个元素
     arr[1] = new int[3];           //第二行分配3个元素
     arr[2] = new int[4];           //第三行分配4个元素
     for(int i=0;i< arr.Length;i++) //遍历行数
     {
         for(int j = 0; j < arr[i].Length; j++) //遍历列数
         {
             Console.Write(arr[i][j]);          //输出遍历到的元素
         }
         Console.WriteLine();                   //换行输出
     }
     Console.ReadLine();
}

推荐阅读