标签:重点 ase 语句 ram strong 创建表 art subarray 产生
数组实际上是由一个变量名称表示的一组同类型的数据元素。每个元素通过变量名称和一个或多个方括号中的索引来访问:
数组名 索引 ↓ ↓ MyArray[4]
让我们从C#中与数组有关的重要定义开始
关于C#数组的一些要点:
C#提供两种类型的数组
另外,有两种类型的多维度数组:矩形数组(rectangular array)和交错数组(jagged array),它们有如下特性:
int x=myArray2[4,6,1]
jagArray1[2][7][4]
数组实例是从System.Array继承的对象。由于数组从BCL(Base Class Library)基类继承,它们也继承了很多有用的方法。
数组是引用类型,与所有引用类型一样,有数据的引用以及数据对象本身。引用在栈或堆上,而数组对象本身总在堆上。
尽管数组总是引用类型,但是数组元素可以是值类型也可以是引用类型。
一维数组和矩形数组的语法非常相似,因此放在一起阐述。然后再单独介绍交错数组。
声明一维数组或矩形数组
声明一维数组或矩形数组,在类型和变量名称间使用一对方括号。
矩形数组声明示例:
秩说明符 ↓ int[,,] firstArray; //三维整型数组 int[,] arr1; //二维整型数组 long[,] arr3; //三维long数组 long[3,2,6] SecondArray;//编译错误 ↑ 声明时不允许设置维度长度
和C/C++不同,方括号在基类型后,而不是在变量名称后。
要实例化数组,我们可以使用数组创建表达式。数组创建表达式由new运算符构成,后面是基类名称和一对方括号。方括号中以逗号分隔每个维度的长度。
例:
int[] arr2=new int[4];//包含4个int的一维数组 MyClass[] maArr=new MyClass[4];//包含4个MyClass引用的一维数组 int[,,] arr3=new int[3,6,2];//三维数组,数组长度是3*6*2=36
与对象创建表达式不一样,数组创建表达式不包含圆括号-即使是对于引用类型数组。
在数组中使用整型值作为索引来访问数组元素。
int[] intArr1=new int[15]; intArr1[2]=10; int var1=intArr1[2]; int[,] intArr2=new int[5,10]; intArr2[2,3]=7; int var2=intArr2[2,3];
int[] myIntArray; myIntArray=new int[4]; for(int i=0;i<4;i++) { myIntArray[i]-i*10; } for(int i=0;i<4;i++) { Console.WriteLine("Value of element {0} = {1}",i,myIntArray[i]); }
数组被创建后,每个元素被自动初始化为类型的默认值。对于预定义类型,整型默认值是0,浮点型默认值是0.0,布尔型默认值是false,而引用类型默认值则是null。
例:一维数组的自动初始化
int[] intArr=new int[4];
int[] intArr=new int[]{10,20,30,40};
要显式初始化矩形数组,需遵守以下规则:
int[,] intArray2=new int[,]{{10,1},{2,10},{11,9}};
在一条语句中使用声明、数组创建和初始化时,可以省略语法的数组创建表达式部分。快捷语法如下:
int[] arr1=new int[3]{10,20,30}; int[] arr1= {10,20,30}; int[,] arr=new int[2,3]{{0,1,2},{10,11,12}}; int[,] arr= {{0,1,2},{10,11,12}};
上面声明的数组都是显式指定数组类型。然而,和其他局部变量一样,数组可以是隐式类型的。
虽然用var替代了显式数组类型,但是仍然需要在初始化中提供秩说明符。
int[] intArr1=new int[]{10,20,30,40}; var intArr2=new []{10,20,30,40}; int[,] intArr3=new int[,]{{10,1},{2,10},{11,9}}; var intArr4=new [,]{{10,1},{2,10},{11,9}}; string[] sArr1=new string[]{"life","liberty","pursuit of happiness"}; var sArr2=new []{"life","liberty","pursuit of happiness"};
例:综合示例
var arr=new int[,]{{0,1,2},{10,11,12}}; for(int i=0;i<2;i++) { for(int j=0;j<3;j++) { Console.WriteLine("Element [{0},{1}] is {2}",i,j,arr[i,j]); } }
交错数组是数组的数组。与矩形数组不同,交错数组的子数组的元素个数可以不同。
例:二维交错数组
int[][] jagArr=new int[3][];
交错数组的声明语法要求每个维度都有一对独立的方括号。数组变量声明中的方括号数决定了数组的秩。
和矩形数组一样,维度长度不能包括在数组类型的声明部分。
int[][] SomeArr;//秩等于2 int [][][] OhterArr;//秩等于3
我们可以将数组创建表达式创建的顶层数组和交错数组的声明相结合。
int[][] jagArr=new int[3][];//3个子数组
不能在声明语句中初始化顶层数组之外的数组。
int[][] jagArr=new int[3][4];//不允许,编译错误
和其他类型数组不一样,交错数组的完全初始化不能在一个步骤中完成。由于交错数组是独立数组的数组-每个数组必须独立创建。
例:实例化交错数组
int[][] Arr=new int[3][]; Arr[0]=new int[]{10,20,30}; Arr[1]=new int[]{40,50,60,70}; Arr[3]=new int[]{80,90,100,110,120};
矩形数组和交错数组的结构区别非常大。
例如,下图演示了3X3的矩形数组以及由3个长度为3的一维数组构成的交错数组的结构。
在CIL(Common Intermediate Laguage,公共中间语言)中,一维数组有特定的指令用于性能优化。矩形数组没有这些指令,并且不在相同级别进行优化。因此,有时使用一维数组(可以被优化)的交错数组比矩形数组(不能被优化)更有效率。
另一方面,矩形数组的编程复杂度要小得多,因为它会被作为一个单元而不是数组的数组。
foreach语句允许我们连续访问数组中的每个元素。
有关foreach语句的重点如下:
foreach(Type Identifier in ArrayName)//显式 { Statement } foreach(var Identifier in ArrayName)//隐式 { Statement }
foreach如下方式工作:
例:foreach示例
int[] arr1={10,11,12,13}; foreach(int item in arr1) { Console.WriteLine("Item Value: {0}",item); }
迭代变量是只读的。但是,对于值类型数组和引用类型数组效果不一样。
对于值类型数组,这意味着在用迭代变量时,我们不能改变它们。
例:尝试修改迭代变量报错
int[] arr1={10,11,12}; foreach(int item in arr1) { item++; }
对于引用变量,迭代变量保存的是数据的引用,而不是数据本身。所以,我们虽然不能改变引用,但是我们可以改变数据。
例:引用变量修改迭代变量
class MyClass { public int MyField=0; } class Program { static void Main() { MyClass[] mcArray=new MyClass[4]; for(int i=0;i<4;i++) { mcArray[i]=new MyClass(); mcArray[i].MyField=i; } foreach(var item in mcArray) { item.MyField+=10; } foreach(var item in mcArray) { Console.WriteLine("{0}",item.MyField); } } }
多维数组里,元素处理顺序是从最右边的索引号依次递增。
例:矩形数组示例
class Program { static void Main() { int total=0; int[,] arr1={{10,11},{12,13}}; foreach(var element in arr1) { total+=element; Console.WriteLine("Element:{0},Current Total:{1}",element,total); } } }
例:交错数组示例
class Program { static void Main() { int total=0; int[][] arr1=new int[2][]; arr1[0]=new int[]{10,11}; arr1[1]=new int[]{12,13,14}; foreach(int[] array in arr1) { Console.WriteLine("Starting new array"); foreach(int item in array) { total+=element; Console.WriteLine("Item:{0},Current Total:{1}",item,total); } } } }
某些情况下,即使某对象不是数组的基类型,我们也可以把它赋给数组元素。这种属性叫做数组协变(array covariance)。在下面情况下使用数组协变。
由于派生类和基类之间总有隐式转换,因此总是可以把派生类对象赋值给基类声明的数组。
例:派生类、基类 数组协变
class A{...} class B:A{...} class Program { static void Main() { A[] AArray1=new A[3]; A[] AArray2=new A[3]; AArray1[0]=new A();AArray1[1]=new A();AArray1[2]=new A(); AArray2[0]=new B();AArray2[1]=new B();AArray2[2]=new B(); } }
值类型数组没有协变
C#数组从System.Array类继承。它们从基类继承了很多有用的属性和方法。
public static void PrintArray(int[] a) { foreach(var x in a) { Console.WriteLine("{0}",x); } Console.WriteLine(""); } static void Main() { int[] arr=new int[]{15,20,5,25,10}; PrintArray(arr); Array.Sort(arr); PrintArray(arr); Array.Reverse(arr); PrintArray(arr); Console.WriteLine(); Console.WriteLine("Rank = {0},Length = {1}",arr.Rank,arr.Length); Console.WriteLine("GetLength(0) = {0}",arr.GetLength(0)); Console.WriteLine("GetType() = {0}",arr.GetType()); }
Clone方法为数组进行浅复制。即,它只创建了数组本身的克隆。如果是引用类型数组,它不会复制元素引用的对象。对于值类型数组和引用类型数组,效果不同。
Clone方法返回object类型的引用,它必须被强制转换成数组类型。
int[] intArr1={1,2,3}; int[] intArr2=(int[])intArr1.Clone();
例:Clone值类型数组示例
class Program { static void Main() { int[] intArr1={1,2,3}; int[] intArr2=(int[])intArr1.Clone(); intArr2[0]=100; intArr2[1]=200; intArr2[2]=300; } }
例:Clone引用类型数组示例
class A { public int Value=5; } class Program { static void Main() { A[] AArray1=new A[3]{new A(),new A(),new A()}; A[] AArray2=(A[])AArray1.Clone(); AArray2[0].Value=100; AArray2[1].Value=200; AArray2[2].Value=300; } }
下表总结了3中类型数组的重要相似点和不同点。
from: http://www.cnblogs.com/moonache/p/6255327.html
标签:重点 ase 语句 ram strong 创建表 art subarray 产生
原文地址:https://www.cnblogs.com/GarfieldEr007/p/10126580.html