相关文章推荐
爱运动的打火机  ·  使用 VBA ...·  2 周前    · 
性感的凉面  ·  VBA | ...·  2 周前    · 
从容的打火机  ·  ApplicationFactory.Get ...·  3 月前    · 
可爱的木耳  ·  探索开源FastChat ...·  1 年前    · 
完美的板栗  ·  javascript - jQuery ...·  1 年前    · 

【c# .net】数组(Array)

C# 数组(Array)

文章目录:

  1. C# 数组
  2. 一维数组
  3. 多维数组
  4. 交错数组
  5. Array类
  6. 参数数组

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;