第三讲开始C#(变量与常量表达式与运算符)_第1页
第三讲开始C#(变量与常量表达式与运算符)_第2页
第三讲开始C#(变量与常量表达式与运算符)_第3页
第三讲开始C#(变量与常量表达式与运算符)_第4页
第三讲开始C#(变量与常量表达式与运算符)_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C#语言基础--程序流程控制1.5

程序流程控制

语句是程序完成一次完整操作的基本单位。默认情况下,程序语句按顺序执行。为提高程序的灵活性,在C#中还定义了选择、循环和跳转语句来控制程序的执行顺序,从而实现比较复杂的程序。1.5.1

选择语句

选择语句可根据某个表达式的值,从若干条给定的语句中选择一条来执行。选择语句包括if语句和switch语句两种。

1if…else语句if(布尔表达式)

【语句块1】或者if(布尔表达式)

【语句块1】else【语句块2】【语句块】可以只有一条语句或为空语句(只有一个分号),若有多条语句,则必须将这些语句放入放在大括号{}内。Else子句是可选的。if语句的执行流程为,先计算布尔表达式的值,若布尔表达式的值是true,则执行语句块1;若布尔表达式的值为false,且有else子句C#语言基础--程序流程控制存在时,则执行语句块2,否则跳出if语句,执行其它程序代码。

if语句可以嵌套,即一个if语句可以是另一个if或else语句的嵌入语句。在实际软件编写时经常用到嵌套if语句。使用嵌套if语句时,需要记住的要点为:一个if语句只能对应一个else语句;一个else语句总是对应着和它在同一块中最近的if语句。C#语言基础--程序流程控制inta=1,b=2,c=3;if(a<b){if(b<c){a=0;}else{a=-1;}}C#语言基础--程序流程控制嵌套的if语句可以组成if…elseif…else语句群。基本原则是:如果else语句的嵌入语句(块)只是一个if…else语句,那么else就能与嵌入的if组合成一个elseif语句,形式如下:if(布尔表达式)

【语句块】else{If(布尔表达式)【语句块】else{if(布尔表达式)【语句块】else【语句块】}}C#语言基础--程序流程控制if(布尔表达式)

【语句块】elseif(布尔表达式)

【语句块】elseif(布尔表达式)

【语句块】else【语句块】

在if…elseif…else语句群中,布尔表达式从上到下求值,一旦找到真的条件,就执行与它关联的语句,该阶梯的其它部分就被忽略。若所有条件都不为真,就执行最后的else语句。若没有最后的else语句,而其它所有的条件都为假,程序将不做任何操作。If…elseif…else语句群,只可能有一个嵌入语句块被执行。C#语言基础--程序流程控制2switch语句

switch语句为多路(分支)选择语句,它根据表达式的值来使程序从多个分支中选择一个分支来执行,switch语句的基本格式如下:switch(【表达式】){case【常量表达式】:【语句块】case【常量表达式】:【语句块】…case【常量表达式:

【语句块】default:【语句块】}C#语言基础--程序流程控制在case标签的【语句块】的末尾必须使用break语句,当遇到一个break语句时,程序将跳过switch语句中的其它标签,而直接跳到整个switch语句后的第一个语句。switch语句的执行规则如下:计算switch语句中【表达式】的值,并将其转换为switch语句规定的类型。若在switch语句的case标签中,有一个指定的常量恰好等于switch表达式的值,则程序将转到匹配case标签后的【语句块】。若switch语句的所有case标签指定的常量都不等于switch中【表达式】的值,且switch语句中存在一个default标签,则程序将转到default标签后的【语句块】。若switch语句的所有case标签指定的常量都不等于C#语言基础--程序流程控制

switch中【表达式】的值,且switch语句中不存在default标签,则程序将转到整个switch语句后的第一语句。在很多情况下,switch语句可以简化if…else语句,提高程序执行效率。下面使用switch语句简化前面判断月份所属季节的程序。

举例:C#语言基础--程序流程控制1.5.2循环语句循环语句使一个语句(块)重复执行,直到满足结束条件为止。循环语句又叫做迭代语句,在C#中定义的循环语句包括:while、do…while、for和foreach语句。1while语句

