C#入门(5):数组、一维数组,二维数组、交错数组、数组复制
在C#中,数组是一种用于存储相同类型元素的数据结构。数组提供了一种有序、索引访问的方式,使得可以通过索引快速访问和修改数组中的元素。在C#中,主要有一维数组和二维数组两种类型。
一维数组(Single-Dimensional Array):
一维数组是最简单的数组类型,它包含在一个单一的行中。在声明一维数组时,需要指定数组元素的类型和数组的大小。
示例代码:
// 声明和初始化一维数组
int[] myArray = new int[5]; // 声明一个包含5个整数的一维数组
// 初始化数组元素
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 3;
myArray[3] = 4;
myArray[4] = 5;
// 使用循环遍历数组元素
for (int i = 0; i < myArray.Length; i++)
{
Console.WriteLine(myArray[i]);
}
二维数组(Two-Dimensional Array):
二维数组是由行和列组成的表格状数据结构。在声明二维数组时,需要指定数组元素的类型以及数组的行数和列数。
示例代码:
// 声明和初始化二维数组
int[,] my2DArray = new int[3, 4]; // 声明一个3行4列的二维数组
// 初始化数组元素
my2DArray[0, 0] = 1;
my2DArray[0, 1] = 2;
// 依此类推...
// 使用嵌套循环遍历二维数组
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 4; col++)
{
Console.Write(my2DArray[row, col] + " ");
}
Console.WriteLine(); // 在每行结束时换行
}
在这个示例中,my2DArray
是一个3行4列的二维数组,通过两层循环遍历数组元素。
无论是一维数组还是二维数组,它们都可以包含任意类型的元素。数组在C#中是引用类型,因此它们在传递给方法时会以引用的方式传递,可以通过索引来读取或修改数组中的元素。
数组做函数参数
将一维数组和二维数组作为函数参数:
在C#中,可以将一维数组和二维数组作为函数的参数传递。当数组作为参数传递时,实际上传递的是数组的引用,因此在函数内对数组的修改会影响到原始数组。
一维数组作为函数参数:
using System;
class Program
{
static void ModifyArray(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
arr[i] *= 2; // 修改原始数组中的元素
}
}
static void Main()
{
int[] myArray = { 1, 2, 3, 4, 5 };
Console.WriteLine("Original Array:");
foreach (int num in myArray)
{
Console.Write(num + " ");
}
Console.WriteLine();
ModifyArray(myArray);
Console.WriteLine("Modified Array:");
foreach (int num in myArray)
{
Console.Write(num + " ");
}
Console.WriteLine();
}
}
二维数组作为函数参数:
using System;
class Program
{
static void Modify2DArray(int[,] arr)
{
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
arr[i, j] *= 2; // 修改原始二维数组中的元素
}
}
}
static void Main()
{
int[,] my2DArray = { { 1, 2, 3 }, { 4, 5, 6 } };
Console.WriteLine("Original 2D Array:");
for (int i = 0; i < my2DArray.GetLength(0); i++)
{
for (int j = 0; j < my2DArray.GetLength(1); j++)
{
Console.Write(my2DArray[i, j] + " ");
}
Console.WriteLine();
}
Modify2DArray(my2DArray);
Console.WriteLine("Modified 2D Array:");
for (int i = 0; i < my2DArray.GetLength(0); i++)
{
for (int j = 0; j < my2DArray.GetLength(1); j++)
{
Console.Write(my2DArray[i, j] + " ");
}
Console.WriteLine();
}
}
}
函数返回数组:
在C#中,函数可以返回一维数组或者多维数组。以下是一个返回一维数组的示例:
using System;
class Program
{
static int[] CreateArray(int size)
{
int[] newArray = new int[size];
for (int i = 0; i < size; i++)
{
newArray[i] = i + 1;
}
return newArray;
}
static void Main()
{
int[] resultArray = CreateArray(5);
Console.WriteLine("Returned Array:");
foreach (int num in resultArray)
{
Console.Write(num + " ");
}
Console.WriteLine();
}
}
对于返回二维数组的情况,也可以采用类似的方法。函数内部可以创建并初始化数组,然后将数组作为返回值返回给调用方。
交错数组
C#中的交错数组(Jagged Array)是一个数组的数组。这意味着它的每个元素都是另一个数组。交错数组与多维数组不同,因为它的行可以有不同的长度,这使得交错数组更加灵活。
交错数组的定义和初始化:
交错数组的声明类似于一维数组,但它使用额外的一组方括号 []
来指示它是一个数组的数组。下面是声明和初始化交错数组的一个例子:
using System;
class Program
{
static void Main()
{
// 声明一个交错数组
int[][] jaggedArray = new int[3][];
// 初始化交错数组的每个元素(即每行)
jaggedArray[0] = new int[4] { 1, 2, 3, 4 }; // 第一行有4个元素
jaggedArray[1] = new int[3] { 5, 6, 7 }; // 第二行有3个元素
jaggedArray[2] = new int[2] { 8, 9 }; // 第三行有2个元素
// 遍历交错数组并打印元素
for (int i = 0; i < jaggedArray.Length; i++)
{
for (int j = 0; j < jaggedArray[i].Length; j++)
{
Console.Write(jaggedArray[i][j] + " ");
}
Console.WriteLine();
}
}
}
交错数组的特点:
-
行的长度可变:交错数组的每一行可以有不同的长度,这与传统的多维数组不同。
-
灵活性:由于行的长度可以不同,交错数组提供了更高的灵活性,适合那些行长度各不相同的情况。
-
内存效率:在某些情况下,交错数组比规则的多维数组更加内存高效,尤其是当数组的某些行比其他行小得多时。
-
访问元素:访问交错数组的元素与访问一维数组类似,但需要通过两个索引——第一个索引是行的索引,第二个索引是行内的元素索引。
交错数组在处理不规则数据结构时非常有用,例如在每行数据长度不一致的表格或其他类型的数据集中。
交错数组做函数参数
在C#中,交错数组也可以作为函数的参数进行传递。由于交错数组本质上是一个数组的数组,因此在作为参数传递时,它们的处理方式与一维数组相似。
交错数组作为函数参数的示例:
以下是一个将交错数组作为参数传递给函数的例子,该示例演示了如何在函数中处理交错数组。
示例代码:
using System;
class Program
{
// 定义一个接收交错数组作为参数的函数
static void PrintJaggedArray(int[][] jaggedArr)
{
for (int i = 0; i < jaggedArr.Length; i++)
{
for (int j = 0; j < jaggedArr[i].Length; j++)
{
Console.Write(jaggedArr[i][j] + " ");
}
Console.WriteLine();
}
}
static void Main()
{
// 声明并初始化一个交错数组
int[][] myJaggedArray = new int[][]
{
new int[] { 1, 2, 3 },
new int[] { 4, 5, 6, 7 },
new int[] { 8, 9 }
};
// 调用函数并传递交错数组
PrintJaggedArray(myJaggedArray);
}
}
注意点:
-
引用传递:与一维和二维数组类似,交错数组作为参数传递给函数时,传递的是引用。因此,对函数内数组元素的任何更改都会反映到原始数组上。
-
灵活性处理:由于交错数组的每个子数组可以有不同的长度,因此在处理交错数组时,需要注意每个子数组的长度可能不同。
-
参数类型:在定义接受交错数组为参数的函数时,参数类型应该清楚地指定为交错数组类型,例如
int[][]
。
交错数组作为参数的处理方式为开发者提供了灵活地处理不规则数据结构的能力,特别是在处理行或列大小不一的复杂数据时非常有用。
数组复制
System.Array.CopyTo()
和 System.Array.Clone()
是用于数组复制的两种不同方法,它们在实现和用途上有一些区别。
System.Array.CopyTo()
方法:
CopyTo()
方法用于将数组的元素复制到另一个数组。它是 Array
类的实例方法,可以用于复制一个数组的内容到另一个数组,前提是目标数组具有足够的空间来容纳源数组的元素。
示例:
using System;
class Program
{
static void Main()
{
int[] sourceArray = { 1, 2, 3, 4, 5 };
int[] destinationArray = new int[5];
// 使用 CopyTo() 方法复制数组
sourceArray.CopyTo(destinationArray, 0);
// 输出目标数组
Console.WriteLine("Destination Array:");
foreach (int num in destinationArray)
{
Console.Write(num + " ");
}
}
}
System.Array.Clone()
方法:
Clone()
方法用于创建当前数组的浅表副本。它是 Array
类的实例方法,返回一个新数组,该数组是原始数组的浅表副本。浅表副本意味着数组元素本身被复制,但如果数组包含引用类型的元素(如对象),则引用仍然指向相同的对象。
示例:
using System;
class Program
{
static void Main()
{
int[] sourceArray = { 1, 2, 3, 4, 5 };
// 使用 Clone() 方法创建数组的浅表副本
int[] clonedArray = (int[])sourceArray.Clone();
// 修改源数组的一个元素
sourceArray[0] = 10;
// 输出两个数组
Console.WriteLine("Source Array:");
foreach (int num in sourceArray)
{
Console.Write(num + " ");
}
Console.WriteLine("\nCloned Array:");
foreach (int num in clonedArray)
{
Console.Write(num + " ");
}
}
}
区别:
-
深度复制 vs 浅表副本:
CopyTo()
执行深度复制,将源数组的元素值复制到目标数组,两者之间没有引用关系。Clone()
创建一个浅表副本,新数组的元素值与原始数组相同,但引用类型的元素仍然指向相同的对象。
-
返回类型:
CopyTo()
不返回新的数组,而是将元素复制到现有的目标数组。Clone()
返回一个新数组,该数组是原始数组的浅表副本。
-
目标数组要求:
- 在使用
CopyTo()
时,需要提供足够空间的目标数组。 - 使用
Clone()
时,不需要提供目标数组,方法会自动创建并返回一个新数组。
- 在使用
选择使用哪个方法取决于你的需求。如果需要深度复制并且已有目标数组,可以使用 CopyTo()
。如果需要创建一个新数组,且对引用类型元素的修改不影响原数组,可以使用 Clone()
。