【c# .net】数组(Array)
C# 数组(Array)
文章目录:
- C# 数组
- 一维数组
- 多维数组
- 交错数组
- Array类
- 参数数组
1.简介
数组是一个存储相同类型元素且固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。
所有的数组都是由连续的内存位置组成,最低的下标对应第一个元素,最高的下标对应最后一个元素。
2.数组的声明
在 C# 中声明一个数组,可以使用下面的语法:
datatype[ ] arrayName;
- datatype 指定被存储在数组中的元素的类型
- [ ] 指定数组的秩(维度),秩是指数组的维数,如一维数组的秩为1,二维数组的秩为2
- arrayName 指定数组的名称
3.特性介绍
1) 数组是引用类型而不是值类型 。
2) 数组的容量为固定值,无法修改 ,如果要增减容量,必须创建新数组,将旧数组的元素复制到新数组中,并删除旧数组。
3) 数组不会自动排序 ,默认按照初始化时排列顺序排序。
4)多维数组可以为每个维度提供不同的界限, 最多可以有 32 个维度 。
5)数组中的元素不可为 null ,否则编译时会报错 。
6)数组的长度为元素的总数,长度为 Length-1 ,超出长度编译时会报错。
一 . 一维数组
datatype[ ] arrayName;
一维数组的元素个数称为一维数组的长度。
一维数组长度为 0 时,我们称之为空数组。一维数组的索引从零开始,具有n个元素的一维数组的索引是从 0 到 n-1 。
当创建一个数组时,编译器会根据数组类型隐式初始化每个数组元素为一个默认值。例如,int 数组的所有元素都会被初始化为 0。
1.一维数组的声明和创建形式:
数组类型 [ ] 数组名 = new 数组类型 [数组长度]
//表示声明和创建一个具有5个数组元素的一维数组a
int [ ] one = new int [ 5 ] ;
2.一维数组的初始化:
1)在创建时初始化
int [ ] one = new int [5] { 1, 2, 3, 4, 5 }; //数组大小必须与花括号中的元素个数相匹配,否则编译会报错
int [ ] one = new int [ ] { 1,2,3,4,5 } ;
int [ ] one = { 1,2,3,4,5 } ;
2)先声明后初始化
int [ ] one;
one = new int [ ] { 1,2,3,4,5 } ;
one ={ 1,2,3,4,5 } ;
3)先创建后初始化
int [ ] one = new int [ 2 ];
one[ 0 ] = 1 ;
one[ 1 ] = 2 ;
3.遍历数组
int[] one = { 0, 1, 2, 3 };
Console.WriteLine("one 秩:{0},长度:{1}", one.Rank, one.Length);
Console.WriteLine("遍历一维数组:one ");
foreach (var item in one) Console.WriteLine(item);
运行结果:
二 . 多维数组
datatype[ ,... ] arrayName;
多维数组需要使用 多个元素索引才能确定数组元素的位置 。
声明多维数组时,必须明确定义维度数、各维度的长度、数组元素的数据类型 。
多维数组的 元素总数是各维度的长度的乘积 。
例如:如果二维数组a的两个维度的长度分别为2和3,则该数组的元素总数为6。
1.多维数组的声明和创建形式:
数组类型 [ 维度 ] 数组名 = new 数组类型 [ 维度长度 ];
//表示声明和创建一个具有 5×4×3 共60个数组元素的三维数组a
int [ , , ] tow = new int [ 5 , 4, 3 ] ;
2,多维数组的初始化需要注意以下几点:
1)以维度为单位组织初始化值,同一维度的初始值放在一对花括号之中
int [ , ] tow = new int [ 2, 3 ] { { 1, 1, 1 } , { 2, 2, 2 } } ;
2)可以省略维度长度列表,系统能够自动计算维度和维度的长度。但注意,逗号不能省略
int[ , ] tow = new int[ , ] { { 1, 2, 3 } , { 4, 5, 6 } };
3)初始化多维数组可以使用简写格式
int [ , ] tow = { { 1, 2, 3 } , { 4, 5, 6 } } ;
4)不允许部分初始化
//只初始化二维数组的第一列元素,这是不允许的
//错误例子:
int [ , ] tow = new int [ 2, 3 ] { { 1 } , { 4 } } ;
5)可以 先创建 再初始化,但不建议这样使用,因为会非常麻烦
注意: 声明时 不需要 指定内存, 创建时 需要 指定内存
//先创建后初始化需要通过下标一个一个赋值
int[ , ] tow = new int[2, 3] ;
tow[0, 0] = 1;
tow[0, 1] = 2;
tow[0, 2] = 3;
tow[1, 0] = 4;
tow[1, 1] = 5;
tow[1, 2] = 6;
//错误例子:
int[ , ] tow2 = new int[2, 3];
tow2 = { { 1, 1, 1 }, { 2, 2, 2 } };
6)可以先声明,再初始化
int[ , ] tow;
tow = new int[2, 3] { { 1, 1, 1 }, { 2, 2, 2 } };
3.遍历数组
int[,] tow;
tow = new int[2,3] { { 1, 1, 1 }, { 2, 2, 2 } };
Console.WriteLine("tow 秩:{0} ,长度:{1}", tow.Rank, tow.Length);
Console.WriteLine("遍历多维数组:tow ");
//无论有多少维,都能使用 foreach 循环遍历
foreach (var item in tow) Console.WriteLine(item);
运行结果:
三 . 交错数组
datatype[ , ... ][ , ... ] arrayName;
交错数组是一种由若干个数组构成的数组。为了便于理解,我们把包含在数组中的数组称为子数组。
1.交错数组的声明和创建形式:
数组类型 [ 维度 ] [ 子数组维度 ] 数组名 = new 数组类型 [ 维度长度 ] [ 子数组维度 ] ;
//表示创建了由2个一维子数组构成一维数组a
//注意:省略维度为一维数组,省略子数组维度表示子数组为一维数组
int [ ] [ ] a = new int [ 2 ] [ ] ;
//交错数组中的元素也可以是多维数组
//表示创建了由3个二维子数组构成的一维数组a2
int [ ] [ , ] a2 = new int [ 3 ] [ , ] ;
//注意:在声明数组型的数组时,不能指定子数组的长度
//错误例子:
int [ ] [ ] a3 = new int [ 2 ] [ 3 ] ;
//多维交错数组的子数组也可以是多维数组
//声明时需要为每个纬度分配长度,但子数组不可指定长度
//表示创建了由 4x5 共 20 个 三维子数组构成的二维数组a4
int[ , ] [ , , ] a4 = new int [ 4 , 5 ] [ , , ];
2.交错数组的初始化:
交错数组同样有多种初始化方式,包括创建时初始化、先声明后初始化等。
注意:初始化交错数组时, 每个元素的 new 运算符都不能省略
1)创建时初始化可省略维度长度
//表示创建由2个一维子数组构成的数组a
int [ ] [ ] a = new int [ ] [ ] { new int [ ] { 1, 2, 3 } , new int [ ] { 4, 5, 6 } ;
2)先声明后初始化更加直观
//声明由3个一维子数组构成的数组a
int [ ] [ ] a = new int [ 3 ] [ ] ;
a[0] = new int [3] { 1, 2, 3 };
//子数组在 new 时可以不指定长度
a[1] = new int [ ] { 1, 2, 3 };
//子数组的长度可以不相同
a[2] = new int [5] { 4, 5, 6, 7, 8 };
3.遍历数组
int[][] three = new int[3][];
three[0] = new int[] { 1, 2 };
three[1] = new int[3] { 3, 4, 5 };
three[2] = new int[] { 6 };
Console.WriteLine("three 秩:{0} ,长度:{1}", three.Rank, three.Length);
Console.WriteLine("遍历交错数组:three ");
//无论多少维,只需要使用两个 foreach 嵌套遍历
foreach (var item in three)
foreach (var item2 in item) Console.WriteLine(item2);
运行结果:
四.Array类
1.简介
Array 类是 C# 中 所有数组的基类 ,它是在 System 命名空间中定义。Array 类提供了各种用于数组的属性和方法。
Array 类是抽象类,无法 new ,只能继承 。
Array 类的方法和属性
1) Array 类的一些常用的 属性 :
属性 | 描述 |
---|---|
IsFixedSize | 大小是否固定 |
IsReadOnly | 是否只读 |
Length | 获取数组中的元素总数(值为32位整数) |
LongLength | 获取数组中的元素总数(值为64位整数) |
Rank | 获取数组的秩(维度) |
2) Array 类的一些常用的 方法 :
方法 | 描述 |
---|---|
object GetValue (int index); | 获取一维 Array 中指定位置的值 |
object? GetValue (int[] indices); | 获取多维 Array 中指定位置的值,int[] indices 为一维数组,表示指定位置的索引 |
int GetLowerBound (int dimension); | 获取 Array 指定维度第一个元素的索引 |
int GetUpperBound (int dimension); | 获取 Array 指定维度最后一个元素的索引 |
int GetLength(int dimension); | 获取指定维度中的所有元素总数(值为32位整数) |
long GetLongLength(int dimension); | 获取指定维度中的所有元素总数(值为64位整数) |
bool Equals(object object); | 确定指定对象是否等于当前对象 |
void SetValue (object value, int index); | 设置一维 Array 中指定位置元素的值 |
void SetValue (object? value, params int[] indices); | 设置多维 Array 中指定位置元素的值,int[] indices 是一维数组,它表示指定位置的索引 |
void CopyTo(Array array, int index); | 将当前一维数组的所有元素复制到指定的一维数组的指定索引处 |
3) Array 类的一些常用的 静态方法 :
静态方法 | 描述 |
---|---|
void Sort (Array array); | 对一维 Array 进行排序 |
void Sort (Array keys, Array items); | 基于第一个 Array 的值,对两个一维 Array 进行排序 |
void Sort (Array array, int index, int length); | 对一维 Array 中指定范围元素进行排序 |
void Reverse (Array array); | 反转一维 Array 中所有元素的顺序 |
void Reverse (Array array, int index, int length); | 反转一维 Array 中指定范围元素的顺序 |
int IndexOf (Array array, object? value); | 搜索一维 Array 指定对象,返回首个索引 |
int IndexOf (Array array, object? value, int startIndex, int count); | 从指定索引范围搜索一维 Array 指定对象,返回首个索引 |
int LastIndexOf (Array array, object? value); | 搜索一维 Array 指定对象,返回最后索引 |
int LastIndexOf (Array array, object? value, int startIndex, int count); | 从指定索引范围搜索一维 Array 指定对象,返回最后索引 |
void Copy(Array array, int index, Array array, int index, int length); | 复制指定范围的元素到另一个 Array 指定索引处 |
void Resize (ref T[]? array, int newSize); | 将一维 Array 元素总数更改为指定的新大小 |
void Clear(Array array, int index , int length); | 将 Array 某个范围的元素设置为每个元素类型的默认值 |
代码演示
注意:为了方便阅读,以下将代码拆分为多段进行演示,实际运行可以把代码直接拼接起来
using System;
namespace 数组
class Program
static void Main(string[] args)
ArrayTest2();
//为了方便验证数据,首先封装两个遍历元素的方法
/// <summary>
/// 遍历多维数组中的所有元素
/// </summary>
static void FTest(Array array)
foreach (var item in array) Console.Write(" " + item);
Console.WriteLine("\n ----------------------\n");
/// <summary>
/// 遍历交错数组中的所有元素
/// </summary>
static void FTest2(Array array)
foreach (var item in array)
Array array1 = item as Array;
FTest(array1);
static void ArrayTest2()
//创建一维数组
int[] one = { 0, 1, 2, 3 };
//创建三维数组
int[,,] tow = new int[2, 3, 2];
tow[0, 0, 0] = 1;
tow[0, 1, 0] = 2;
tow[0, 2, 0] = 3;
tow[0, 0, 1] = 4;
tow[0, 1, 1] = 5;
tow[0, 2, 1] = 6;
tow[1, 0, 0] = 7;
tow[1, 1, 0] = 8;
tow[1, 2, 0] = 9;
tow[1, 0, 1] = 10;
tow[1, 1, 1] = 11;
tow[1, 2, 1] = 12;
//创建二维交错数组,子数组为二维数组
int[,][,] three = new int[3, 2][,];
three[0, 0] = new int[2, 1] { { 0 }, { 1 } };
three[0, 1] = new int[3, 1] { { 2 }, { 3 }, { 4 } };
three[1, 0] = new int[2, 2] { { 5, 6 }, { 7, 8 } };
three[1, 1] = new int[2, 1] { { 9 }, { 10 } };
three[2, 0] = new int[2, 1] { { 11 }, { 12 } };
three[2, 1] = new int[2, 1] { { 13 }, { 14 } };
//创建一维交错数组,子数组为二维数组
int[][,] three2 = new int[3][,];
three2[0] = new int[,] { { 1 }, { 2 } };
three2[1] = new int[,] { { 3, 4, 5 }, { 6, 7, 8 } };
three2[2] = new int[,] { { 9, 10 }, { 11, 12 } };
Console.WriteLine(" ----------------------\n");
非静态方法:
Console.WriteLine(" 非静态方法: \n");
Console.WriteLine("1.获取数组中指定位置的值:");
//一般获取对应索引的值可使用 item 的方式,例如 [index] ,item 适用所有类型数组
//一维数组可直接通过1个参数索引获取对应值,二维/三维参数改成2/3个即可,最多3个参数
//如果参数个数错误,运行时才会报错
Console.WriteLine("一维数组:one[2]的值: {0}/ {1}", one.GetValue(2), one[2]);
Console.WriteLine("三维数组:tow[0,1,1]的值: {0}/ {1}", tow.GetValue(0, 1, 1), tow[0, 1, 1]);
//除了一维数组,其它数组都可以通过1个一维数组作为其索引获取对应值
int[] index = { 0, 0 };
Console.WriteLine("多维数组:three[0,0]的值: ");
//如果不知道获取的数组是什么类型,可以使用 GetType() 方法
Type type = three.GetValue(index).GetType();
Console.WriteLine("three子数组的类型是:{0}", type);
var t = three.GetValue(index) as int[,];
FTest(t);
运行结果:
Console.WriteLine("2.获取数组中指定维度的第一个索引:");
//需要注意维度索引从 0 开始,超过当前维度的范围,运行时会报错
//这个方法貌似没用,返回值是一个 Int 值,对多维数组没意义
//而一维数组永远只有一维,第一位永远是 0
Console.WriteLine("one : " + one.GetLowerBound(0));
Console.WriteLine("tow : " + tow.GetLowerBound(0));
Console.WriteLine("three : " + three.GetLowerBound(0));
Console.WriteLine(" ----------------------\n");
Console.WriteLine("3.获取数组中指定维度的最后一个索引:");
//这个方法相当于获取每个维度的下限,下限加一,就是维度的长度
Console.WriteLine("one : " + one.GetUpperBound(0));
Console.WriteLine("tow : " + tow.GetUpperBound(0));
Console.WriteLine("tow : " + tow.GetUpperBound(1));
Console.WriteLine("tow : " + tow.GetUpperBound(2));
Console.WriteLine("three : " + three.GetUpperBound(0));
Console.WriteLine("three : " + three.GetUpperBound(1));
Console.WriteLine(" ----------------------\n");
Console.WriteLine("4.获取数组中指定维度长度:");
Console.WriteLine("one : " + one.GetLength(0));
Console.WriteLine("tow : " + tow.GetLength(0));
Console.WriteLine("tow : " + tow.GetLength(1));
Console.WriteLine("tow : " + tow.GetLength(2));
Console.WriteLine("three : " + three.GetLength(0));
Console.WriteLine("three : " + three.GetLength(1));
Console.WriteLine(" ----------------------\n");
运行结果:
Console.WriteLine("6.判断两个对象是否绝对相等:");
int[] one2 = { 0, 1, 2, 3 };
//从表面上看one和one2是相等的,可结果是 false
//因为这里的相等指绝对相等,指针必需指向相同的内存
Console.WriteLine("one和one是否相等: {0}", one.Equals(one));
Console.WriteLine("one和one2是否相等: {0}", one.Equals(one2));
Console.WriteLine("one和tow是否相等: {0}", one.Equals(tow));
Console.WriteLine(" ----------------------\n");
Console.WriteLine("7.设置指定位置元素的值:");
one.SetValue(5, 2);
Console.WriteLine("一维数组:one[2]的值: {0}", one[2]);
tow.SetValue(15, 0, 1, 1);
Console.WriteLine("三维数组:tow[0,1,1]的值: {0}", tow[0, 1, 1]);
int[,] n = { { 2 }, { 3 } };
three.SetValue(n, 0, 0);
Console.WriteLine("多维数组:three[0,0]的值: ");
FTest(three[0, 0]);
Console.WriteLine("8.复制数组到另一个数组中:");
//因为数组的长度是固定的,无法自动伸缩
//复制前需要注意数组之间的长度,如果复制过去后长度不够,运行时会报错
//复制操作只支持一维数组,其它维度运行时会报错
one.CopyTo(one2, 0);
Console.WriteLine("i: ");
FTest(one2);
//该方法同样适用于交错数组
int[][,] three3 = new int[3][,];
three3[0] = new int[,] { { 13 }, { 14 } };
three3[1] = new int[,] { { 15, 16, 17 }, { 18, 19, 20 } };
three3[2] = new int[,] { { 21, 22 }, { 23, 24 } };
three2.CopyTo(three3, 0);
Console.WriteLine("three3: ");
FTest2(three3);
运行结果:
静态方法:
Console.WriteLine(" 静态方法: \n");
Console.WriteLine("9.对数组进行排序:");
//Sort() 方法仅支持一维数组
//1.对数组进行简单排序
int[] i = { 1, 0, 2, 3, 4, 5, 6, 7, 8, 9 };
Array.Sort(i);
Console.WriteLine("i: ");
FTest(i);
//2.基于第一个数组排序后的顺序,对第二个数组进行相同排序
//此方法会将两个数组都排序
int[] i2 = { 4, 3, 2, 1, 0, 9, 8, 7, 6, 5 };
Array.Sort(i2, i);
Console.WriteLine("i2: ");
FTest(i2);
FTest(i);
string[] str = { "a", "c", "b", "d", "f", "e", "g", "i", "h" };
Array.Sort(str, i);
Console.WriteLine("str: ");
FTest(str);
FTest(i);
bool[] bo = { true, false, false, false, false, false, true, true, true };
Array.Sort(bo, i);
Console.WriteLine("bo: ");
FTest(bo);
FTest(i);
//3.对数组中指定部分进行排序
Console.WriteLine("i3: ");
int[] i3 = { 4, 3, 2, 1, 0, 9, 8, 7, 6, 5 };
Array.Sort(i3, 0, 5);
FTest(i3);
运行结果:
Console.WriteLine("10.反转数组中的元素排序:");
Array.Sort(i);//先将数组 i 的顺序调整为从小到大排列
//该方法仅支持一维数组,多维数组会运行报错
Array.Reverse(i);
Console.WriteLine("i: ");
FTest(i);
//该方法同样支持一维交错数组
Array.Reverse(three2);
Console.WriteLine("three2: ");
FTest2(three2);
运行结果:
Console.WriteLine("11.搜索一维数组中指定对象,返回首个索引:");
//将i的最后一个值设置为5,让该数组中存在两个相同的值
i[i.Length-1] = 5;
Console.WriteLine("i: 5 ,{0}\n" ,Array.IndexOf(i, 5));
//如果需要搜索的对象不在数组中,则返回 -1
Console.WriteLine("i: 100 ,{0}\n" ,Array.IndexOf(i, 100));
//该方法无法获取交错数组指定对象的首个索引,返回值都是是 -1
int[,] i4 = new int[,] { { 9, 10 }, { 11, 12 } };
Console.WriteLine("three2: i4 ,{0}\n" , Array.IndexOf(three2, i4));
Console.WriteLine("12.搜索一维数组中指定对象,返回最后索引:");
Console.WriteLine("i: 5 ,{0}\n" , Array.LastIndexOf(i, 5));
//如果需要搜索的对象不在数组中,则返回 -1
Console.WriteLine("i: 100 ,{0}\n" ,Array.LastIndexOf(i, 100));
//该方法无法获取交错数组指定对象的首个索引,返回值都是是 -1
Console.WriteLine("three2: i4 ,{0}\n" ,Array.LastIndexOf(three2, i4));
Console.WriteLine("13.复制指定范围的元素到另一个数组指定索引处:");
//1.从第一位开始复制指定长度的元素到另一个数组的第一位中
//复制时需要注意两个数组的长度
Array.Copy(i, i2, 3);
FTest(i2);
//2.从指定索引处开始复制指定长度的元素到另一个数组的指定索引处
Array.Copy(i, 2, i2, 3, 5);
FTest(i2);
运行结果:
Console.WriteLine("14.将一维数组元素总数更改为指定新大小:");
//新长度会根据指定大小进行伸缩,多出来的会默认为该类型的默认值
Array.Resize<int>(ref i2,20);
FTest(i2);
Console.WriteLine("15.将数组某个范围的元素设置为元素类型的默认值:");
//int 类型默认值为 0
Array.Clear(i2, 0, i2.Length);
FTest(i2);
//string 类型默认值为 space(空格)
Array.Clear(str, 0, str.Length);
FTest(str);
//bool 类型默认值为 false
Array.Clear(bo, 0, bo.Length);
FTest(bo);
Console.ReadKey();
运行结果:
五.参数数组
当声明一个方法时,不能确定参数的数目,可以使用参数数组,参数数组通常 用于传递未知数量的参数 给方法。
params 关键字
在使用数组作为形参时,C# 提供了 params 关键字,使调用数组为形参的方法时, 既可以传递数组实参,也可以只传递一组数组 。params 的使用格式为:
public 返回类型 方法名称( params 类型名称[] 数组名称 )
代码演示
using System;
namespace 数组
class Program
static void Main(string[] args)
//可以直接使用多个实参传递给方法
ArrayTest3(1,2,3,4,5,6,7,8,9);
//也可以通过一维数组来传递实参
int[] i = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ArrayTest3(i);
ArrayTest3(new int[] { 1 }, new int[] { 2 });
int[][] i2 = { new int[] { 1 }, new int[] { 2 } };
ArrayTest3(i2);
ArrayTest3(new int[,] { { 1 }, { 2 } }, new int[,] { { 3 }, { 4 } });
int[][,] i3 = { new int[,] { { 1 }, { 2 } }, new int[,] { { 3 }, { 4 } } };
ArrayTest3(i3);
Console.ReadKey();
//参数必须是一维数组
static void ArrayTest3(params int[] array)
int sum = 0;
foreach (var item in array)
sum += item;
Console.WriteLine("【一维普通数组】: " + sum);
//一维交错数组也可以,子数组维度可以任意
static void ArrayTest3(params int[][] array)
int sum = 0;
foreach (var i in array)
foreach (var item in i) sum += item;
Console.WriteLine("【一维交错数组】一维子数组: " + sum);
static void ArrayTest3(params int[][,] array)
int sum = 0;
foreach (var i in array)
foreach (var item in i) sum += item;