while语句用于根据条件值执行一个嵌入语句(块)零次或多次。基本格式为:while(【布尔表达式】)【嵌入语句块】while语句按如下规则执行:计算【布尔表达式】的值。若表达式的值为true,程序将转到嵌入语句。当程序执行到嵌入语句的结束点(嵌入语句块的结束或遇到C#语言基础--程序流程控制continue语句)时,控制将转到while语句的开头。若【布尔表达式】的值为true,这继续执行【嵌入语句块】;否则,转到while语句的结束点,结束循环。当嵌入语句块包含多条语句时,必须用{}将它们括起来。在while语句的嵌入语句(块)内,break语句可用于将控制转到while语句的结束点,跳出循环。ontinue语句可将控制直接转到下一次循环。C#语言基础--程序流程控制StringBuilder

strV=newStringBuilder("");//定义一个可变字符串对象inti=0,count=100;while(i<count){i++;if(i>20)break;//若i大于20终止循环

if(i%2==0)continue;//若i为偶数则转入下次循环

strV.Append(i.ToString()+"");//将奇数添加到可变字符串对象的末尾}textBox1.Text=strV.ToString();//在文本框中显示奇数列表C#语言基础--程序流程控制

2do…while语句

do…while语句与while语句相似,但它的判断条件在循环后,这样可以确保至少执行循环体一次。do…while语句的基本格式为:do{【语句块】}while(【布尔表达式】)

do…while语句的执行规则如下为:控制转到【语句块】;当控制到达【语句块】的结束点(也有可能是通过执行一个continue语句)时,计算【布尔表达式】的值,若其值为true,则转到do语句的开头;否则,控制转到do语句的结束点,结束循环。请同学们联系P35页上的菜单程序。C#语言基础--程序流程控制3for语句

for语句计算一个初始化表达式序列,然后判断一个条件表达式的值是否为true,若为true,则重复执行嵌套语句块,并计算一个迭代表达式序列;若为false,则终止循环,退出for语句。for语句的基本形式为:for(【初始化表达式】;【条件表达式】;【迭代表达式】){【嵌入语句块】}【初始化表达式】由一个局部变量申明或由一个逗号分隔的表达式列表组成。【初始化表达式】申明的局部变量的作用域从变量的声明开始,一直到嵌入语句块的结束。【条件表达式】若存在,必须是布尔表达式,【迭代表达式】若存在,必须包含一个用逗号分隔的表达式列表。

C#语言基础--程序流程控制for语句的执行规则如下:若有【初始化表达式】存在,则按变量初始化设定项或语句表达式的编写顺序执行它们,此步骤只执行一次。若存在【条件表达式】,则计算它的值。若计算结果为true或不存在【条件表达式】,控制转到嵌入语句块,若控制到达嵌入语句块的结束点(可能通过执行一个continue语句)时,则按顺序执行【迭代表达式】,然后从上述步骤中的计算【条件表达式】开始,执行另一次循环。若存在【条件表达式】,且计算结果为false,控制将转到for语句的结束点。C#语言基础--程序流程控制下面三个for语句的功能完全相同:stringstrV1=string.Empty;//第一个for语句

for(inti=0;i<10;i++){strV1=strV1+i.ToString()+"";}textBox1.Text=strV1;stringstrV1=string.Empty;//第二个for语句

inti=0;for(;i<10;){strV1=strV1+i.ToString()+"";i++;}textBox1.Text=strV1;

C#语言基础--程序流程控制

stringstrV1=string.Empty;//第三个for语句

inti=0;for(;;){if(i>=10)break;strV1=strV1+i.ToString()+"";i++;}textBox1.Text=strV1;

在for语句的嵌套语句块内,break语句用于直接终止循环,而continue语句则用于开始下一次循环。C#语言基础--程序流程控制下面的代码用于显示小于10的奇数:

stringstrV1=string.Empty;for(inti=0;;i++){if(i>=10)break;//直接终止循环

if(i%2==0)continue;//开始下一次循环

strV1=strV1+i.ToString()+"";}textBox1.Text=strV1;C#语言基础--程序流程控制下面的代码使用了两重for循环,实现冒泡(升幂)排序。int[]items={1,10,8,5,-10,18,231,35,66,9};//定义需要排序的数组

for(inti=1;i<items.Length;i++){for(intj=items.Length-1;j>=i;j--){//若不符合排序要求,则交换相邻的两个数

if(items[j-1]>items[j]){

inttemp=items[j-1];

items[j-1]=items[j];

items[j]=temp;}}}C#语言基础--程序流程控制stringstrV=string.Empty;for(inti=0;i<items.Length;i++)

strV=strV+items[i].ToString()+"";textBox1.Text=strV;下面的方法也实现相同的功能,请加以比较:int[]items={1,10,8,5,-10,18,231,35,66,9};for(inti=0;i<items.Length-1;i++){for(intj=i+1;j<items.Length;j++){//若不符合排序要求,则交换相邻的两个数

if(items[i]>items[j]){

inttemp=items[i];

items[i]=items[j];

items[j]=temp;}

C#语言基础--程序流程控制}}stringstrV=string.Empty;for(inti=0;i<items.Length;i++)

strV=strV+items[i].ToString()+"";textBox1.Text=strV;4foreach语句

foreach用于列举一个集合的元素,并对该集合中的每个元素执行一次嵌入语句(块)。foreach的形式为:foreach(【类型】【迭代变量名】in【集合类型表达式】){【嵌入语句】}

【类型】和【迭代变量名】用于声明迭代变量,迭代变量是作用域范围覆盖整个嵌入语句块的局部变量。C#语言基础--程序流程控制在foreach语句的执行期间,迭代变量表示当前正在为其执行迭代的集合元素,若嵌入语句试图修改迭代变量,将会发生编译错误。foreach语句的【集合类型表达式】必须有一个从该集合的元素类型到迭代变量类型的显示转换。若【集合类型表达式】的值为null,则会出现异常。

System.Array类型是集合类型,因所有的数组类型都是从System.Array派生,所以foreach语句中允许使用数组类型表达式。foreach语句按如下顺序遍历数组元素:对一维数组按递增的索引顺序遍历元素,即从0开始索引,到索引Length-1结束。对多维数组的遍历方式为,首先递增最右边维度的索引,然后是它的左边紧邻的维度,依次类推,直到最左边的那个维度。C#语言基础--程序流程控制1.5.3跳转语句

跳转语句用于无条件地转移控制,跳转语句会将控制转到某个位置,该位置称为跳转语句的目标。当一个跳转语句出现在某个语句块内,而跳转语句的目标却在语句块之外,就称该跳转语句退出该语句块。在C#中定义的跳转语句主要包括break语句、continue语句、goto语句和return语句。1break语句

break语句只能用在switch、while、do…while、for或foreach语句内,用来退出它所在的switch、while、do…while、for和foreach语句。当有多个switch、while、do…while、for或foreach语句彼此嵌套时,break语句只能退出直接包含它的语句,若要穿越多个嵌套层,直接转移控制,则必须使用goto语句。C#语言基础--程序流程控制stringstrAdd=string.Empty;stringstrV=string.Empty;for(inti=0;i<3;i++){for(intj=0;j<100;j++){if(j==10)break;

strAdd=strAdd+j.ToString()+"";}

strV=strV+"第"+i.ToString()+"遍:"+strAdd+"\r\n";

strAdd=string.Empty;}textBox1.Text=strV;

分析上述程序可以看出,内层循环的break语句仅仅终止了内层循环,并未影响外部循环。C#语言基础--程序流程控制2continue语句

continue语句只能用于while、do、for或foreach语句的嵌入语句块内,用来忽略循环语句块内位于它后面的代码,直接开始一次新的循环。当有多个while、do、for或foreach语句彼此嵌套时,continue语句只能使直接包含它的循环语句直接开始一次新的循环。C#语言基础--程序流程控制

stringstrAdd=string.Empty;stringstrV=string.Empty;for(inti=0;i<3;i++){for(intj=0;j<20;j++){if(j%2==0)continue;

strAdd=strAdd+j.ToString()+"";}

strV=strV+"第"+i.ToString()+"遍:"+strAdd+"\r\n";

strAdd=string.Empty;}textBox1.Text=strV;C#语言基础--程序流程控制

3return语句

return语句将控制返回到使用return语句的方法(函数成员)的调用方。若方法有返回类型,return语句必须返回这个类型的值;若没有返回类型,则应使用没有表达式的return语句。usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Collections;namespaceAppDes1{publicpartialclassForm1:Form//类C#语言基础--程序流程控制

{publicForm1(){

InitializeComponent();}//创建一个string类型的静态方法

staticstringMyStr(string

str){stringstrOut;

strOut="您输入的数据是:"+str;returnstrOut;}privatevoidbutton1_Click(objectsender,EventArgse){//在按钮单击事件中调用此方法

stringstrV=textBox1.Text;//获取用户输入文本框中的内容

stringstrOut=MyStr(strV);

MessageBox.Show(strOut,"信息提示");//显示调用结果

}}}

4goto语句

goto语句用于将控制转到由标签标记的语句。标签包括switch语句中的case标签和default标签,以及标记语句所声明的标签。标签语句的形式为:【标签】:【语句】它声明了一个名为【标签】的标签。标签的作用域为声明它的整个语句块,包括其中的嵌套块,两个同名标签的作用域如果重叠,将产生编译错误。goto语句的三种形式如下:goto【标签】,其目标是具有给定标签的标记语句。gotocase【参数表达式】,其目标是它所在的switch语句的某个语句列表,此列表包含一个具有给定常数值的case标签。C#语言基础--程序流程控制

gotodefault,其目标是它所在switch语句中的default标签。在进行实际编程时,应尽量避免使用goto语句,它会破坏程序结构,使程序调试变得困难。C#语言基础--程序流程控制1.6

数组和集合

数组(array)是一种包含相同若干变量的数据结构,可通过计算索引来访问这些变量。数组中包含的变量叫做数组的元素(element),数组的元素具有相同的类型,该类型称为数组的元素类型。数组类型为其元素类型后加上一对中括号[]组成。如int型数组表示为int[],string型数组表示为string[]。

数组的秩用于确定和每个数组元素关联的索引个数。数组的秩又称为数组的维度,秩为1的数组称为一维数组(singledemensionarray)。秩大于1的数组称为多维数组(multi-dimensionarray),如二维数组和三维数组等。C#语言基础--数组和集合

数组的每个维度都有一个关联的长度。维度的长度只与数组类型的实例相关联,它是在创建实例时确定的。维度的长度确定了维度索引的有效范围,如长度为n的维度,其索引范围为0到n-1。数组中元素的总数是数组中各维度长度的乘积。数组类型为引用类型,数组变量的声明只是为数组实例的引用留出空间。实际的数组实例在运行时用new运算符动态创建。new运算符指定新数组实例的长度(length),它在该实例的生存周期内是固定不变的。数组元素的索引范围从0到length-1,new运算符自动将数组的元素默认为它们的初始值,如将所有的值类型初始化为0,将所有的引用类型初始化为null。可以使用元素访问运算符[]来访问数组元素,如设A为整型数组,A[1]就是该数组的第2个元素。C#语言基础--数组和集合

数组是通过指定数组的元素类型、数组的秩和数组中每个维度的上下限来定义的。1.6.1

一维数组的声明和使用1一维数组的声明一维数组的声明语法如下:

type[]arrayName;

type为数组中存储元素的类型,arrayName为数组名。int[]arr;//声明了一个名为arr的整型一维数组。在声明数组时,数组的长度不是声明的一部分,数组必须在访问前初始化,数组的类型可以是基本数据类型,也可以是枚举或其它类型。

int[]arr=newint[5];//声明了一个名为arr且长度为5的整型数组,数组中的每个元素被初始化为0.C#语言基础--数组和集合数组对象一旦被创建(声明),就可以利用其提供的诸多属性和方法。可以利用Length属性获得数组对象允许存储的容量值,Rank属性用于返回数组的秩(维数),用GetLowerBound方法返回数组对象的第一个索引值,该值一律被置为0,GetUpperBound方法则用于返回数组对象的最后一个索引值。GetLowerBound和GetUpperBound方法均接受一个参数,这个参数指定返回的结果是属于哪个维度的数组,对一维数组输入参数为0。2一维数组的使用

在需要存储多个值时,可以使用一维数组,可以使用foreach语句或数组的下标访问数组中各元素的值。下面的示例代码是定义一个一维数组,并用foreach语句显示数组的内容。C#语言基础--数组和集合string[]arrStr={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};stringstrV=string.Empty;

foreach(stringstrinarrStr){

strV=strV+str+"";}textBox1.Text=strV;1.6.2

二维数组的声明和使用1二维数组的声明

二维数组的声明语法如下:

Type[,]arrayName;

type为数组中存储元素的类型,arrayName为数组名。下面举例说明二维数组的声明方法。

int[,]arr=newint[2,2];//声明一个两行两列的整形数组C#语言基础--数组和集合

int[,]arrV1=newint[2,2]{{1,2},{3,4}};//利用new关键字二维数组的默认值

double[,]arrV2=newdouble[,]{{124.234,12.012,56.231},{0.123,18.345,22.334}};//在初始化时,不指定行数和列数,由编译器根据初始值的数量来自动计算数组的行数和列数

2二维数组的使用以下是一个4行和4列的二维数组,二维数组按行排列数组元素。[0,0][0,1][0,2][0,3][1,0][1,1][1,2][1,3][2,0][2,1][2,2][2,3][3,0][3,1][3,2][3,3]C#语言基础--数组和集合下面的示例代码定义了一个二维数组,并使用Rank属性和GetUpperBound方法,获取数组行和列的元素个数,通过遍历数组,以输出其元素。//定义双精度二维数组double[,]arrV2=newdouble[,]{{124.234,12.012,56.231,123.011},{129.123,18.345,22.334,589.342}};int

numRank=arrV2.Rank;//获取数组的维数int

numRow=arrV2.GetUpperBound(numRank-2)+1;//获取总行数int

numCol=arrV2.GetUpperBound(numRank-1)+1;//获取总列数stringstrV1=string.Empty;C#语言基础--数组和集合//定义双精度二维数组double[,]arrV2=newdouble[,]{{124.234,12.012,56.231,123.011},{129.123,18.345,22.334,589.342}};int

numRank=arrV2.Rank;//获取数组的维数int

numRow=arrV2.GetUpperBound(numRank-2)+1;//获取总行数int

numCol=arrV2.GetUpperBound(numRank-1)+1;//获取总列数stringstrV1=string.Empty;C#语言基础--数组和集合1.6.3三维数组的声明和使用

三维数组的声明语法格式如下:

type[,,]arrayName;type为数组中存储元素的类型,arrayName为数组名。下面的语句用于初始化一个三维数组。

double[,,]arrV2=newdouble[,,]{{{124.234,12.012,56.231,123.011},{129.123,18.345,22.334,589.342}},{{124.234,12.012,56.231,123.011},{129.123,18.345,22.334,589.342}}};

对三维数组,可通过Rank属性和GetUpperBound方法获取其页面数、行数和列数。设有一个名为arrV2的三维数组,其页面数、行数和列数分别为:numPage=arrV2.GetUpperBound(numRank-3)+1;//获取总页面数C#语言基础--数组和集合numRow=arrV2.GetUpperBound(numRank-2)+1;//获取总行数numCol=arrV2.GetUpperBound(numRank-1)+1;//获取总列数下面的示例代码将三维数组arrV2中的元素分按页面进行显示。

//定义双精度三维数组

double[,,]arrV2=newdouble[,,]{{{124.234,12.012,56.231,123.011},{129.123,18.345,22.334,589.342}},{{124.234,12.012,56.231,123.011},{129.123,18.345,22.334,589.342}}};

int

numRank=arrV2.Rank;//获取数组的维数

int

numPage=arrV2.GetUpperBound(numRank-3)+1;//获取总页面数C#语言基础--数组和集合int

numRow=arrV2.GetUpperBound(numRank-2)+1;//获取总行数

int

numCol=arrV2.GetUpperBound(numRank-1)+1;//获取总列数

stringstrV1=string.Empty;for(intk=0;k<numPage;k++){for(inti=0;i<numRow;i++){for(intj=0;j<numCol;j++){strV1=strV1+arrV2[k,i,j].ToString()+"";}strV1=strV1+"\r\n";//对二维数组的每行进行换行显示

}}textBox1.Text=strV1;C#语言基础--数组和集合

在声明数组时,数组的元素可以是任意类型,包括数组类型。元素类型为数组类型的数组叫做交错数组(jaggedarray,也称为锯齿形数组)。交错数组的元素数组的长度不必完全相同。下面的示例说明由一个int数组组成的交错数组。

int[][]arrA=newint[3][];//创建包含三个元素的数组,每个元素的类型为int[],并设定其初始值为nullarrA[0]=newint[10];//初始化第1个元素

arrA[1]=newint[5];//初始化第2个元素arrA[2]=newint[15];//初始化第3个元素

声明交错数组,必须使用两个[]运算符,并且只需指定其行数。因每行的长度不同,在对象被创建后,应根据具体需要一一指定每一行的长度。在初始化数组时,数组的维度容量可以用变量和表达式描述,但变量和表达式必须要有确定的数值。C#语言基础--数组和集合真正的动态数组,是指可以在已经定义数组维数的基础上动态改变数组维数的大小。而数组中已经存储的数组元素的值可以保持不变。如:

double[]dblArr=null;

dblArr=newdouble[10];

array.resize(refdblArr,dblArr.length+100);//动态改变数组大小。1.6.4

数组的方法和属性

在C#中数组是由System.Array类派生而来的引用对象,可以使用Array类中的各种属性和方法对数组进行操作,数组继承的方法和属性如表1.6.1所示。对数组的操作可以分为静态操作和动态操作,静态操作包括查询、遍历、复制和排序等,动态操作包括插入、删除、合并和拆分等。C#语言基础--数组和集合

下面通过举例说明操作数组的常用方法。静态方法IndexOf和LastIndexOf可以用来搜索数组中的元素,如下面的示例代码:

string[]strArr=newstring[]{"方形样地","菱形样地","方形样地","圆形样地","角规样地","无样地观测"};//查找方形样地第一出现的索引号

intnumV1=Array.IndexOf(strArr,"方形样地");

intnumV2=Array.LastIndexOf(strArr,"方形样地");//结果显示

stringstrV="方形样地首次出现的索引号为:"+numV1.ToString();

strV+="\r\n";

strV=strV+"方形样地最后出现的索引号为:"+numV2.ToString();textBox1.Text=strV;C#语言基础--数组和集合

数组遍历一般使用foreach语句进行,数组元素的排序,除前面介绍过的冒泡排序法外,还可以表1.6.1中的Sort方法和Reverse方法进行,如下面的示例代码:

int[]arrA=newint[]{3,9,12,-23,0,1,12,33};stringstrV=string.Empty;

Array.Sort(arrA);//进行升幂排序foreach(int

intVinarrA)strV=strV+intV.ToString()+"";strV=strV+"\r\n";Array.Reverse(arrA);//反转排序结果foreach(int

