1第5章数组和过程本章涉及两个问题:(1)当需要处理的数据具有同一性质而且数据量大时,如果用变量存储数据是不合适的,这时只有用数组来实现比较方便。(2)VisualBasic应用程序是由过程组成的。过程设计和调试使程序设计简单化、模块化和功能化。可以这样说,在用VisualBasic设计应用程序时,除了定义常量、变量、控件外,全部工作就是编写过程。5.1数组处理少量的数据,可以为每一个数据设计一个变量,一个变量存储一个数据。但如果数据量很大,就要用数组来存储数据了。例如:要记录一个班的30个同学的成绩时,总不能分别定义c1,c2,…,c30等30个变量来分别存储30项成绩。如果使用数组存储这30个同学的成绩,我们只需要定义一个数组名,30个同学的成绩之间的区分靠数组的下标来表达。5.1.1数组的概念1.基本概念(1)数组:是同类型变量的一个有序的集合。这些同类型变量共用同一个名字——数组名,它们之间的区别是以数组名后面跟上下标来表达的。(2)数组元素:即数组中的变量。从形式上讲,数组名后面跟上下标就是数组元素,或者说带下标的数组名不再表示数组,而是表示数组中的一个变量——数组元素。数组元素的表示形式:数组名(n1,n2,…)。其中n1、n2表示元素在数组中的排列位置,称为“下标”。例如:A(3,2)表示二维数组A中第3行第2列上的那个元素。(3)数组维数:由数组元素中下标的个数决定,一个下标表示一维数组,二个下标表示二维数组,……。VB中有一维数组、二维数组、……最多60维数组。(4)下标:下标表示顺序号,每个数组元素有一个唯一的顺序号,下标不能超过数组声明时的上、下界范围。下标可以是整型的常数、变量、表达式,甚至还可以是一个数组元素。特别说明:这里所说的“下标”仅是用于数组元素的下标,在数组声明时,如果省略下界,数组声明的形式与数组元素的书写形式一样,但在数组声明时,写在数组名后园括号内的单个常量叫范围。2.数组声明数组必须先声明后使用。声明数组就是让系统在内存中分配一个连续的区域,也就是表明同时定义相应的数组元素,为存储数据做准备。声明的内容:数组名、类型、维数、数组大小。2一般情况下,数组中各元素类型必须相同,但若数组为Variant时,可包含不同类型的数据。5.1.2静态数组静态数组的声明形式:语法:Dim|Private|Static|Public数组名(范围[,范围,…])[As类型]范围=[下界常量TO]上界常量说明:(1)范围的写法是:下界常量TO上界常量,也可以只写上界常量,这时表示省略了下界常量,其默认值为0,多数都是这种写法。(2)下界常量、上界常量必须是常数,不可以为表达式或变量。(3)下界常量最小为-32768,上界常量最大为32767;一维数组的大小(数组元素的个数)为:(上界常量-下界常量)+1;如果省略下界,一维数组的大小为:上界常量+1。(4)如果省略类型,则为变体型。(5)范围个数决定数组的维数,最多60维。例如:DimA(10)AsInteger声明了数组A、整型、一维数组、有11个数组元素,下标的范围是0~10。例如:DimAB(-5To5)AsString*3声明了数组AB、字符串型、一维数组、有11个元素,下标的范围是-5~5,每个元素最多存放3个字符。例如:DimABC(2To5,4)AsLong声明了数组ABC、长整型、二维数组、第一维下标范围为2~5,第二维下标的范围是0~4,占据4x5个长整型变量的空间。(6)上面的语法形式只表达了声明一个数组的简单情况,实际上可以在一行中声明多个数组。例如:DimA(10),B(20),C(5)AsDouble声明了数组A、B和C三个数组。5.1.3动态数组1.动态数组的使用建立动态数组的目的是希望在程序的运行过程中改变数组的大小,建立动态的数据存储区。往往在实际编程会有这样的情况发生,在程序开始运行时只知道需要一个数据区,但并不知道需要多大的数据区,只在程序运行一段时间后,才会知道需要多大的数据区。动态数组是VB的最大特点之一,许多程序设计语言不具有这一特点。建立动态数组的方法是:利用Dim、Private、Static、Public语句声明园括号内为空的数组,然后在过程中用ReDim语句指明该数组的大小。动态数组的声明形式:3语法:ReDim[Preserve]数组名(范围[,范围,…])[As类型]范围=[下界常量TO]上界常量说明:(1)语法形式只描述了声明一个数组的简单情况,实际上可在一行中声明多个数组。(2)范围可以是常量,也可以是有了确定值的变量。(3)数组名必须与Dim中的声明语句保持一致。(4)类型可以省略,若不省略,必须与Dim中的声明语句保持一致。(5)如果使用了Preserve关键字,则只能重新定义数组最末维的大小,不能改变维数的数目。使用Preserve关键字的目的是保留改变之前数组中的数据。如果数组就是一维的,则可以重新定义该维的大小并保留原来的数据。如果数组是二维或多维的时,则只能改变其最末维。同时仍保留数组中的数据。只能改变范围的上界。【例5.1】下面的代码段第一次使用ReDim语句时定义了动态数组A,第二次使用带“Preserve”关键字的ReDim语句时改变了数组A的大小,但保留了原来的数据。图5.1给出的输出结果证明了这一点。DimA()AsIntegerPrivateSubForm_Click()ReDimA(10)AsIntegerFori=0To10A(i)=iNextiReDimPreserveA(15)Fori=0To15Print;A(i);NextiEndSub图5.1例5.1输出结果(6)多次使用不带“Preserve”关键字的ReDim语句不断可以改变数组的大小,还可以改变数组的维数。但每次使用ReDim语句都会使原来数组中的数据丢失。【例5.2】下面的代码段第二次使用ReDim语句时改变了数组A的大小及维数,但丢失原来数组中的数据。图5.2给出本例代码运行的输出结果。DimA()AsIntegerPrivateSubForm_Click()ReDimA(10)AsIntegerFori=0To104A(i)=2*iNextiFori=0To10Print;A(i);NextiPrint:PrintReDimA(10,2)Fori=0To2Forj=0To10Print;A(j,i);NextjPrintNextiEndSub图5.2例5.2输出结果2.静态数组与动态数组区别静态数组:声明时确定了大小的数组。动态数组:声明时没有给定数组大小(省略了括号中的上界与下界),使用时需要用ReDim语句重新指出其大小。使用动态数组的优点是根据用户需要,有效地利用存储空间,它是在程序执行到ReDim语句时才分配存储单元,而静态数组是在程序编译时分配存储单元。3.数组的清除和重新定义在一个程序中,同一数组只能用Dim语句定义一次。但有时可能需要清除数组的内容或对数组重新定义,这可以用Erase语句来实现。语法:Erase〈数组名〉[,〈数组名〉]…功能:重新初始化静态数组的元素,或者释放动态数组的存储空间。说明:(1)在Erase语句中,只需给出数组名,不带括号和范围。(2)在Erase语句用于静态数组时,如果这个数组是数值数组,则把数组中的所有数值元素置为0;如果是字符串数组,则把所有数组元素置为空字符串。(3)当把Erase语句用于动态数组时,将删除整个数组结构并释放该数组所占用的内存区。也就是说,动态数组经Erase语句执行后,即不复存在;而静态数组经Erase后,仍然存在,只是其内容被清空。5(4)Erase语句释放动态数组所使用的内存,在下一次引用该动态数组之前,必须用ReDim语句重新定义该数组。【例5.3】下面的代码段指出:使用Erase语句后,数组A仍然存在,只是其中数据不存在了;而数组B所占存储空间被释放,所以,如果将下面代码段中加下划线的行前面的单引号去掉,让这一行由注解行变成程序行,引用下标变量B(1),将会程序运行错误。DimA(10)AsIntegerPrivateSubForm_Click()Fori=0To10A(i)=2*i:Print;A(i);NextiPrintReDimB(5)Fori=0To5B(i)=3*i:Print;B(i);NextiPrintEraseA,BFori=0To10Print;A(i);NextiPrint'PrintB(1)EndSub图5.3例5.3输出结果4.数组下标界的测试函数有时需要知道数组的上界值和下界值,这可以通过LBound和UBound函数来测试。语法:LBound(数组名[,维])UBound(数组名[,维])功能:LBound函数返回数组指定维的下界。UBound函数返回数组指定维的上界。说明:(1)格式中的“维”是指定要测试数组的第几维。两个函数一起使用,即可确定一个数组的大小。(2)对于一维数组来说,“维”可以省略。如果要测试多维数组,“维”不能省略。【例5.4】使用LBound函数和UBound函数。代码如下:6PrivateSubForm_Click()DimA(10),B(10,8,-4To5)AsIntegerPrintLBound(A),UBound(A)PrintPrintLBound(B,1),UBound(B,1)PrintLBound(B,2),UBound(B,2)PrintLBound(B,3),UBound(B,3)EndSub程序运行的输出结果如图5.4所示。图5.4例5.4输出结果5.1.4数组的基本操作对数组的操作实际上主要是引用数组元素。我们把数组元素当成一个普通变量看待,普通变量能够出现的地方,数组元素就能出现。数组元素的写法:数组名(下标1,下标2,…)数组元素中的下标可以是常量、变量、表达式。注意与数组声明时的下标范围(省略下界)相区别。数组声明时的下标范围只能常量。1.数组元素的赋值例如:DimA(1To10)AsIntegerFori=1To10A(i)=100*iNextiA(10)=Int(sin(1)+cos(2))+100A(9)=A(10)A(8)=InputBox()Fori=1To10PrintA(i)*100Nexti2.数组的赋值在VB6.0中可以直接将一个数组的值赋值给另一个数组。这VB的特点。例如:PrivateSubForm_Click()Dima(3)AsIntegerDimb()AsInteger7a(0)=0:a(1)=1:a(2)=2:a(3)=8b=aFori=0To3Printb(i)NextiEndSub注意:(1)赋值号两边的数据类型必须一致。(2)如果赋值号左边的是一个动态数组,则赋值时系统自动将动态数组ReDim成右边相同大小的数组。(3)如果赋值号左边的是一个大小固定的数组,则数组赋值出错。5.1.5控件数组1.控件数组的概念控件数组是由一组相同类型的控件组成的,它们共用一个控件名。控件数组适用于若干个控件执行的操作相似的场合,控件组共享同样的事件过程。控件数组通过索引号(属性中的Index)来标识各控件,第一个下标是0。如:Text1(0)、Text1(1)、Text1(2)、Text1(3)……2.控件数组的建立控件数组的建立有两种方法,一种是在界面设计时就建立,二是在运行时添加。在设计时建立的具体步骤如下:(1)在窗体上画出某控件,并进行属性设置。(2)选中该控件进行“复制”和“粘贴”操作,系统提示“是否建立控件数组”,选择是即可。多次粘贴就可以创建多个控件元素。(3)进行事件过程的编程。在运行时添加控件数组的具体步骤如下:1)在窗体上画出某控件,设置该控件的Index值为0,表示该控件为数组。2)在编程时通过Load方法添加其余若干个元素,也可以通过Unload删除某个添加的元素。3)每个添加的