Array

至页首    至页尾

1.作为对象的数组

在 C# 中,数组实际上是对象,而不只是如在 C 和 C++ 中的连续内存的可寻址区域。 Array 是所有数组类型的抽象基类型。 可以使用 Array 具有的属性和其他类成员。 例如,使用 Length 属性来获取数组的长度。 以下代码可将 numbers 数组的长度 5 分配给名为 lengthOfNumbers 的变量:

int[] numbers = { 1, 2, 3, 4, 5 };
int lengthOfNumbers = numbers.Length;

Array 类可提供多种其他有用的方法和属性,用于对数组进行排序、搜索和复制。


此示例使用 Rank 属性显示数组的维数。

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.

2.一维数组

可以声明五个整数的一维数组,如以下示例所示:

int[] array = new int[5];

此数组包含从 array[0] 到 array[4] 的元素。 new 运算符用于创建数组并将数组元素初始化为其默认值。 在此示例中,所有数组元素都将被初始化为零。


可使用相同方式声明存储字符串元素的数组。 例如:

string[] stringArray = new string[6];

可以在声明时初始化数组,在这种情况下,无需秩说明符,因为它已由初始化列表中的元素数目提供。 例如:

int[] array1 = new int[] { 1, 3, 5, 7, 9 };

可使用相同方式初始化字符串数组。 下面是一个字符串数组的声明,其中每个数组元素都由一天的名称初始化:

string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

如果在声明时初始化数组,可以使用以下快捷方式:

int[] array2 = { 1, 3, 5, 7, 9 };
string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

可以在不初始化的情况下声明数组变量,但必须使用 new 运算符向此变量分配数组。 例如:

int[] array3;
array3 = new int[] { 1, 3, 5, 7, 9 };   // OK
//array3 = {1, 3, 5, 7, 9};   // Error

有关值类型和引用类型数组,请考虑以下数组声明:

SomeType[] array4 = new SomeType[10];

此语句的结果取决于 SomeType 是值类型还是引用类型。 如果它是值类型,该语句将创建一个 10 个元素的数组,其中每个元素的类型都为 SomeType。 如果 SomeType 是引用类型,该语句将创建一个 10 个元素的数组,其中每个元素都将被初始化为空引用。


3.多维数组

数组可具有多个维度。 例如,以下声明创建一个具有四行两列的二维数组。

int[,] array = new int[4, 2];

以下声明创建一个具有三个维度(4、2 和 3)的数组。

int[, ,] array1 = new int[4, 2, 3];

数组初始化
声明后即可初始化数组,如以下示例所示。

int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
                                        { "five", "six" } };

int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, 
                                 { { 7, 8, 9 }, { 10, 11, 12 } } };
                                 
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } }, 
                                       { { 7, 8, 9 }, { 10, 11, 12 } } };

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]);

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

还可在不指定秩的情况下初始化数组。

int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

如果选择在不初始化的情况下声明数组变量,则必须使用 new 运算符将数组赋予变量。 new 的用法如以下示例所示。

int[,] array5;
array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };   // OK
//array5 = {{1,2}, {3,4}, {5,6}, {7,8}};   // Error

以下示例将值赋予特定的数组元素。

array5[2, 1] = 25;

同样,以下示例将获取特定数组元素的值并将其赋予变量 elementValue。

int elementValue = array5[2, 1];

以下代码示例将数组元素初始化为默认值(交错数组除外)。

int[,] array6 = new int[10, 10];

4.交错数组

交错数组是元素为数组的数组。 交错数组元素的维度和大小可以不同。

交错数组有时称为“数组的数组”。 以下示例说明如何声明、初始化和访问交错数组。


下面声明一个具有三个元素的一维数组,其中每个元素都是一维整数数组:

int[][] jaggedArray = new int[3][];

必须初始化 jaggedArray 的元素后才可使用它。 可按下方操作初始化元素:

jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];

每个元素都是一维整数数组。 第一个元素是由 5 个整数组成的数组,第二个是由 4 个整数组成的数组,而第三个是由 2 个整数组成的数组。


也可使用初始化表达式通过值来填充数组元素,这种情况下不需要数组大小。 例如:

jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };

还可在声明数组时将其初始化,如:

    int[][] jaggedArray2 = new int[][] 
{
    new int[] {1,3,5,7,9},
    new int[] {0,2,4,6},
    new int[] {11,22}
};

可以使用下面的缩写形式。 请注意:不能从元素初始化中省略 new 运算符,因为不存在元素的默认初始化:

    int[][] jaggedArray3 = 
{
    new int[] {1,3,5,7,9},
    new int[] {0,2,4,6},
    new int[] {11,22}
};

交错数组是数组的数组,因此其元素为引用类型且被初始化为 null。


可以如下例所示访问个别数组元素:

// 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;

可以混合使用交错数组和多维数组。

下面声明和初始化一个包含大小不同的三个二维数组元素的一维交错数组。

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):

System.Console.Write("{0}", jaggedArray4[0][1, 0]);

方法 Length 返回包含在交错数组中的数组的数目。 例如,假定已声明了前一个数组,则此行:

System.Console.WriteLine(jaggedArray4.Length);

返回值 3。

5.对数组使用foreach

foreach 语句提供一种简单、明了的方法来循环访问数组的元素。


对于单维数组,foreach 语句以递增索引顺序处理元素(从索引 0 开始并以索引 Length - 1 结束):

int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 };
foreach (int i in numbers)
{
    System.Console.Write("{0} ", i);
}
// Output: 4 5 6 1 2 3 -2 -1 0

对于多维数组,遍历元素的方式为:首先增加最右边维度的索引,然后是它左边的一个维度,以此类推,向左遍历元素:

int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };
// Or use the short form:
// int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } };

foreach (int i in numbers2D)
{
    System.Console.Write("{0} ", i);
}
// Output: 9 99 3 33 5 55

但对于多维数组,使用嵌套的 for 循环可以更好地控制处理数组元素的顺序。


6.数组作为参数传递

数组可以作为实参传递给方法形参。 由于数组是引用类型,因此方法可以更改元素的值。


1.将一维数组作为参数传递
可将初始化的一维数组传递给方法。 例如,下列语句将一个数组发送给了 Print 方法。

int[] theArray = { 1, 3, 5, 7, 9 };
PrintArray(theArray);

下面的代码演示 Print 方法的部分实现。

void PrintArray(int[] arr)
{
    // Method code.
}

可在同一步骤中初始化并传递新数组,如下例所示。

PrintArray(new int[] { 1, 3, 5, 7, 9 });

2.将多维数组作为参数传递
通过与传递一维数组相同的方式,向方法传递初始化的多维数组。

int[,] theArray = { { 1, 2 }, { 2, 3 }, { 3, 4 } };
Print2DArray(theArray);

下列代码演示了 Print 方法的部分声明(该方法接受将二维数组作为其参数)。

void Print2DArray(int[,] arr)
{
    // Method code.
}

可在一个步骤中初始化并传递新数组,如下例所示:

Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } });

7.使用 ref 和 out 传递数组

与所有的 out参数一样,在使用数组类型的 out参数前必须先为其赋值,即必须由被调用方为其赋值


示例 :在此例中,在调用方(Main 方法)中声明数组 theArray,并在 FillArray 方法中初始化此数组。然后将数组元素返回调用方并显示。

class TestOut
{
    static void FillArray(out int[] arr)
    {
        //初始化数组:
        arr = new int[5] { 1, 2, 3, 4, 5 };
    }

    static void Main()
    {
        int[] theArray; // 可以不用初始化数组

        //使用out传递数组
        FillArray(out theArray);

        
        System.Console.WriteLine("数组结果:");
        for (int i = 0; i < theArray.Length; i++)
        {
            System.Console.Write(theArray[i] + " ");
        }
    }
}

output:
1
 
数组结果:
1 2 3 4 5

与所有的 ref 参数一样,数组类型的 ref参数必须由调用方明确赋值。因此不需要由接受方明确赋值。可以将数组类型的 ref 参数更改为调用的结果。例如,可以为数组赋以 null 值,或将其初始化为另一个数组。