intVinarrA)strV=strV+intV.ToString()+"";textBox1.Text=strV;C#语言基础--数组和集合

Copy方法可以进行数组的全部或部分复制,对一维数组还可以使用实例方法CopyTo进行赋值,如下面的示例代码所示:

//数组元素复制

int[,]arr=newint[3,2];//给数组元素赋初值

for(inti=0;i<arr.GetLength(0);i++){for(intj=0;j<arr.GetLength(1);j++)

arr[i,j]=i*j;}

int[,]newArr1=newint[3,2];

int[,]newArr2=newint[2,2];

Array.Copy(arr,newArr1,arr.Length);//完全复制

Array.Copy(arr,0,newArr2,0,newArr2.Length);//部分复制C#语言基础--数组和集合

//对一维数组使用CopyTo进行复制

int[]arrA1=newint[8];for(inti=0;i<arrA1.Length;i++)arrA1[i]=i*i+2;

int[]newarrA=newint[10];arrA1.CopyTo(newarrA,2);//使用实例方法复制

数组的合并和拆分在很多情况下都会用到,在对数组进行这两项操作时,拆分和合并后的数组类型应一致。可以将多个一维数组合并为一个一维数组、二维数组或多维数组;也可以将一个一维数组拆分成多个一维数组,或是将多维数组拆分为多个一维数组或多维数组。请同学们试验下面的代码。C#语言基础--数组和集合

