在本文中,我们使用C#中的数组。
数组定义
数组是数据的集合。标量变量一次只能保存一个项目。另一方面,数组可以容纳多个项目。这些项目称为数组的元素。
数组存储相同数据类型的数据。每个元素都可以通过索引引用。索引是从零开始的。(第一个元素的索引为零。)数组是引用类型。
我们将数组声明为某种数据类型。Array
类包含多个用于排序、查找和修改数组元素的方法。
int[] ages; String[] names; float[] weights;
我们有三个数组声明。声明由两部分组成,数组的类型和数组名。数组的类型具有确定数组中元素类型的数据类型(在我们的例子中是int
、String
、float
)和a一对方括号[]
。括号表示我们有一个数组。
集合的用途与数组类似。它们比数组更强大。
C#初始化数组
在C#中有几种方法可以初始化数组。
int[] vals = new int[5]; vals[0] = 1; vals[1] = 2; vals[2] = 3; vals[3] = 4; vals[4] = 5; for (int i = 0; i < vals.Length; i++) { Console.WriteLine(vals[i]); }
我们声明并初始化一个数值数组。数组的内容被打印到控制台。
int[] vals = new int[5];
这里我们声明了一个包含五个元素的数组。所有元素都是整数。
vals[0] = 1; vals[1] = 2; ...
我们用一些数据初始化数组。这是赋值初始化。索引在方括号中。数字1将是数组的第一个元素,2是第二个元素。
for (int i = 0; i < vals.Length; i++) { Console.WriteLine(vals[i]); }
我们遍历数组并打印它的元素。数组具有Length
属性,它给出了数组中元素的数量。由于数组是从零开始的,因此索引为0..length-1。
我们可以在一条语句中声明和初始化一个数组。
int[] array = new int[] { 2, 4, 5, 6, 7, 3, 2 }; foreach (int i in array) { Console.WriteLine(i); }
这是先前程序的修改版本。
int[] array = new int[] {2, 4, 5, 6, 7, 3, 2 };
一个数组的声明和初始化一步到位。元素在大括号中指定。我们没有指定数组的长度。编译器会为我们做这件事。
foreach (int i in array) { Console.WriteLine(i); }
我们使用foreach
关键字遍历数组并打印其内容。
C#Array.Fill
Array.Fill
方法用给定的值填充整个数组。
int[] vals = new int[10]; Array.Fill<int>(vals, 0); Console.WriteLine(string.Join(", ", vals));
我们创建一个整数数组;该数组用零填充。
$ dotnet run 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
C#数组访问元素
创建数组后,可以通过其索引访问其元素。索引是放在方括号内的数字,紧跟数组名称。
我们可以使用indexfromend^
运算符从数组末尾获取元素。^0
等于array.Length,^n
等于array.Length-n。
string[] names = { "Jane", "Thomas", "Lucy", "David" }; Console.WriteLine(names[0]); Console.WriteLine(names[1]); Console.WriteLine(names[2]); Console.WriteLine(names[3]); Console.WriteLine("*************************"); Console.WriteLine(names[^1]); Console.WriteLine(names[^2]); Console.WriteLine(names[^3]); Console.WriteLine(names[^4]);
在示例中,我们创建了一个字符串名称数组。我们通过索引访问每个元素并将它们打印到终端。
string[] names = { "Jane", "Thomas", "Lucy", "David" };
创建了一个字符串数组。
Console.WriteLine(names[0]); Console.WriteLine(names[1]); Console.WriteLine(names[2]); Console.WriteLine(names[3]);
数组的每个元素都被打印到控制台。使用names[0]
构造,我们引用名称数组的第一个元素。
Console.WriteLine(names[^1]); Console.WriteLine(names[^2]); Console.WriteLine(names[^3]); Console.WriteLine(names[^4]);
我们从末尾访问数组元素。
$ dotnet run Jane Thomas Lucy David ************************* David Lucy Thomas Jane
C#隐式类型数组
C#可以推断数组的类型。
var vals = new[] { 1, 2, 3, 4, 5 }; var words = new[] { "cup", "falcon", "word", "water" }; Console.WriteLine(vals.GetType()); Console.WriteLine(words.GetType());
我们创建了两个隐式类型数组。
var vals = new[] { 1, 2, 3, 4, 5 };
创建了一个整数数组。我们不指定数组的类型;编译器可以从赋值的右侧推断出类型。
Console.WriteLine(vals.GetType()); Console.WriteLine(words.GetType());
使用GetType
,我们验证数组的数据类型。
$ dotnet run System.Int32[] System.String[]
C#数组修改元素
可以修改数组的元素-它们不是不可变的。
int[] vals = { 1, 2, 3, 4 }; vals[0] *= 2; vals[1] *= 2; vals[2] *= 2; vals[3] *= 2; Console.WriteLine("[{0}]", string.Join(", ", vals));
我们有一个包含三个整数的数组。每个值都将乘以二。
int[] vals = { 1, 2, 3, 4 };
创建了一个包含三个整数的数组。
vals[0] *= 2; vals[1] *= 2; vals[2] *= 2; vals[3] *= 2;
使用元素访问,我们将数组中的每个值乘以二。
Console.WriteLine("[{0}]", string.Join(", ", vals));
使用Join
方法,我们从数组的所有元素创建一个字符串。元素以逗号分隔。
$ dotnet run [2, 4, 6, 8]
所有四个整数都已乘以数字2。
C#数组切片
我们可以使用..
运算符来获取数组切片。范围指定范围的开始和结束。范围的开始是包容性的,但范围的结束是排他性的。意思是起点在范围内,终点不在范围内。
int[] vals = { 1, 2, 3, 4, 5, 6, 7 }; int[] vals2 = vals[1..5]; Console.WriteLine("[{0}]", string.Join(", ", vals2)); int[] vals3 = vals[..6]; Console.WriteLine("[{0}]", string.Join(", ", vals3)); int[] vals4 = vals[3..]; Console.WriteLine("[{0}]", string.Join(", ", vals4));
该示例适用于数组范围。
int[] vals2 = vals[1..5];
我们创建一个包含从索引1到索引4的元素的数组切片。
int[] vals3 = vals[..6];
如果省略起始索引,则切片从索引0开始。
int[] vals4 = vals[3..];
如果省略结束索引,切片将一直到数组末尾。
$ dotnet run [2, 3, 4, 5] [1, 2, 3, 4, 5, 6] [4, 5, 6, 7]
C#遍历数组
我们经常需要遍历数组的所有元素。我们展示了两种遍历数组的常用方法。
string[] planets = { "Mercury", "Venus", "Mars", "Earth", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" }; for (int i=0; i < planets.Length; i++) { Console.WriteLine(planets[i]); } foreach (string planet in planets) { Console.WriteLine(planet); }
创建了一个行星名称数组。我们使用for和foreach语句来打印所有值。
for (int i=0; i < planets.Length; i++) { Console.WriteLine(planets[i]); }
在这个循环中,我们利用了这样一个事实,即我们可以从数组对象中获取元素的数量。元素的数量存储在Length
属性中。
foreach (string planet in planets) { Console.WriteLine(planet); }
foreach语句可用于在遍历数组或其他集合时使代码更加紧凑。在每个循环中,planet变量被传递给planets数组中的下一个值。
C#将数组作为函数参数传递
数组通过引用传递给函数。这意味着可以更改原始数组的元素。
var vals = new int[] { 1, 2, 3, 4, 5 }; ModifyArray(vals); Console.WriteLine(string.Join(", ", vals)); void ModifyArray(int[] data) { Array.Reverse(data); }
我们将一个整数数组传递给ModifyArray
函数。它反转数组元素。由于传递的是对数组的引用而不是副本,因此vals
数组已更改。
$ dotnet run 5, 4, 3, 2, 1
C#数组维度
到目前为止,我们使用的是一维数组。指定元素所需的索引数称为数组的维度或等级。
二维数组
接下来,我们使用二维数组。
int[,] twodim = new int[,] { {1, 2, 3}, {1, 2, 3} }; int d1 = twodim.GetLength(0); int d2 = twodim.GetLength(1); for (int i=0; i<d1; i++) { for (int j=0; j<d2; j++) { Console.WriteLine(twodim[i, j]); } }
如果我们需要两个索引来访问数组中的一个元素,那么我们就有了一个二维数组。
int[,] twodim = new int[,] { {1, 2, 3}, {1, 2, 3} };
我们在一个语句中声明和初始化一个二维数组。注意方括号内的逗号。
int d1 = twodim.GetLength(0); int d2 = twodim.GetLength(1);
我们得到数组的维度。GetLength
获取数组指定维度中的元素数。
for (int i=0; i<d1; i++) { for (int j=0; j<d2; j++) { Console.WriteLine(twodim[i, j]); } }
我们使用两个for
循环遍历二维数组的所有元素。请注意,使用两个索引获取特定的数组元素,以逗号分隔。
$ dotnet run 1 2 3 1 2 3
我们可以用foreach循环遍历一个二维数组。
int[,] vals = new int[4, 2] { { 9, 99 }, { 3, 33 }, { 4, 44 }, { 1, 11 } }; foreach (var val in vals) { Console.WriteLine(val); }
通过foreach循环,我们从头到尾一个一个的获取元素。
$ dotnet run 9 99 3 33 4 44 1 11
三维数组
接下来,我们使用三维数组。
int[,,] n3 = { {{12, 2, 8}}, {{14, 5, 2}}, {{3, 26, 9}}, {{4, 11, 2}} }; int d1 = n3.GetLength(0); int d2 = n3.GetLength(1); int d3 = n3.GetLength(2); for (int i=0; i<d1; i++) { for (int j=0; j<d2; j++) { for (int k=0; k<d3; k++) { Console.Write(n3[i, j, k] + " "); } } } Console.Write('\n');
我们有一个数值三维数组。同样,我们用数字初始化数组并将它们打印到终端。
int[,,] n3 = { {{12, 2, 8}}, {{14, 5, 2}}, {{3, 26, 9}}, {{4, 11, 2}} };
左边的方括号和右边的大括号之间还有一个逗号。
for (int k=0; k<d3; k++) { Console.Write(n3[i, j, k] + " "); }
这个循环穿过第三个维度。我们使用三个索引从数组中检索值。
$ dotnet run 12 2 8 14 5 2 3 26 9 4 11 2
C#排名
Rank
属性给出了数组的维数。
int[] a1 = { 1, 2 }; int[,] a2 = { { 1 }, { 2 } }; int[,,] a3 = { { { 1, 2 }, { 2, 1 } } }; Console.WriteLine(a1.Rank); Console.WriteLine(a2.Rank); Console.WriteLine(a3.Rank);
我们有三个数组。我们使用Rank
属性来获取每个维度的数量。
Console.WriteLine(a1.Rank);
这里我们得到第一个数组的排名。
$ dotnet run 1 2 3
C#交错数组
具有相同大小元素的数组称为矩形数组。相反,具有不同大小元素的数组称为锯齿状数组。锯齿状数组的声明和初始化方式不同。
int[][] jagged = new int[][] { new int[] { 1, 2 }, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3, 4 } }; foreach (int[] array in jagged) { foreach (int e in array) { Console.Write(e + " "); } } Console.Write('\n');
这是一个锯齿状数组的例子。
int[][] jagged = new int[][] { new int[] { 1, 2 }, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3, 4 } };
这是一个交错数组的声明和初始化。请注意,这次我们使用了两对方括号。我们有一个数组数组。更具体地说,我们声明了一个包含三个int数据类型数组的数组。每个数组都有不同数量的元素。
foreach (int[] array in jagged) { foreach (int e in array) { Console.Write(e + " "); } }
我们使用两个foreach循环来遍历锯齿状数组。在第一个循环中,我们得到了数组。在第二个循环中,我们获取得到的数组的元素。
C#数组排序和反转
Array.sort
方法对数组元素进行就地排序。Array.Reverse
方法反转数组元素的顺序。
string[] names = {"Jane", "Frank", "Alice", "Tom" }; Array.Sort(names); foreach(string el in names) { Console.Write(el + " "); } Console.Write('\n'); Array.Reverse(names); foreach(string el in names) { Console.Write(el + " "); } Console.Write('\n');
在此示例中,我们对字符串数组进行排序和反转。
string[] names = {"Jane", "Frank", "Alice", "Tom" };
我们有一个字符串数组。
Array.Sort(names);
静态Sort
方法按字母顺序对数据进行排序。
Array.Reverse(names);
Reverse
方法反转整个一维数组中元素的顺序。
$ dotnet run Alice Frank Jane Tom Tom Jane Frank Alice
或者,我们可以使用LINQ的Order
和OrderDescending
方法对数组进行排序。
string[] names = {"Jane", "Frank", "Alice", "Tom" }; var sorted = names.Order(); foreach (var name in sorted) { Console.WriteLine(name); } Console.WriteLine("----------------------"); var sorted2 = names.OrderDescending(); foreach (var name in sorted2) { Console.WriteLine(name); }
程序按升序和降序对字符串数组进行排序。
$ dotnet run Alice Frank Jane Tom ---------------------- Tom Jane Frank Alice
C#数组GetValue&SetValue
SetValue
方法为指定位置的元素设置一个值。GetValue
获取指定位置的值。
string[] names = { "Jane", "Frank", "Alice", "Tom" }; names.SetValue("Beky", 1); names.SetValue("Erzebeth", 3); Console.WriteLine(names.GetValue(1)); Console.WriteLine(names.GetValue(3));
此示例使用SetValue
和GetValue
方法。
names.SetValue("Beky", 1); names.SetValue("Erzebeth", 3);
SetValue
为数组中的特定索引设置一个值。
Console.WriteLine(names.GetValue(1)); Console.WriteLine(names.GetValue(3));
我们使用GetValue
方法从数组中检索值。
$ dotnet run Beky Erzebeth
C#数组克隆和清除
Array.Copy
方法将值从源数组复制到目标数组。Array.Clear
删除数组的所有元素。
string[] names = {"Jane", "Frank", "Alice", "Tom"}; string[] names2 = new string[4]; Array.Copy(names, names2, names.Length); Console.WriteLine(string.Join(", ", names2)); Array.Clear(names2); Console.WriteLine(string.Join(", ", names2));
在程序中,我们创建了一个数组的副本,然后将其删除。
Array.Copy(names, names2, names.Length);
Copy
方法将值从源数组复制到目标数组。第一个参数是源数组,第二个是目标数组。第三个参数是长度;它指定要复制的元素数。
Array.Clear(names2);
Clear
方法从数组中删除所有元素。
$ dotnet run Jane, Frank, Alice, Tom , , ,
在本文中,我们使用了C#中的数组。
列出所有C#教程。