# 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# 教程的这一部分中，我们使用了数组。