//将两个一维数组合并的举例

int[]arr1=newint[]{12,34,15,28};

int[]arr2=newint[]{6,9,10,18};

int

numN=arr1.Length+arr2.Length;

int[]arr3=newint[numN];//定义新数组,以便合并两个一维数组

for(inti=0;i<numN;i++){if(i<arr1.Length)arr3[i]=arr1[i];elsearr3[i]=arr2[i-arr1.Length];}//定义一个需要合并的二维数组

int[,]arr4=newint[2,arr1.Length];for(inti=0;i<arr4.Rank;i++)C#语言基础--数组和集合

{switch(i){case0:{for(intj=0;j<arr1.Length;j++)arr4[i,j]=arr1[j];break;}case1:{for(intj=0;j<arr2.Length;j++)arr4[i,j]=arr2[j];break;}}}C#语言基础--数组和集合//显示合并后的数组元素

stringstrV="合并后的一维数组为:\r\n";foreach(int

intVinarr3)

strV=strV+intV.ToString()+"";

strV=strV+"\r\n"+"合并后的二维数组为:\r\n";stringstrV1=string.Empty;

int

numRow=arr4.GetUpperBound(arr4.Rank-2)+1;

int

numCol=arr4.GetUpperBound(arr4.Rank-1)+1;for(inti=0;i<numRow;i++){for(intj=0;j<numCol;j++)strV1=strV1+arr4[i,j].ToString()+"";strV1=strV1+"\r\n";//分行显示

}

