一维和多维数组
数组是程序设计中常用的一种数据结构,和C/C++一样,C#中的数组索引从0开始,且其元素类型必须相同,当然由于多态等带来的隐式转型则另当别论。C#中的数组可以分为一维数组、多维数组以及参差数组(Ragged Array),它们各自的声明、初始化以及元素索引都有不同的语法规定。C#同C++数组的一个显著不同是它由.NET通用语言运行环境(CLR)保证其类型安全,可以在运行时动态创建和扩充容量。
一维数组声明和初始化有特定的语法,我们通常将它们放在一起,看下面的代码:
//声明的同时初始化
int[] MyIntArr1=new int[] {1,2,3};
//声明并初始化1×3数组
int[] MyIntArr2=int{1,2,3};
//简化形式的声明并初始化
//声明与初始化分开
int[] MyIntArr3;
MyIntArr3=new int[]{1,2,3};//不可以单用简化形式的初始化
//初始化中可以指定数组的容量
int[] MyIntArr4=new int[3]{1,2,3};
//不可以: int[3] MyIntArr4=new int[3]{1,2,3}
注意这里声明部分的括号([])紧跟在数组元素类型(如int)之后,然后才是变量名。C#不支持传统C++那样的“int a[]={1,2,3,4,5}”声明方式。等号右面是初始化部分,我们可以看到C#支持两种初始化表达形式,其中后者是前者的简化,但在声明与初始化分开的情况下,不能再采用简化形式的初始化。C#数组的初始化部分可以在括号([])中指定数组的容量(其中必须为整数常量或常数,当然必须和后面初始化的数组元素个数匹配),数组声明部分不可以包含数组的容量。
C#支持多维数组,其初始化和C++一样都采用嵌套的大括号来表达,但它的声明和C++有所不同,看下面的代码与注释:
//声明的同时初始化
int[,] MyMulArr1=new int[,]{{1,2,3},{2,4,6}};//声明并初始化2×3数组
int[,] MyMulArr2={{1,2,3},{2,4,6}};
//简化形式的初始化
//声明与初始化分开
int[,] MyMulArr3;
MyMulArr3=new int[,]{{1,2,3},{2,4,6}};
//初始化中可以指定数组的容量
int[,] MyMulArr4=new int[2,3]{{1,2,3},{2,4,6}};
//不可以: int[2,3] MyMulArr5=new int[2,3]{{1,2,3},{2,4,6}};
C#在括号中用逗号(,)分割的方法来声明多维数组,多个括号(如int[][] a)的表达方式在C#中用来表示参差数组。多维数组的声明和初始化与一维数组有相似的规定,我们可以从上面的例子中看出来。
参差数组
参差数组又称数组的数组(Array of Array),它表面上类似于上面讲到的多维数组,但它本质上仍是一个一维数组,只不过它的元素又是一个数组(可以是一维数组、多维数组或者参差数组)。参差数组一个显著的特性是作为它的元素的数组阶数可以不同,非常形象地表现为“参差不齐”状。由于本质仍是一个一维数组,参差数组的声明与初始化和一维数组的规定一样,只是由于在“感觉”上老把它假定为一个多维数组而导致在这里很容易犯错,看下面的代码与注释:
//声明的同时初始化
int[][] MyRagArr1=new int[][]{new int[]{1,2,3},new int[]{2,4,6}};//声明并初始化二维数组,其元素为三维数组
int[][] MyRagArr2={new int[]{1,2,3},
new int[]{2,4,6}};//简化形式的初始化
//不可以用多维数组的初始化语句:int[][] MyRagArr2={{1,2,3},{2,4,6}};
//声明与初始化分开
int[][] MyRagArr3;
MyRagArr3=new int[2][];//初始化一维数组,
//不可以这样:MyRagArr3=new int[2][3];
MyRagArr3[0]=new int[]{1,2,3};
//初始化数组元素
MyRagArr3[1]=new int[]{2,4,6};
//初始化数组元素
//初始化中可以指定数组的容量
int[][] MyRagArr4=new int[2][]{new int[]{1,2,3},new int[]{2,4,6}};
//不可以: int[2][] MyRagArr=new int[2][]{new int[]{1,2,3},new int[]{2,4,6}};
//也不可以: int[][] MyRagArr4=new int[2][3]{new int[]{1,2,3},new int[]{2,4,6}};
//一个典型的“参差”数组
int[][] MyRagArr5=new int[3][];
MyRagArr5[0]=new int[]{1,2,3,4,5};
MyRagArr5[1]=new int[]{1,2,3};
MyRagArr5[2]=new int[]{1,2,3,4,5,6,7,8};
C#采用多个括号并列的方式来表达参差数组(数组的数组)。上面的代码和注释详细地展示了参差数组在声明和初始化时的用法。大多数行为和前面从一维数组中得来的经验相同,但只有一点需要指出:为什么在指定数组容量的时候只能指定其第一个括号中的常量或常数,而不可以指定其后面括号中的容量?这可以从参差数组的本质——一维数组上找到答案。在对参差数组初始化的时候,实际上是在初始化一维数组中的各个元素。根据一维数组的规定,只能指定这些元素的个数,即一维数组的容量,也就是参差数组第一个括号中的常量或常数。
C#中的数组本质上是一种托管的System.Array类型,当然它也拥有System.Array所有的接口操作。值得指出的是System.Array是一个抽象类型,我们不可以直接声明System.Array而得到数组类型——实际上,System.Array根本就不应该被认为是数组类型,它仅仅是通过系统服务为我们提供接口操作。System.Array很多的属性和方法对操作数组非常有用,本文不再一一列出,下面仅给出一个完整的示范性例子以帮助理解:
using System;
class Test {
public static void Main() {
//一维数组
int[] MyIntArr=new int[] {1,2,3,4,5};
foreach(int i in MyIntArr)
Console.Write(i);
Console.WriteLine(“/nThe Length:”+MyIntArr.Length+“/n”);
//多维数组
int[,] MyMulArr=new int[,]{{1,2,3},{2,4,6}};
foreach(int i in MyMulArr)
Console.Write(i);
Console.WriteLine();
for(int i=0;i<2;i++) {
Console.WriteLine();
for(int j=0;j<3;j++)
Console.Write(MyMulArr[i,j]);
}
Console.WriteLine(“/nThe Length:”+MyMulArr.Length+“/n”);
//参差数组
int[][] MyRagArr=new int[3][];
MyRagArr[0]=new int[]{1,2,3,4,5};
MyRagArr[1]=new int[]{1,2,3};
MyRagArr[2]=new int[]{1,2,3,4,5,6,7,8};
for(int i=0;i<MyRagArr.Length;i++) {
Console.WriteLine();
for(int j=0;j<MyRagArr[i].Length;j++)
Console.Write(MyRagArr[i][j]);
}
Console.WriteLine(“/nThe Length:”+MyRagArr.Length);
}
}
数组是程序设计中常用的一种数据结构,和C/C++一样,C#中的数组索引从0开始,且其元素类型必须相同,当然由于多态等带来的隐式转型则另当别论。C#中的数组可以分为一维数组、多维数组以及参差数组(Ragged Array),它们各自的声明、初始化以及元素索引都有不同的语法规定。C#同C++数组的一个显著不同是它由.NET通用语言运行环境(CLR)保证其类型安全,可以在运行时动态创建和扩充容量。
一维数组声明和初始化有特定的语法,我们通常将它们放在一起,看下面的代码:
//声明的同时初始化
int[] MyIntArr1=new int[] {1,2,3};
//声明并初始化1×3数组
int[] MyIntArr2=int{1,2,3};
//简化形式的声明并初始化
//声明与初始化分开
int[] MyIntArr3;
MyIntArr3=new int[]{1,2,3};//不可以单用简化形式的初始化
//初始化中可以指定数组的容量
int[] MyIntArr4=new int[3]{1,2,3};
//不可以: int[3] MyIntArr4=new int[3]{1,2,3}
注意这里声明部分的括号([])紧跟在数组元素类型(如int)之后,然后才是变量名。C#不支持传统C++那样的“int a[]={1,2,3,4,5}”声明方式。等号右面是初始化部分,我们可以看到C#支持两种初始化表达形式,其中后者是前者的简化,但在声明与初始化分开的情况下,不能再采用简化形式的初始化。C#数组的初始化部分可以在括号([])中指定数组的容量(其中必须为整数常量或常数,当然必须和后面初始化的数组元素个数匹配),数组声明部分不可以包含数组的容量。
C#支持多维数组,其初始化和C++一样都采用嵌套的大括号来表达,但它的声明和C++有所不同,看下面的代码与注释:
//声明的同时初始化
int[,] MyMulArr1=new int[,]{{1,2,3},{2,4,6}};//声明并初始化2×3数组
int[,] MyMulArr2={{1,2,3},{2,4,6}};
//简化形式的初始化
//声明与初始化分开
int[,] MyMulArr3;
MyMulArr3=new int[,]{{1,2,3},{2,4,6}};
//初始化中可以指定数组的容量
int[,] MyMulArr4=new int[2,3]{{1,2,3},{2,4,6}};
//不可以: int[2,3] MyMulArr5=new int[2,3]{{1,2,3},{2,4,6}};
C#在括号中用逗号(,)分割的方法来声明多维数组,多个括号(如int[][] a)的表达方式在C#中用来表示参差数组。多维数组的声明和初始化与一维数组有相似的规定,我们可以从上面的例子中看出来。
参差数组
参差数组又称数组的数组(Array of Array),它表面上类似于上面讲到的多维数组,但它本质上仍是一个一维数组,只不过它的元素又是一个数组(可以是一维数组、多维数组或者参差数组)。参差数组一个显著的特性是作为它的元素的数组阶数可以不同,非常形象地表现为“参差不齐”状。由于本质仍是一个一维数组,参差数组的声明与初始化和一维数组的规定一样,只是由于在“感觉”上老把它假定为一个多维数组而导致在这里很容易犯错,看下面的代码与注释:
//声明的同时初始化
int[][] MyRagArr1=new int[][]{new int[]{1,2,3},new int[]{2,4,6}};//声明并初始化二维数组,其元素为三维数组
int[][] MyRagArr2={new int[]{1,2,3},
new int[]{2,4,6}};//简化形式的初始化
//不可以用多维数组的初始化语句:int[][] MyRagArr2={{1,2,3},{2,4,6}};
//声明与初始化分开
int[][] MyRagArr3;
MyRagArr3=new int[2][];//初始化一维数组,
//不可以这样:MyRagArr3=new int[2][3];
MyRagArr3[0]=new int[]{1,2,3};
//初始化数组元素
MyRagArr3[1]=new int[]{2,4,6};
//初始化数组元素
//初始化中可以指定数组的容量
int[][] MyRagArr4=new int[2][]{new int[]{1,2,3},new int[]{2,4,6}};
//不可以: int[2][] MyRagArr=new int[2][]{new int[]{1,2,3},new int[]{2,4,6}};
//也不可以: int[][] MyRagArr4=new int[2][3]{new int[]{1,2,3},new int[]{2,4,6}};
//一个典型的“参差”数组
int[][] MyRagArr5=new int[3][];
MyRagArr5[0]=new int[]{1,2,3,4,5};
MyRagArr5[1]=new int[]{1,2,3};
MyRagArr5[2]=new int[]{1,2,3,4,5,6,7,8};
C#采用多个括号并列的方式来表达参差数组(数组的数组)。上面的代码和注释详细地展示了参差数组在声明和初始化时的用法。大多数行为和前面从一维数组中得来的经验相同,但只有一点需要指出:为什么在指定数组容量的时候只能指定其第一个括号中的常量或常数,而不可以指定其后面括号中的容量?这可以从参差数组的本质——一维数组上找到答案。在对参差数组初始化的时候,实际上是在初始化一维数组中的各个元素。根据一维数组的规定,只能指定这些元素的个数,即一维数组的容量,也就是参差数组第一个括号中的常量或常数。
C#中的数组本质上是一种托管的System.Array类型,当然它也拥有System.Array所有的接口操作。值得指出的是System.Array是一个抽象类型,我们不可以直接声明System.Array而得到数组类型——实际上,System.Array根本就不应该被认为是数组类型,它仅仅是通过系统服务为我们提供接口操作。System.Array很多的属性和方法对操作数组非常有用,本文不再一一列出,下面仅给出一个完整的示范性例子以帮助理解:
using System;
class Test {
public static void Main() {
//一维数组
int[] MyIntArr=new int[] {1,2,3,4,5};
foreach(int i in MyIntArr)
Console.Write(i);
Console.WriteLine(“/nThe Length:”+MyIntArr.Length+“/n”);
//多维数组
int[,] MyMulArr=new int[,]{{1,2,3},{2,4,6}};
foreach(int i in MyMulArr)
Console.Write(i);
Console.WriteLine();
for(int i=0;i<2;i++) {
Console.WriteLine();
for(int j=0;j<3;j++)
Console.Write(MyMulArr[i,j]);
}
Console.WriteLine(“/nThe Length:”+MyMulArr.Length+“/n”);
//参差数组
int[][] MyRagArr=new int[3][];
MyRagArr[0]=new int[]{1,2,3,4,5};
MyRagArr[1]=new int[]{1,2,3};
MyRagArr[2]=new int[]{1,2,3,4,5,6,7,8};
for(int i=0;i<MyRagArr.Length;i++) {
Console.WriteLine();
for(int j=0;j<MyRagArr[i].Length;j++)
Console.Write(MyRagArr[i][j]);
}
Console.WriteLine(“/nThe Length:”+MyRagArr.Length);
}
}