企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
{% raw %} # C# 数组 > 原文: [https://zetcode.com/lang/csharp/arrays/](https://zetcode.com/lang/csharp/arrays/) 在 C# 编程教程的这一部分中,我们将介绍数组。 我们将初始化数组并从中读取数据。 ## C# 数组定义 数组是数据的集合。 标量变量一次只能容纳一项。 数组可以容纳多个项目。 这些项目称为数组的元素。 数组存储相同数据类型的数据。 每个元素都可以由索引引用。 数组从零开始。 第一个元素的索引为零。 数组是引用类型。 数组用于存储我们应用的数据。 我们声明数组为某种数据类型。 我们指定它们的长度。 我们用数据初始化数组。 我们有几种使用数组的方法。 我们可以修改元素,对其进行排序,复制或搜索。 ```cs int[] ages; String[] names; float[] weights; ``` 我们有三个数组声明。 声明由两部分组成。 数组的类型和名称。 数组的类型具有确定数组中元素的类型(在我们的情况下为`int`,`String`,`float`)和一对方括号`[]`的数据类型。 方括号表示我们有一个数组。 集合具有相似的目的。 它们比数组更强大。 稍后将在单独的章节中进行介绍。 ## C# 初始化数组 有几种方法,如何在 C# 中初始化数组。 `Program.cs` ```cs using System; namespace InitArray { class Program { static void Main(string[] args) { int[] array = new int[5]; array[0] = 1; array[1] = 2; array[2] = 3; array[3] = 4; array[4] = 5; for (int i = 0; i < array.Length; i++) { Console.WriteLine(array[i]); } } } } ``` 我们声明并初始化一个数值数组。 数组的内容将打印到控制台。 ```cs int[] array = new int[5]; ``` 在这里,我们声明一个包含五个元素的数组。 所有元素都是整数。 ```cs array[0] = 1; array[1] = 2; ... ``` 我们用一些数据初始化数组。 这是分配初始化。 索引在方括号中。 数字 1 将成为数组的第一个元素,数字 2 将成为第二个元素。 ```cs for (int i = 0; i < array.Length; i++) { Console.WriteLine(array[i]); } ``` 我们遍历数组并打印其元素。 数组具有`Length`属性,该属性给出数组中元素的数量。 由于数组基于零,因此索引为`0..length-1`。 我们可以在一个语句中声明并初始化一个数组。 `Program.cs` ```cs using System; namespace InitArray2 { class Program { static void Main(string[] args) { int[] array = new int[] { 2, 4, 5, 6, 7, 3, 2 }; foreach (int i in array) { Console.WriteLine(i); } } } } ``` 这是先前程序的修改版本。 ```cs int[] array = new int[] {2, 4, 5, 6, 7, 3, 2 }; ``` 一步就声明并初始化一个数组。 元素在大括号中指定。 我们没有指定数组的长度。 编译器将为我们完成此任务。 ```cs foreach (int i in array) { Console.WriteLine(i); } ``` 我们使用`foreach`关键字遍历数组并打印其内容。 ## C# 数组访问元素 创建数组后,可以通过其索引访问其元素。 索引是放在数组名称后面方括号内的数字。 我们可以使用末尾`^`运算符的索引从数组末尾获取元素。 `^0`等于`array.Length`,`^n`等于`array.Length-n`。 `Program.cs` ```cs using System; namespace AccessElements { class Program { static void Main(string[] args) { 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]); } } } ``` 在示例中,我们创建一个字符串名称数组。 我们通过其索引访问每个元素,并将它们打印到终端。 ```cs string[] names = { "Jane", "Thomas", "Lucy", "David" }; ``` 将创建一个字符串数组。 ```cs Console.WriteLine(names[0]); Console.WriteLine(names[1]); Console.WriteLine(names[2]); Console.WriteLine(names[3]); ``` 数组的每个元素都打印到控制台。 在`names[0]`构造中,我们引用了名称数组的第一个元素。 ```cs Console.WriteLine(names[^1]); Console.WriteLine(names[^2]); Console.WriteLine(names[^3]); Console.WriteLine(names[^4]); ``` 我们从头开始访问数组元素。 ```cs $ dotnet run Jane Thomas Lucy David ************************* David Lucy Thomas Jane ``` 运行示例,我们得到上面的输出。 ## C# 数组修改元素 可以修改数组的元素-它们不是不可变的。 `Program.cs` ```cs using System; namespace ModifyElements { class Program { static void Main(string[] args) { int[] vals = { 1, 2, 3, 4 }; vals[0] *= 2; vals[1] *= 2; vals[2] *= 2; vals[3] *= 2; Console.WriteLine("[{0}]", string.Join(", ", vals)); } } } ``` 我们有一个由三个整数组成的数组。 每个值都将乘以 2。 ```cs int[] vals = { 1, 2, 3, 4 }; ``` 创建一个由三个整数组成的数组。 ```cs vals[0] *= 2; vals[1] *= 2; vals[2] *= 2; vals[3] *= 2; ``` 使用元素访问,我们将数组中的每个值乘以 2。 ```cs Console.WriteLine("[{0}]", string.Join(", ", vals)); ``` 使用`Join()`方法,我们从数组的所有元素中创建一个字符串。 元素用逗号分隔。 ```cs $ dotnet run [2, 4, 6, 8] ``` 所有四个整数均已乘以数字 2。 ## C# 数组切片 我们可以使用`..`运算符来获取数组切片。 范围指定范围的开始和结束。 范围的开始是包含范围的,但范围的结束是包含范围的。 这意味着起点包括在范围内,而终点不包括在范围内。 `Program.cs` ```cs using System; namespace ArrayRanges { class Program { static void Main(string[] args) { 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)); } } } ``` 该示例适用于数组范围。 ```cs int[] vals2 = vals[1..5]; ``` 我们创建一个数组切片,其中包含从索引 1 到索引 4 的元素。 ```cs int[] vals3 = vals[..6]; ``` 如果省略起始索引,则切片将从索引 0 开始。 ```cs int[] vals4 = vals[3..]; ``` 如果省略了结束索引,则切片将一直持续到数组的末尾。 ```cs $ dotnet run [2, 3, 4, 5] [1, 2, 3, 4, 5, 6] [4, 5, 6, 7] ``` 这是输出。 ## C# 遍历数组 我们经常需要遍历数组的所有元素。 我们展示了两种遍历数组的常用方法。 `Program.cs` ```cs using System; namespace Traversing { class Program { static void Main(string[] args) { 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`语句来打印所有值。 ```cs for (int i=0; i < planets.Length; i++) { Console.WriteLine(planets[i]); } ``` 在此循环中,我们利用了可以从数组对象中获取元素数量的事实。 元素数存储在`Length`属性中。 ```cs foreach (string planet in planets) { Console.WriteLine(planet); } ``` 在遍历数组或其他集合时,可以使用`foreach`语句使代码更紧凑。 在每个循环中,将行星变量传递给行星数组中的下一个值。 ## C# 数组大小 到目前为止,我们已经处理了一维数组。 指定元素所需的索引数称为数组的维或等级。 ### 二维数组 接下来,我们将处理二维数组。 `Program.cs` ```cs using System; namespace TwoDimensions { class Program { static void Main(string[] args) { 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]); } } } } } ``` 如果我们需要两个索引来访问数组中的元素,则我们有一个二维数组。 ```cs int[,] twodim = new int[,] { {1, 2, 3}, {1, 2, 3} }; ``` 我们在一个语句中声明并初始化一个二维数组。 请注意方括号内的逗号。 ```cs int d1 = twodim.GetLength(0); int d2 = twodim.GetLength(1); ``` 我们得到数组的大小。 `GetLength()`获取数组指定维中的元素数。 ```cs for (int i=0; i<d1; i++) { for (int j=0; j<d2; j++) { Console.WriteLine(twodim[i, j]); } } ``` 我们使用两个`for`循环遍历二维数组的所有元素。 请注意,使用两个索引(以逗号分隔)可获得特定的数组元素。 ```cs $ dotnet run 1 2 3 1 2 3 ``` 这是代码示例的输出。 我们可以使用`foreach`循环遍历二维数组。 `Program.cs` ```cs using System; namespace TraversingTwoDim { class Program { static void Main(string[] args) { int[,] vals = new int[4, 2] { { 9, 99 }, { 3, 33 }, { 4, 44 }, { 1, 11 } }; foreach (var val in vals) { Console.WriteLine(val); } } } } ``` 通过`foreach`循环,我们从头到尾一个一个地获取元素。 ```cs $ dotnet run 9 99 3 33 4 44 1 11 ``` This is the output. ### 三维数组 接下来,我们将处理三维数组。 `Program.cs` ```cs using System; namespace ThreeDimensions { class Program { static void Main(string[] args) { 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'); } } } ``` 我们有一个数字三维数组。 同样,我们用数字初始化数组并将其打印到终端。 ```cs int[,,] n3 = { {{12, 2, 8}}, {{14, 5, 2}}, {{3, 26, 9}}, {{4, 11, 2}} }; ``` 左侧的方括号和右侧的其他花括号之间还有另一个逗号。 ```cs for (int k=0; k<d3; k++) { Console.Write(n3[i, j, k] + " "); } ``` 该循环经过三维。 我们使用三个索引从数组中检索值。 ```cs $ dotnet run 12 2 8 14 5 2 3 26 9 4 11 2 ``` 我们将三维数组的内容打印到控制台。 ### 维数 有`Rank`属性,它提供数组的维数。 `Program.cs` ```cs using System; namespace Rank { class Program { static void Main(string[] args) { 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`属性获取每个大小的数量。 ```cs Console.WriteLine(a1.Rank); ``` 在这里,我们获得第一个数组的排名。 ```cs $ dotnet run 1 2 3 ``` 这是程序的输出。 ## C# 锯齿状数组 具有相同大小元素的数组称为矩形数组。 相反,具有不同大小元素的数组称为锯齿状数组。 锯齿状数组的声明和初始化方式不同。 `Program.cs` ```cs using System; namespace Jagged { class Program { static void Main(string[] args) { 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'); } } } ``` 这是一个锯齿状数组的示例。 ```cs int[][] jagged = new int[][] { new int[] { 1, 2 }, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3, 4 } }; ``` 这是锯齿状数组的声明和初始化。 请注意,这一次,我们使用两对方括号。 我们有一个数组数组。 更具体地说,我们已经声明了一个数组,其中包含三个`int`数据类型的数组。 每个数组具有不同数量的元素。 ```cs foreach (int[] array in jagged) { foreach (int e in array) { Console.Write(e + " "); } } ``` 我们使用两个`foreach`循环遍历锯齿状数组。 在第一个循环中,我们得到数组。 在第二个循环中,我们获取获得的数组的元素。 ## C# 数组方法 有多种使用数组的方法。 这些方法可用于检索,修改,排序,复制,搜索数据。 我们使用的这些方法是`Array`类的静态方法或数组对象的成员方法。 `Program.cs` ```cs using System; namespace Sorting { class Program { static void Main(string[] args) { 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'); } } } ``` 在此示例中,我们对数据进行排序。 ```cs string[] names = {"Jane", "Frank", "Alice", "Tom" }; ``` 我们有一个字符串数组。 ```cs Array.Sort(names); ``` 静态`Sort()`方法按字母顺序对数据进行排序。 ```cs Array.Reverse(names); ``` `Reverse()`方法反转整个一维数组中元素的顺序。 ```cs $ dotnet run Alice Frank Jane Tom Tom Jane Frank Alice ``` 我们已经按升序和降序对名称进行了排序。 以下示例使用`SeValue()`,`GetValue()`,`IndexOf()`,`Copy()`和`Clear()`方法。 `Program.cs` ```cs using System; namespace ArrayMethods { class Program { static void Main(string[] args) { string[] names = {"Jane", "Frank", "Alice", "Tom"}; string[] girls = new string[5]; names.SetValue("Beky", 1); names.SetValue("Erzebeth", 3); Console.WriteLine(names.GetValue(1)); Console.WriteLine(names.GetValue(3)); Console.WriteLine(Array.IndexOf(names, "Erzebeth")); Array.Copy(names, girls, names.Length); foreach(string girl in girls) { Console.Write(girl + " "); } Console.Write('\n'); Array.Clear(names, 0, 2); foreach(string name in names) { Console.Write(name + " "); } Console.Write('\n'); } } } ``` 本示例介绍了其他方法。 ```cs names.SetValue("Beky", 1); names.SetValue("Erzebeth", 3); ``` `SetValue()`为数组中的特定索引设置一个值。 ```cs Console.WriteLine(names.GetValue(1)); Console.WriteLine(names.GetValue(3)); ``` 我们使用`GetValue()`方法从数组中检索值。 ```cs Console.WriteLine(Array.IndexOf(names, "Erzebeth")); ``` `IndexOf()`方法返回首次出现特定值的索引。 ```cs Array.Copy(names, girls, names.Length); ``` `Copy()`方法将值从源数组复制到目标数组。 第一个参数是源数组,第二个参数是目标数组。 第三个参数是长度; 它指定要复制的元素数。 ```cs Array.Clear(names, 0, 2); ``` `Clear()`方法从数组中删除所有元素。 它包含三个参数:数组,起始索引和要从索引中清除的元素数。 ```cs $ dotnet run Beky Erzebeth 3 Jane Beky Alice Erzebeth Alice Erzebeth ``` This is the output. 在 C# 教程的这一部分中,我们使用了数组。 {% endraw %}