strV+=strV1;textBox1.Text=strV;C#语言基础--数组和集合

//将二维数组拆分为两个一维数组的举例

int[,]arr1=newint[,]{{12,34,15,28},{6,9,10,18}};

int

numRow=arr1.GetUpperBound(arr1.Rank-2)+1;

int

numCol=arr1.GetUpperBound(arr1.Rank-1)+1;

int[]arr2=newint[numCol];//定义拆分后的一维数组

int[]arr3=newint[numCol];

for(inti=0;i<numRow;i++){for(intj=0;j<numCol;j++){switch(i){case0:arr2[j]=arr1[i,j];break;C#语言基础--数组和集合

case1:arr3[j]=arr1[i,j];break;default:break;}}}//拆分后的数组元素显示

stringstrV="拆分后的第一个数组元素:\r\n";

foreach(int

intVinarr2)

strV=strV+intV.ToString()+"";

strV=strV+"\r\n"+"拆分后的第二数组元素:\r\n";

foreach(int

intVinarr3)

strV=strV+intV.ToString()+"";textBox1.Text=strV;C#语言基础--数组和集合1.6.5

CreateInstance方法

C#数组默认的下限都是0,但System.Array提供了一个静态方法CreatInstance,可以用来动态创建数组,也可以创建下限不为0的数组和重新声明数组的大小。下面的示例代码说明如何创建下限不为0的数组。

