可以在一个数组数据结构中存储同一类型的多个变量。 通过指定其元素的类型声明数组。
type[] arrayName;
下面的示例创建一维、多维和交错数组:
C#
class TestArraysClass
{
static void Main()
{
// Declare a single-dimensional array
int[] array1 = new int[5];
// Declare and set array element values
int[] array2 = new int[] { 1, 3, 5, 7, 9 };
// Alternative syntax
int[] array3 = { 1, 2, 3, 4, 5, 6 };
// Declare a two dimensional array
int[,] multiDimensionalArray1 = new int[2, 3];
// Declare and set array element values
int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };
// Declare a jagged array
int[][] jaggedArray = new int[6][];
// Set the values of the first array in the jagged array structure
jaggedArray[0] = new int[4] { 1, 2, 3, 4 };
}
}
数组概述
数组具有以下属性:
- 数组可以是一维、多维或交错的。
- 当创建了数组实例时,将建立维度数和每个维度的长度。 在实例的生存期内,这些值不能更改。
- 数值数组元素的默认值设置为零,而引用元素的默认值设置为 null。
- 交错数组是数组的数组,因此其元素是引用类型并初始化为 null。
- 数组的索引从零开始:具有 n 个元素的数组的索引是从 0 到 n-1。
- 数组元素可以是任何类型,包括数组类型。
- 数组类型是从抽象基类型 Array 派生的引用类型。 由于此类型实现了 IEnumerable 和 IEnumerable,因此可以对 C# 中的所有数组使用 foreach 迭代。
作为对象的数组
在 C# 中,数组实际上是对象,而不只是像 C 和 C++ 中那样的可寻址连续内存区域。 Array 是所有数组类型的抽象基类型。 可以使用 Array 具有的属性以及其他类成员。 这种用法的一个示例是使用 Length 属性来获取数组的长度。 下面的代码将 numbers 数组的长度(为 5)赋给名为 lengthOfNumbers 的变量:
C#
int[] numbers = { 1, 2, 3, 4, 5 };
int lengthOfNumbers = numbers.Length;
Array 类提供了许多其他有用的方法和属性,用于排序、搜索和复制数组。
示例
此示例使用 Rank 属性来显示数组的维数。
C#
class TestArraysClass
{
static void Main()
{
// Declare and initialize an array:
int[,] theArray = new int[5, 10];
System.Console.WriteLine("The array has {0} dimensions.", theArray.Rank);
}
}
// Output: The array has 2 dimensions.
一维数组
可按下面的示例所示声明五个整数的一维数组。
C#
int[] array = new int[5];
此数组包含从 array[0] 到 array[4] 的元素。 new 运算符用于创建数组并将数组元素初始化为它们的默认值。 在此例中,所有数组元素都初始化为零。
可以用相同的方式声明存储字符串元素的数组。 例如:
C#
string[] stringArray = new string[6];
数组初始化
可以在声明数组时将其初始化,在这种情况下不需要级别说明符,因为级别说明符已经由初始化列表中的元素数提供。 例如:
C#
int[] array1 = new int[] { 1, 3, 5, 7, 9 };
可以用相同的方式初始化字符串数组。 下面声明一个字符串数组,其中每个数组元素用每天的名称初始化:
C#
string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
如果在声明数组时将其初始化,则可以使用下列快捷方式:
C#
int[] array2 = { 1, 3, 5, 7, 9 };
string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
可以声明一个数组变量但不将其初始化,但在将数组分配给此变量时必须使用 new 运算符。 例如:
C#
int[] array3;
array3 = new int[] { 1, 3, 5, 7, 9 }; // OK
//array3 = {1, 3, 5, 7, 9}; // Error
C# 3.0 引入了隐式类型的数组。
值类型数组和引用类型数组
请看下列数组声明:
C#
SomeType[] array4 = new SomeType[10];
该语句的结果取决于 SomeType 是值类型还是引用类型。 如果为值类型,则语句将创建一个有 10 个元素的数组,每个元素都有 SomeType 类型。 如果 SomeType 是引用类型,则该语句将创建一个由 10 个元素组成的数组,其中每个元素都初始化为空引用。
多维数组
数组可以具有多个维度。 例如,下列声明创建一个四行两列的二维数组。
C#
int[,] array = new int[4, 2];
下列声明创建一个三维(4、2 和 3)数组。
C#
int[, ,] array1 = new int[4, 2, 3];
数组初始化
可以在声明数组时将其初始化,如下例所示。
C#
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// Accessing array elements.
System.Console.WriteLine(array2D[0, 0]);
System.Console.WriteLine(array2D[0, 1]);
System.Console.WriteLine(array2D[1, 0]);
System.Console.WriteLine(array2D[1, 1]);
System.Console.WriteLine(array2D[3, 0]);
System.Console.WriteLine(array2Db[1, 0]);
System.Console.WriteLine(array3Da[1, 0, 1]);
System.Console.WriteLine(array3D[1, 1, 2]);
// Getting the total count of elements or the length of a given dimension.
var allLength = array3D.Length;
var total = 1;
for (int i = 0; i < array3D.Rank; i++) {
total *= array3D.GetLength(i);
}
System.Console.WriteLine("{0} equals {1}", allLength, total);
// Output:
// 1
// 2
// 3
// 4
// 7
// three
// 8
// 12
// 12 equals 12
也可以初始化数组但不指定级别。
C#
int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
如果选择声明一个数组变量但不将其初始化,必须使用 new 运算符将一个数组分配给此变量。 以下示例显示 new 的用法。
C#
int[,] array5;
array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // OK
//array5 = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error
以下示例将值分配给特定的数组元素。
C#
array5[2, 1] = 25;
同样,下面的示例获取特定数组元素的值,并将它赋给变量elementValue。
C#
int elementValue = array5[2, 1];
以下代码示例将数组元素初始化为默认值(交错数组除外):
C#
int[,] array6 = new int[10, 10];
交错数组
交错数组是元素为数组的数组。交错数组元素的维度和大小可以不同。交错数组有时称为“数组的数组”。以下示例说明如何声明、初始化和访问交错数组。
下面声明一个由三个元素组成的一维数组,其中每个元素都是一个一维整数数组:
C#
int[][] jaggedArray = new int[3][];
必须初始化 jaggedArray 的元素后才可以使用它。可以如下例所示初始化该元素:
C#
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];
每个元素都是一个一维整数数组。第一个元素是由 5 个整数组成的数组,第二个是由 4 个整数组成的数组,而第三个是由 2 个整数组成的数组。
也可以使用初始值设定项用值填充数组元素,在这种情况下不需要数组大小。例如:
C#
jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };
还可以在声明数组时将其初始化,如:
C#
int[][] jaggedArray2 = new int[][]
{
new int[] {1,3,5,7,9},
new int[] {0,2,4,6},
new int[] {11,22}
};
可以使用下面的速记格式。请注意:不能从元素初始化中省略 new 运算符,因为不存在元素的默认初始化:
C#
int[][] jaggedArray3 =
{
new int[] {1,3,5,7,9},
new int[] {0,2,4,6},
new int[] {11,22}
};
交错数组是数组的数组,因此其元素是引用类型并初始化为 null。
可以如下例所示访问个别数组元素:
C#
// Assign 77 to the second element ([1]) of the first array ([0]):
jaggedArray3[0][1] = 77;
// Assign 88 to the second element ([1]) of the third array ([2]):
jaggedArray3[2][1] = 88;
可以混合使用交错数组和多维数组。下面声明和初始化一个一维交错数组,该数组包含大小不同的三个二维数组元素。
C#
int[][,] jaggedArray4 = new int[3][,]
{
new int[,] { {1,3}, {5,7} },
new int[,] { {0,2}, {4,6}, {8,10} },
new int[,] { {11,22}, {99,88}, {0,9} }
};
可以如本例所示访问个别元素,该示例显示第一个数组的元素 [1,0] 的值(值为 5):
C#
System.Console.Write("{0}", jaggedArray4[0][1, 0]);
方法 Length 返回包含在交错数组中的数组的数目。例如,假定您已声明了前一个数组,则此行:
C#
System.Console.WriteLine(jaggedArray4.Length);
返回值 3。
本例生成一个数组,该数组的元素为数组自身。每一个数组元素都有不同的大小。
C#
class ArrayTest
{
static void Main()
{
// Declare the array of two elements:
int[][] arr = new int[2][];
// Initialize the elements:
arr[0] = new int[5] { 1, 3, 5, 7, 9 };
arr[1] = new int[4] { 2, 4, 6, 8 };
// Display the array elements:
for (int i = 0; i < arr.Length; i++)
{
System.Console.Write("Element({0}): ", i);
for (int j = 0; j < arr[i].Length; j++)
{
System.Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " ");
}
System.Console.WriteLine();
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
Element(0): 1 3 5 7 9
Element(1): 2 4 6 8
*/
将数组作为参数传递
数组可作为实参传递给方法形参。由于数组是引用类型,因此方法可以更改元素的值。
将一维数组作为参数传递
可以将初始化的一维数组传递给方法。例如,下面的语句将数组发送到 print 方法。
C#
int[] theArray = { 1, 3, 5, 7, 9 };
PrintArray(theArray);
下面的代码显示 print 方法的部分实现。
C#
void PrintArray(int[] arr)
{
// Method code.
}
您可以在一个步骤中初始化和传递新数组,如下面的示例所示。
C#
PrintArray(new int[] { 1, 3, 5, 7, 9 });
示例
说明
在下面的示例中,将初始化一个字符串数组并将其作为参数传递到字符串的 PrintArray 方法。该方法显示数组的元素。接下来,调用 ChangeArray 和 ChangeArrayElement 方法以演示通过值发送数组参数时不会阻止更改这些数组元素。
代码
C#
class ArrayClass
{
static void PrintArray(string[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
System.Console.Write(arr[i] + "{0}", i < arr.Length - 1 ? " " : "");
}
System.Console.WriteLine();
}
static void ChangeArray(string[] arr)
{
// The following attempt to reverse the array does not persist when
// the method returns, because arr is a value parameter.
arr = (arr.Reverse()).ToArray();
// The following statement displays Sat as the first element in the array.
System.Console.WriteLine("arr[0] is {0} in ChangeArray.", arr[0]);
}
static void ChangeArrayElements(string[] arr)
{
// The following assignments change the value of individual array
// elements.
arr[0] = "Sat";
arr[1] = "Fri";
arr[2] = "Thu";
// The following statement again displays Sat as the first element
// in the array arr, inside the called method.
System.Console.WriteLine("arr[0] is {0} in ChangeArrayElements.", arr[0]);
}
static void Main()
{
// Declare and initialize an array.
string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
// Pass the array as an argument to PrintArray.
PrintArray(weekDays);
// ChangeArray tries to change the array by assigning something new
// to the array in the method.
ChangeArray(weekDays);
// Print the array again, to verify that it has not been changed.
System.Console.WriteLine("Array weekDays after the call to ChangeArray:");
PrintArray(weekDays);
System.Console.WriteLine();
// ChangeArrayElements assigns new values to individual array
// elements.
ChangeArrayElements(weekDays);
// The changes to individual elements persist after the method returns.
// Print the array, to verify that it has been changed.
System.Console.WriteLine("Array weekDays after the call to ChangeArrayElements:");
PrintArray(weekDays);
}
}
// Output:
// Sun Mon Tue Wed Thu Fri Sat
// arr[0] is Sat in ChangeArray.
// Array weekDays after the call to ChangeArray:
// Sun Mon Tue Wed Thu Fri Sat
//
// arr[0] is Sat in ChangeArrayElements.
// Array weekDays after the call to ChangeArrayElements:
// Sat Fri Thu Wed Thu Fri Sat
将多维数组作为参数传递
可采用与传递一维数组相同的方式将初始化的多维数组传递给方法。
C#
int[,] theArray = { { 1, 2 }, { 2, 3 }, { 3, 4 } };
Print2DArray(theArray);
下面的代码显示 print 方法的部分声明,该方法接受一个二维数组作为其参数。
C#
void Print2DArray(int[,] arr)
{
// Method code.
}
您可以在一个步骤中初始化和传递新数组,如下面的示例所示。
C#
Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } });
示例
说明
在下面的示例中,将初始化一个二维整数数组并将其传递到 Print2DArray 方法。该方法显示数组的元素。
代码
C#
class ArrayClass2D
{
static void Print2DArray(int[,] arr)
{
// Display the array elements.
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
System.Console.WriteLine("Element({0},{1})={2}", i, j, arr[i, j]);
}
}
}
static void Main()
{
// Pass the array as an argument.
Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } });
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
/* Output:
Element(0,0)=1
Element(0,1)=2
Element(1,0)=3
Element(1,1)=4
Element(2,0)=5
Element(2,1)=6
Element(3,0)=7
Element(3,1)=8
*/