第5章 C#数组结构和枚举.docx
- 文档编号:6017708
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:24
- 大小:83.65KB
第5章 C#数组结构和枚举.docx
《第5章 C#数组结构和枚举.docx》由会员分享,可在线阅读,更多相关《第5章 C#数组结构和枚举.docx(24页珍藏版)》请在冰豆网上搜索。
第5章C#数组结构和枚举
第5章C#数组、结构和枚举
声明一个变量可以存储一个值,当遇到要存储多个相同类型的值的时候,变量就显得无能为力,数组正是在这种存储需求下设计的一种数据结构;常量可用来存储一个固定值,但是要存储多个固定值的时候,常量也失效了,这时候就要借助于枚举来实现;而结构是用来表示更加复杂的值类型,在结构里,用户可以声明不同数据类型的变量作为一个整体。
学完本章后,读者将了解数组、结构和枚举的用法。
本章主要涉及到的知识点有:
❑数组:
理解数组的概念,并创建数组。
❑使用数组:
包括定位、遍历、查找、排序等典型操作。
❑结构:
在需要考虑运行效率、且几乎不做运算的数据应该作为结构定义。
了解结构的用法。
❑枚举:
用于声明一组命名的常数。
理解枚举的好处,并使用枚举。
5.1C#中的数组
在日常生活中,人们用容器来存储物品,为了方便查找,总是将众多的物品分门别类地存储在不同的容器中。
在计算机程序中,同样会遇到处理大量具有相同类型的数据的时候,C#语言提供了“数组”这一数据结构,用于处理这样的数据。
5.1.1声明和初始化一维数组
【本节示例参考:
\源代码\chapter5\5.1.1\ArrayExample】
数组类似于生活中的容器,可以将一组数据类型相同的数据按照一定的顺序存储起来,存储在数组中的数据又叫元素,可以通过“索引”,或叫“下标”的整数来区分数组中的元素。
C#支持一维数组、多维数组(矩形数组)和数组的数组(交错数组)。
下面通过一个例子来学习一维数组。
暑期到了,音像店的老板Landy整理了一个CD架位置,并买了5张碟片放在上面出租,分别是《功夫熊猫》、《不可思议绿巨人》、《赤壁》、《木乃伊3》、《牛仔裤的夏天2》,有客人来租碟的时候,就从相应的位置找到这张碟。
如果把这个CD架理解为一个“数组”,它顺序存放的“元素”就是碟片。
在程序中,可以用以下的语句声明一个数组:
string[]movies;
声明以后,需要让计算机内存分配指定大小的空间,这叫初始化数组,如下所示:
movies=newstring[5];
用new关键字创建一个数组,实际上是在请求分配内存空间。
数组初始化成功后,就可以把元素存入数组,如下所示:
movies[0]=“功夫熊猫”;
movies[1]=“不可思议绿巨人”;
movies[2]=“赤壁”;
movies[3]=“木乃伊3”;
movies[4]=“牛仔裤的夏天2”;
注意:
紧跟数组名的数字,称之为“下标”或“索引”。
同C语言和大部分语言一样,C#数组的下标是从0开始,而不是从1。
如果要声明一个大小是5的数组,其下标就是从0~4。
通过以上内容,完成了数组的声明和初始化工作。
对于数组的声明和初始化,还可以用以下三种不同的方式简写。
(1)方式一:
string[]movies=newstring[5];
计算机内存将分配5个连续的存储string类型的空间。
因为字符串在C#中是引用类型,所以系统默认将每个元素初始化为NULL。
如果是数值型数组,将默认初始化为0,例如:
intnumArr=newint[5];//每个元素默认值为0
floatstrArr=newfloat[5];//每个元素默认值为0
objectobjArr=newobject[5];//每个元素默认值为NULL
(2)方式二:
string[]movies=newstring[]{“功夫熊猫”,”不可思议绿巨人”,”赤壁”,”木乃伊3”,”牛仔裤的夏天2”}
这里可以不用显式指定数组的大小,数组大小默认为初始化的元素个数。
(3)方式三:
如果在声明的时候就初始化,还可以简化为:
string[]movies={“功夫熊猫”,”不可思议绿巨人”,”赤壁”,”木乃伊3”,”牛仔裤的夏天2”}
以上的数组定义方式都能达到相同的目的,在定义数组的时候,之前如果不知道数组的元素,应采用方式一。
如果定义的时候就知道数组的元素,那么采取方式三会使程序更简洁。
数组定义好以后,就可以通过循环来访问数组的每一个元素:
for(inti=0;i { Console.WriteLine("movies[{0}]={1}",i,movies[i]); } 注意: 这里用到了数组的公共属性Length,返回数组的大小,其用法是: 数组.Length。 5.1.2声明和初始化其他类型的数组 通过一维数组的方式,解决了Landy保存部分碟片的问题。 但是Landy的烦恼是,随着碟片不断增多,查找碟片越来越难,如果能给每张碟片一个编号,编号表示碟片存放的位置在第几排第几列,这样会方便很多,每一张碟片的编号及其存储位置如图5.1所示。 11 12 13 14 15 21 … 31 41 图5.1碟片编号 现在用程序来实现。 编号是按照表格方式排列的,即是二维的,所以通过二维数组可以实现。 二维数组的声明方式如下: 1//方式一 2int[,]numbers;//声明 3numbers=newint[,]{//初始化 4{1,2,3,4,5}, 5{1,2,3,4,5}, 6{1,2,3,4,5}, 7{1,2,3,4,5}, 8{1,2,3,4,5} 9}; 10//方式二 11int[,]numbers=newint[,]{//声明并初始化 12{1,2,3,4,5}, 13{1,2,3,4,5}, 14{1,2,3,4,5}, 15{1,2,3,4,5}, 16{1,2,3,4,5} 17}; 声明的numbers数组可以存放5行5列的元素,即numbers.Length=25,要访问每个元素,可以通过下标,如numbers[0,0]=1。 以此类推,还可以创建更多维的数组。 此外,数组的元素可以是数组,即数组的数组(交错数组)。 交错数组的声明方式如下: //方式一 int[][]jaggedArr=newint[2][];//声明交错数组 jaggedArr[0]=newint[5];//声明交错数组的第一个元素为一个大小为5的整型数组 jaggedArr[1]=newint[5]; //方式二 int[][]jaggedArr=newint[2][]{ newint[5], newint[5] }; 综合一下,列出创建数组的惯用语法,如下所述: ❑data_type[]arr_name=newdata_type[intlength],这种方式定义一个元素数据类型为data_type,长度为length的一维数组arr_name。 ❑data_type[]arr_name=newdata_type[]{item1,item2,…,itemn},这种方式定义一个元素数据类型为data_type,并通过“=”运算符进行赋值,其初始值为所给出的元素{item1,item2,…,itemn}的个数的一维数组。 ❑data_type[,…,]arr_name=newdata_type[intlength1,intlength2,…,intlengthn],这种方式定义一个元素数据类型为data_type,秩为n,各维长度分别为length1,length2,…lengthn的多维数组arr_name。 ❑data_type[][]…arr_name=newdata_type[intlength1][intlength2],这种方式定义一个交错数组arr_name,与定义多维数组非常相似,所不同的是,必须单独初始化交错数组每一维中的元素。 5.1.3支持数组语言实现的基类: System.Array 【本节示例参考: \源代码\chapter5\5.1.3\ArrayClass】 C#中的数组是由System.Array类派生而来的引用对象,它提供一些公共的属性和方法,对数组的操作提供了很大帮助。 其常用的属性和方法如表5.1所示(更多的属性和方法请参考MSDN)。 常用方法的使用会在以下章节中介绍。 表5.1Array类常用属性/方法说明 属性/方法 说明 Length 获得一个32位整数,表示Array的所有维数中元素的总数 IsFixedSize 返回一个布尔值,表示数组是否是固定大小的 IsReadOnly 返回一个布尔值,表示数组是否是只读的 Rank 获取Array的秩(维数),如二维数组numbers,numbers.Rank=2 BinarySearch 使用二进制搜索算法在一维的排序Array中搜索值 Clone 创建Array的浅表副本 Copy/CopyTo 将一个Array的一部分复制到另一个Array中 GetLength 获取一个32位整数,表示Array的指定维中的元素 GetLowerBound/GetUpperBound 获取Array的指定维度的下/上限 GetValue/SetValue 获取/设置Array中的指定元素值 IndexOf/LastIndexOf 返回一维Array或部分Array中某个值第一个/最后一个匹配项索引 Sort 对一维Array对象中的元素进行排序 下面的代码演示了System.Array类的属性的用法。 string[]movies={"功夫熊猫","不可思议绿巨人","赤壁","木乃伊3","牛仔裤的夏天2"}; Console.WriteLine("是否固定大小(IsFixedSize): "+movies.IsFixedSize); Console.WriteLine("是否只读(IsReadOnly): "+movies.IsReadOnly); Console.WriteLine("数组元素的总数(Length): "+movies.Length); Console.WriteLine("数组的秩(Rank): "+movies.Rank); Console.ReadLine(); 输出的结果如下所示: 是否固定大小(IsFixedSize): True 是否只读(IsReadOnly): False 数组元素的总数(Length): 5 数组的秩(Rank): 1 5.1.4访问数组元素 【本节示例参考: \源代码\chapter5\5.1.4\VisitExample】 Landy的新碟到了以后,生意好了很多,每天都有很多人去租碟。 通过每张碟的编号,从CD架上找到碟片。 这就好比从数组中去访问每个元素一样。 访问元素的方式很多,最直接的就是通过数组的下标。 假如所有碟片都放在一排陈列架上,就要用一维数组,例如: 定义一维数组: string[]movies=newstring[]{“功夫熊猫”,”不可思议绿巨人”,”赤壁”,”木乃伊3”,”牛仔裤的夏天2”} 获取第一个元素: movies[0]=“功夫熊猫”。 获取最后一个元素: movies[4]=“牛仔裤的夏天2”。 假如碟片分别放在多排CD架上每排可以放多张碟,则要用二级数组,定义二维数组: string[,]movies=newstring[,]{{“功夫熊猫”,”不可思议绿巨人”},{”赤壁”,”木乃伊3”}} 这样创建的数组,表示CD 在架上是这样摆放的,如图5.2所示。 图5.2CD架上的碟片 获取第一个元素: movies[0,0]=“功夫熊猫”。 获取最后一个元素: movies[1,1]=“木乃伊3” 注意: 如果引用的下标超出了数组的范围,会抛出System.IndexOutOfRangeException异常。 还可以通过System.Array类的GetValue/SetValue方法访问数组元素。 GetValue方法语法: publicobjectGetValue(paramsint[]indices);,其中,多个int型参数indices的含义为下标。 方法返回一个object对象,这是C#中所有对象的基类,使用多态性,它可以指向所有的C#对象,如下所示: 1string[]movies=newstring[]{“功夫熊猫”,”不可思议绿巨人”,”赤壁”,”木乃伊3”,”钢铁侠”}; 2for(inti=0;i 3{ 4Console.WriteLine(“碟片[{0}]={1}”,i,movies.GetValue(i)); 5} 输出结果为: 碟片[0]=功夫熊猫 碟片[1]=不可思议绿巨人 碟片[2]=赤壁 碟片[3]=木乃伊3 碟片[4]=钢铁侠 SetValue方法语法为: publicobjectSetValue(…);其作用是给指定下标的元素赋值,用法跟GetValue类似。 1string[]movies=newstring[]{“功夫熊猫”,”不可思议绿巨人”,”赤壁”,”木乃伊3”,”钢铁侠”}; 2for(inti=movies.GetLowerBound(0);i<=movies.GetUpperBound(0);i++) 3{ 4movies.SetValue("蝙蝠侠",i); 5Console.WriteLine(“碟片[{0}]={1}”,i,movies.GetValue(i)); 6} 输出结果为: 碟片[0]=蝙蝠侠 碟片[1]=蝙蝠侠 碟片[2]=蝙蝠侠 碟片[3]=蝙蝠侠 碟片[4]=蝙蝠侠 注意: SetValue(objectvalue,intindex),表示将value值赋给下标是index的元素;GetLowerBound方法可以获取数组某一维上的最低下标,而GetUpperBound则可获取其最高下标 5.1.5使用foreach语句遍历数组 【本节示例参考: \源代码\chapter5\5.1.5\ForeachExample】 遍历是指全部访问数组中的元素一次且仅一次,可以在遍历的过程中完成查找等许多操作,需要注意一点: foreach循环对数组内容进行只读访问,所以不能改变任何元素的值。 foreach语句格式如下: foreach(data_typtitem_nameinarr_name) { //遍历每一个元素 } 注意: 无论是几维的数组,foreach语句都会从最深层的原子元素开始,遍历一次且仅一次,因此,不需要嵌套foreach循环。 代码5-1实现二维数组的遍历和元素的处理: 代码5-1利用foreach遍历数组示例: ForeachExample.cs 1//定义二维数组 2int[,]numbers=newint[,]{ 3{1,1,1,1,1}, 4{2,2,2,2,2}, 5{3,3,3,3,3}, 6{4,4,4,4,4}, 7{5,5,5,5,5} 8}; 9//遍历-输出 10intcount=0;//定义一个计数器 11foreach(intnuminnumbers) 12{ 13Console.Write(num+","); 14count++;//每输出一个元素,计数器加1 15if(count==5)//每输出5个元素 16{ 17Console.WriteLine();//输出换行 18count=0;//初始化计数器 19} 20} 21Console.ReadLine(); 输出结果: 1,1,1,1,1, 2,2,2,2,2, 3,3,3,3,3, 4,4,4,4,4, 5,5,5,5,5, 5.1.6查找数组元素 【本节示例参考: \源代码\chapter5\5.1.6\SearchExample】 数组的元素是有序的,每一个元素对应一个唯一下标,在程序设计中,经常需要查找某个元素是否存在,以及该元素所在的位置等操作。 可以通过遍历整个数组的方式来查找,也可以通过System.Array提供的BinarySearch方法完成这些操作。 有个客户需要租《赤壁》,Landy需要在CD架中找到片名叫《赤壁》的碟片,下面的例子演示了查找元素《赤壁》所在的位置的两种方法: 1//定义数组 2string[]movies=newstring[]{"功夫熊猫","钢铁侠","赤壁","木乃伊3","牛仔裤的夏天2"}; 3//方法一: 遍历,比较 4for(inti=0;i 5{ 6if(movies[i]=="赤壁") 7{ 8Console.WriteLine("'赤壁'所在的位置是: {0}",i); 9} 10} 11//方法二: 通过方法查找 12intindex=System.Array.BinarySearch(movies,"赤壁"); 13Console.WriteLine("'赤壁'所在的位置是: {0}",index); 输出的结果: '赤壁'所在的位置是: 2 '赤壁'所在的位置是: 2 注意: BinarySearch方法的第一个参数是需要查找的数组,第二个参数表示需要查找的元素,如果找到,方法返回该元素所在数组中的下标,如果没找到,将返回一个负数。 5.1.7对数组进行排序 【本节示例参考: \源代码\chapter5\5.1.7\SortExample】 生活中会经常遇到一些排序问题,比如把一个班的考试成绩排序,足球比赛积分排序等。 那么怎样用计算机程序来完成排序工作呢? 这个问题前人早就有深刻的研究,总结出了很多高效率的排序算法,下面就来看看怎样用C#语言实现经典的冒泡排序。 在编写程序之前,先来了解一下冒泡排序算法原理。 假设现有5个数: 3,5,2,4,1,要将它们从小到大排序。 冒泡排序的过程如图5.3所示。 图5.3冒泡排序流程图 可以将每个元素比作一个气泡,排序的过程就是气泡不断向上冒的过程,越小的气泡冒得越高。 代码5-2用程序实现冒泡排序的功能。 代码5-2使用冒泡排序示例: SortTest1.cs 1//定义数组 2int[]numbers={3,5,2,4,1}; 3//输出排序前数组 4Console.WriteLine("排序前的数组: "); 5for(inti=0;i 6{ 7Console.Write(numbers[i]+","); 8} 9//开始排序 10for(inti=0;i 11{ 12//将最大的元素交换到最后 13for(intj=0;j 14{ 15if(numbers[j]>numbers[j+1]) 16{ 17//交换元素 18inttmp=numbers[j]; 19numbers[j]=numbers[j+1]; 20numbers[j+1]=tmp; 21} 22} 23} 24//输出排序后数组 25Console.WriteLine("\n排序后的数组: "); 26for(inti=0;i 27{ 28Console.Write(numbers[i]+","); 29} 30Console.ReadLine(); 输出结果: 排序前的数组: 3,5,2,4,1, 排序后的数组: 1,2,3,4,5, 可以看到,对数组进行排序,是指按照一定的排序规则,如递增或递减规则,重新对数组中的所有元素排序。 除了冒泡排序等算法实现外,C#提供了很好的排序支持,可以使用Array类的Sort方法轻松完成这个功能。 代码5-3用程序实现冒泡排序。 代码5-3利用Sort排序数组示例: SortTest2.cs 1//定义数组 2int[]numbers={3,5,2,4,1}; 3//输出排序前数组 4Console.WriteLine("排序前的数组: "); 5for(inti=0;i 6{ 7Console.Write(numbers[i]+","); 8} 9//开始排序 10System.Array.Sort(numbers); 11//输出排序后数组 12Console.WriteLine("\n排序后的数组: "); 13for(inti=0;i 14{ 15Console.Write(numbers[i]+","); 16} 17Console.ReadLine(); 该程序输出结果为: 1,1,1,1,1, 2,2,2,2,2, 3,3,3,3,3, 4,4,4,4,4, 5,5,5,5,5, 注意: 语法publicstaticvoidSort(Arrayarray);其中,参数array为待排序的数组。 5.2用C#中的结构来实现音像记录表 C#是面向对象的语言,结构可视为轻量级的类,是创建用于存储少量数据的数据类型的理想选择,不能表示以后可能要通过继承进行扩展的类型。 本章将通过讲解实现完善碟片编号的功能来向读者展示结构的用法。 5.2.1音像信息记录表程序实例 【本节示例参考: \源代码\chapter5\5.2.1\StructTest】 通过数组一节,Landy完成了碟片的存储和给碟片编号的任务。 现在Landy希望把所有的碟片记录在电子表格中,以方便查找。 对电子表格的设计通常采用图5.4的形式。 图5.4碟片记录表 每一条记录,要求存储碟片的编号,名称,以及出租状态。 现在考虑如何用程序来实现: 碟片的编号用整数类型来表示,名称用字符串类型来表示,而出租状态可能是个方法。 显然用数组会有点力不从心,因为数组只能存储相同数据类型的数据。 这里需要一个更好的类型支持,这就是结构。 不管是用什么实现,下面迫不及待地想完成这张音像记录表的建立。 在理解相对晦涩的概念之前,笔者手把手教你完成这个项目,然后再来研究结构的语法和细节。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第5章 C#数组结构和枚举 C# 数组 结构 枚举