示例 在此例中,在调用方(Main 方法)中初始化数组 theArray,并通过使用 ref 参数将其传递给 FillArray 方法。在 FillArray 方法中更新某些数组元素。然后将数组元素返回调用方并显示。

class TestRef
{
    static void FillArray(ref int[] arr)
    {
       
        if (arr == null)
        {
            arr = new int[10];
        }

        arr[0] = 1111;
        arr[4] = 5555;
    }

    static void Main()
    {
        // 必须初始化数组
        int[] theArray = { 1, 2, 3, 4, 5 };

        // 使用ref传递数组
        FillArray(ref theArray);

        
        System.Console.WriteLine("数组结果:");
        for (int i = 0; i < theArray.Length; i++)
        {
            System.Console.Write(theArray[i] + " ");
        }
    }
}

output:

数组结果:
1111 2 3 4 5555

8.隐式类型的数组

可以创建隐式类型化的数组,其中数组实例的类型通过数组初始值设定项中指定的元素来推断。


隐式类型化数组通常用于查询表达式、匿名类型、对象和集合初始值设定项。


下列示例演示如何创建隐式类型化数组:

class ImplicitlyTypedArraySample
{
    static void Main()
    {
        var a = new[] { 1, 10, 100, 1000 }; // int[]
        var b = new[] { "hello", null, "world" }; // string[]

        // single-dimension jagged array
        var c = new[]   
        {  
            new[]{1,2,3,4},
            new[]{5,6,7,8}
        };

        // jagged array of strings
        var d = new[]   
        {
            new[]{"Luca", "Mads", "Luke", "Dinesh"},
            new[]{"Karen", "Suma", "Frances"}
        };
    }
}

在上个示例中,请注意对于隐式类型化数组,初始化语句的左侧没有使用方括号。

另请注意,和一维数组一样,通过使用 new [] 来初始化交错数组。


创建包含数组的匿名类型时,必须在类型的对象初始值设定项中隐式类型化数组。

在下列示例中,contacts 是匿名类型的隐式类型化数组,每个类型都包含名为 PhoneNumbers 的数组。 请注意,不可在对象初始值设定项中使用 var 关键字。

var contacts = new[] 
{
    new {
            Name = " Eugene Zabokritski",
            PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
        },
    new {
            Name = " Hanying Feng",
            PhoneNumbers = new[] { "650-555-0199" }
        }
};

9.非零基及遍历

创建非零基数组

// 二维非零基数组
int[] lengths = { 5, 4 };
int[] lowerBounds = { 2018, 1 };
int[,] intArray = (int[,])Array.CreateInstance(typeof(int), lengths, lowerBounds);
intArray[2018, 1] = 1;
intArray[2022, 4] = 20;
Console.WriteLine($"{intArray[2018, 1]}, {intArray[2022, 4]}");

// 一维非零基数组
Array a = Array.CreateInstance(typeof(int), new int[] { 2 }, new int[] { 20 });
a.SetValue(100, 20);
a.SetValue(200, 21);
Console.WriteLine($"{a.GetValue(20)}, {a.GetValue(21)}");

获取数组的行列数遍历数组

// 多维数组
int[,] b = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
for (int i = 0; i < b.GetLength(0); i++)
{
    for (int j = 0; j < b.GetLength(1); j++)
    {
        Console.Write(b[i, j] + " ");
    }
    Console.WriteLine();
}
Console.WriteLine("**********");
// 包含多维数组的交错数组
int[][,] a = new int[3][,]
{
    new int[,] { { 1, 3 }, { 5, 7 } },
    new int[,] { { 1, 2 }, { 3, 4 } },
    new int[,] { { 1, 2, 1 }, { 3, 4, 6 }, { 3, 1, 1 } }
};
for (int i = 0;i<a.Length;i++)
{
    for(int j = 0;j< a[i].GetLength(0);j++)
    {
        for(int k = 0;k< a[i].GetLength(1);k++)
        {
            Console.Write(a[i][j, k] + " ");
        }
        Console.WriteLine();
    }
    Console.WriteLine("----------");
}

至目录    至页首

原文地址:https://www.cnblogs.com/jizhiqiliao/p/10649042.html