int[]arrLens=newint[2]{3,5};

int[]arrBound=newint[2]{2,3};//创建二维string类型数组,第一维长度为3,第二维长度为5//第一维元素索引从2开始计数;第二维索引从3开始计数

string[,]array=(string[,])Array.CreateInstance(typeof(String),arrLens,arrBound);//给二维数组array赋初值

for(inti=array.GetLowerBound(0);i<=array.GetUpperBound(0);i++)C#语言基础--数组和集合{for(intj=array.GetLowerBound(1);j<=array.GetUpperBound(1);j++){

int[]myIndiceArray=newint[2]{i,j};

array.SetValue(Convert.ToString(i)+j,myIndiceArray);}}//显示数组中的元素

stringstrV="数组元素为:\r\n";for(inti=array.GetLowerBound(0);i<=array.GetUpperBound(0);i++){for(intj=array.GetLowerBound(1);j<=array.GetUpperBound(1);j++)C#语言基础--数组和集合

strV=strV+array[i,j]+"";

strV+="\r\n";}textBox1.Text=strV;

下面的示例代码说明用CreateInstance动态地创建在编译时不知道元素类型和数组维数的数组,包括利用该方法重新定义数组的大小。

C#语言基础--数组和集合//创建一个string类型的静态方法

staticArrayReDim(Array

arr,int

newSize){//动态创建指定大小的数组,用GetElementType来获取数组元素类型

Arrayna=Array.CreateInstance(arr.GetType().GetElementType(),newSize);

int

len=newSize;if(newSize>arr.Length)

len=arr.Length;

Array.Copy(arr,0,na,0,len);//将原数组中的元素拷贝到新数组中

returnna;}C#语言基础--数组和集合

