数组是一种数据结构,它包含若干相同类型的变量。数组的定义是:在内存中连续开辟的空间,该空间中存储着一组相同数据类型的值。
数组具有以下属性:
数组可以是一维、多维或交错的。
数值数组元素的默认值设置为零,而引用元素的默认值设置为 null。
交错数组是数组的数组,因此,它的元素是引用类型,初始化为 null。
数组的索引从零开始:具有 n 个元素的数组的索引是从 0 到 n-1。
数组元素可以是任何类型,包括数组类型。
数组的声明是使用“[]”对数据类型修饰,并在声明的同时,告诉编译器,我们需要在内存中开辟的空间可以存储多少个值。数组中的值,我们称为数组的元素。
int[] iarr=new int[6];
上述就是一个整型数组的声明。int[]告诉编译器,我们声明一个整数数组,该数组中只能存储整型值。iarr是变量名称。new int[6]就是告诉编译器,我们需要在内存中开辟的空间能存储6个整型值。
数组的大小一旦被定义后,就不可以再被更改。同时编译器为数组中的每一个元素依次配给一个标记,该标记叫下标。你可以想象下酒店的情况,在一层楼上有20个房间,每个房间都有一个门牌号,房间一旦完成隔离就不可以再更改了,除非这层楼全面重新设计布局。
数组的下标是从0开始分配的,这个和我们平常的生活有所不同,我们的门牌号大多都是1开始计数,初学者必须要习惯C#喜欢从0开始计数的怪异脾气。所以下标的最大值总要比数组中元素的总数小1。
对数组中具体的元素的访问,我们必须通过下标实现:
static void Main(string[] args)
{
int[] iarr = new int[6];
iarr[0] = 2;
iarr[1] = 23;
iarr[2] = 4;
iarr[3] = 2;
iarr[4] = 7;
iarr[5] = 10;
System.Console.WriteLine(iarr[4]); //输出下标为4的元素的值
}
运行的结果如图3.1.1。
图3.1.1 显示数组中指定的元素值
我们也可以在声明的时候为数组的每一个元素赋值,如果使用这种模式,就不必再显示的描述元素的个数,编译器能推测出元素的个数。
static void Main(string[] args)
{
int[] iarr = new int[] { 2, 23, 4, 2, 7, 10 };
System.Console.WriteLine(iarr[4]); //输出下标为4的元素的值
}
数组是连续分配的空间,下标的分配也是连续的,从上述代码我们可以发现使用迭代循环是访问数组的好方法。
static void Main(string[] args)
{
int[] iarr = new int[] { 2, 23, 4, 2, 7, 10 };
for (int i = 0; i <= iarr.Length - 1; i++)
{
System.Console.WriteLine(iarr[i]);
}
}
Length是数组的属性,该属性能告诉我们当前数组声明的元素个数。上述代码的输出结果如图3.1.2。
图3.1.2遍历数据中的每一个元素
虽然说,数组的定义是在内存中连续分配的空间,但是在 C# 中,数组实际上是对象,而不只是像 C 和 C++ 中那样的可寻址连续内存区域。Array 是所有数组类型的抽象基类型,可以使用 Array 具有的属性以及其他类成员。比如使用Array数组可以非常方便的对数组类型的值进行排序。
static void Main(string[] args)
{
int[] iarr = new int[6];
iarr[0] = 2;
iarr[1] = 23;
iarr[2] = 4;
iarr[3] = 2;
iarr[4] = 7;
iarr[5] = 10;
Array.Sort(iarr); //升序排序
for (int i = 0; i <= iarr.Length - 1; i++)
{
System.Console.WriteLine(iarr[i]);
}
}
排序后的输出结果如图3.1.3。
图3.1.3 Sort结果
C#没有提供降序的排序方法,不过呢,C#提供了一种方式将数组中的值反转它们的顺序。
static void Main(string[] args)
{
int[] iarr = new int[6];
iarr[0] = 2;
iarr[1] = 23;
iarr[2] = 4;
iarr[3] = 2;
iarr[4] = 7;
iarr[5] = 10;
Array.Reverse(iarr); //反转数组中元素的顺序
for (int i = 0; i <= iarr.Length - 1; i++)
{
System.Console.WriteLine(iarr[i]);
}
}
上述代码的结果如图3.1.4。
图3.1.4 Reverse结果
可以观察Sort和Reverse的结果。如果你有足够的联想力的话,也许你会想到以下的代码来解决降序的排序方案:
static void Main(string[] args)
{
int[] iarr = new int[6];
iarr[0] = 2;
iarr[1] = 23;
iarr[2] = 4;
iarr[3] = 2;
iarr[4] = 7;
iarr[5] = 10;
Array.Sort(iarr); //升序排序
Array.Reverse(iarr); //反转数组中元素的顺序
for (int i = 0; i <= iarr.Length - 1; i++)
{
System.Console.WriteLine(iarr[i]);
}
}
以下就是数组中元素降序排序的结果,如图3.1.5所示。
图3.1.5 降序排序结果
如果我们需要了解某一个值是否在数组的一系列元素中存在,我们不必遍历数组中的每一个元素,C#的数组类提供了IndexOf方法,该方法返回指定的元素值在数组中第一次出现的下标位置,如果该值不存在,则返回-1。下面的代码描述了如何使用IndexOf方法查找数组中元素的值。
static void Main(string[] args)
{
int[] iarr = new int[6];
iarr[0] = 2;
iarr[1] = 23;
iarr[2] = 4;
iarr[3] = 2;
iarr[4] = 7;
iarr[5] = 10;
System.Console.WriteLine(Array.IndexOf(iarr, 7));
System.Console.WriteLine(Array.IndexOf(iarr, 20));
}
得到的结果如图3.1.6。
图3.1.6 IndesOf结果
如果我们使用目前的所有知识来模拟IndexOf的方法,大致的代码如下:
static void Main(string[] args)
{
int[] iarr = new int[6];
iarr[0] = 2;
iarr[1] = 23;
iarr[2] = 4;
iarr[3] = 2;
iarr[4] = 7;
iarr[5] = 10;
System.Console.WriteLine(MyIndexOf(iarr,7));
System.Console.WriteLine(MyIndexOf(iarr,20));
}
public static int MyIndexOf(int[] iarr, int value)
{
for (int i = 0; i <= iarr.Length - 1; i++)
{
if (iarr[i] == value)
{
return i;
}
}
return -1;
}
我们自己编写的MyIndexOf方法的执行模式的效果和Array的IndexOf方法是一致的。当然我们可以编写LastIndexOf方法,代码的实现如下:
public static int MyLastIndexOf(int[] iarr, int value)
{
int index = -1;
for (int i = 0; i <= iarr.Length - 1; i++)
{
if (iarr[i] == value)
{
index = i; ;
}
}
return index; ;
}
如果可以的话,你还可以编写的函数看看自己是否能灵活运用。
public static int MyIndexOf(int[] iarr, int value, int start, int end)
{
end = end < iarr.Length ? end : iarr.Length;
for (int i = start; i < end; i++)
{
if (iarr[i] == value)
{
return i;
}
}
return -1;
}
初学者注意
使用自己的编程知识,模拟.NET Framework提供的方法,是一种很有效的学习方法。