在本文中,我们使用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#教程。