privatevoidbutton1_Click(objectsender,EventArgse){stringstrV=string.Empty;

int[]arrA=newint[]{10,6,9,12,18,22};//动态改变数组的长度

arrA=(int[])ReDim(arrA,arrA.Length+5);

strV="改变后的数组元素为:\r\n";

foreach(int

intVinarrA)

strV=strV+intV.ToString()+"";//在动态改变数组

arrA=(int[])ReDim(arrA,arrA.Length-8);

strV+="\r\n";

strV=strV+"再此改变后的数组元素为:\r\n";

foreach(int

intVinarrA)

strV=strV+intV.ToString()+"";textBox1.Text=strV;//显示数组动态改变后的结果

}}}1.6.6

集合

System.Collections命名空间中定义了一系列集合类,其中最常用的包括ArrayList、Hashtable、Queue、SortedList和Stack。System.Collections命名空间中定义的大部分集合都是弱类型的,用于存放System.Object的实例。因.NET框架类型都是直接或间接从System.Object派生出来,任何类型都可显示转换为System.Object对象,这些集合类都能存储任何数据类型。C#语言基础--数组和集合

数组的长度是固定的,在声明数组时必须指定。在实际软件开发中使用长度可变的数组可以提高内存的利用率,ArrayList能动态改变数组的长度。即其大小可按需要进行动态增减,ArrayList有如下三种构造函数:

ArrayList();//初始化ArrayList类的新实例,该实例为空且具有默认的初始容量。

ArrayList(ICollection);//初始化ArrayList类的新实例该实例包含从指定集合复制的元素,并且具有与所复制的元素相同的初始容量。

ArrayList(int32);//初始化ArrayList类的新实例,该实例为空,且具有指定的初始容量。

ArrayList类的主要属性和方法请参阅表1.6.2。C#语言基础--数组和集合在操作ArrayList的方法中,Remove、RemoveAt、RemoveRange和Clear都可以用来删除ArrayList中的元素,当元素被删除后,ArrayList并不会自动释放内存,要释放内存,必须使用TrimToSize方法或通过显示设置Capacity属性减少容量。

在利用Add方法增加元素时,Capacity的值会随着增加,因此需要不断地扩展ArrayList的容量并拷贝元素,这样会影响程序的效率。为避免这种不利影响,可以使用第三种形式的构造函数来创建ArrayList,并在其中设定一个合理的最大容量值,以便提高程序效率,尤其是在元素数量特别庞大的情况下,这种技巧非常重要。如下面的示例代码:C#语言基础--数组和集合stringstrV=string.Empty;int

bigNum=30000000;DateTimetime1=DateTime.Now;ArrayListall1=newArrayList();//默认构造函数for(inti=0;i<bigNum;i++)all1.Add(i);//添加元素,需要动态扩展ArrayList容量DateTimetime2=DateTime.Now;TimeSpants1=time2.Subtract(time1);doublems1=ts1.TotalMilliseconds;Console.WriteLine(ms1);strV="第一种方法所用时间为:"+ms1+"毫秒";strV+="\r\n";DateTimetime3=DateTime.Now;ArrayListall2=newArrayList(bigNum);C#语言基础--数组和集合for(inti=0;i<bigNum;i++)all2.Add(i);//添加元素,但不需要扩展ArrayList容量DateTimetime4=DateTime.Now;TimeSpants2=time4.Subtract(time3);doublems2=ts2.TotalMilliseconds;strV=strV+"第二种方法所用时间为:"+ms2+"毫秒";textBox1.Text=strV;2Hashtable

Hashtable(离散表)表示键/值对的集合,这些键/值根据键的离散列代码进行组织。Hashtable是现在检索速度最快的数据组织方式。Hashtable的主要属性和方法如表1.6.3所示。C#语言基础--数组和集合

Add方法用来将键/值对添加到Hashtable中,及键值散列,散列值作为插入表中的索引,用来标识存储位置。Hashtable键不能为空引用,值可以为空引用。Hashtable将添加的元素存放在System.Collections.DictionaryEntry对象中。使用foreach或者IEnumerator的Current属性时,都应将Hashtable的元素转换为DictionaryEntry对象。可以使用键值作为索引来访问Hashtable中的元素,当检索值时,键再次被散列,并将得到的散列值作为索引来检索值在表中的位置。

Remove用来删除一个元素,Clear用来删除所有的元素。ContainsKey和ContainsValue分别用来检查元素的键和值是否存在。Hashtable的默认初始容量为0,伴随元素的添加,容量会通过重新分配自动增加。为此会重新C#语言基础--数组和集合计算表的索引,并将表中的元素复制到新的位置。与ArrayList的构造类似,实际编程时,最好提供一个合理的最大容量来构造Hashtable对象。

Hashtable常用的构造函数如下:

Hashtabletable=newHashtable();//默认初始容量为0

Hashtabletable=newHashtable(intcapacity);//capacity为Hashtable适合的最大容量下面的示例代码演示Hashtable的使用方法:

Hashtable

tabHash=newHashtable();tabHash.Add("200601","张艳");tabHash.Add("200602","徐鹏");tabHash.Add("200603","李光太");tabHash.Add("200604","鲁班");tabHash.Add("200605","吕伟彰");C#语言基础--数组和集合

stringstrV="表中的元素数量为:\r\n"+tabHash.Count;

strV+="\r\n"+"200604对应的值为:\r\n"+tabHash["200604"];//检索表中包含的所有元素

strV=strV+"表中包含的所有元素为:";

IEnumerator

eE=tabHash.GetEnumerator();while(eE.MoveNext()){

DictionaryEntryde=(DictionaryEntry)eE.Current;

strV=strV+"\r\n"+de.Key+""+de.Value;}textBox1.Text=strV;

对Hashtable表,可以使用键值作为索引来添加元素,也可以使用Add方法来添加元素,当二者有一定区别。使用Add添加元素,当要添加的元素的键值在表中存在时,C#语言基础--数组和集合

Add方法会引发异常,而使用键值添加则不会,只是使用新的值代替旧值。

Hashtable

tabHash=newHashtable();tabHash.Add("200601","张艳");tabHash.Add("200602","徐鹏");tabHash.Add("200603","李光太");tabHash.Add("200602","李大为");//会引发异常

tabHash[“200602”]=“李大为”;//用键值作为索引添加,不会引发异常。3Q

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论