第 7章 数组从存储角度看,前面使用的变量都是相互独立的,
无关的,通常称它们为简单变量 。 但如果处理将 200个学生的成绩按大小顺序排序这类问题,只使用简单变量将会非常麻烦,而利用数组却很容易实现 。 本章讲述 VB数组的基本概念和使用方法,主要内容有:数组的概念,数组的定义及应用,可调数组的概念及应用,
控件数组的概念及应用 。
退出
7.1 数组的概念
7.2 一维数组
7.3 二维数组
7.4 可调数组
7.5 控件数组
7.1 数组的概念在实际应用中,常常需要处理相同类型的一批数据 。 例如,为了处理 100个员工的工资,可以用 S( 1),
S( 2),…,S( 100) 来分别代表每个员工的工资,
其中 S( 1) 代表第一个员工的工资,S( 2) 代表第二个员工的工资 …… 。 在 VB中,把一组相互关系密切的数据放在一起并用一个统一的名字作为标志,这就是数组 。
数组中的每一个数据称为数组元素,用数组名和该数据在数组中的序号来标识。序号又称为下标,数组元素又称为下标变量。例如,S( 2)是一个数组元素,
其中的 S称为数组名,2是下标。在使用数组元素时,
必须把下标放在一对紧跟在数组名之后的括号中。 S
( 3)是一个数组元素,而 S3是一个简单变量。
如果只用一个下标就能确定某个数组元素在数组中的位置,这样的数组称为一维数组。如果用两个或多个下标才能确定某个数组元素在数组中的位置,则数组分别称为二维数组或多维数组。
7.2 一维数组
7.2.1 一维数组的定义数组应当先定义后使用,数组的定义又称为数组的声明或说明 。
对于固定大小的一维数组,用如下格式进行定义:
说明符 数组名 ( 下标 ) [As 类型 ]
例如,Dim y( 5) As Integer
定义了一个一维数组,该数组的名字为 y,类型为
Integer,占据 6个 ( 0~ 5) 整型变量的空间 。
说明:
( 1)“说明符”为保留字,可以为 Dim,Public,
Private,Static中的任意一个。在使用过程中可以根据实际情况进行选用。本章主要讲述用 Dim声明数组,
其它参数的意义在 8.4节介绍。定义数组后,数值数组中的全部元素都初始化为 0,字符串数组中的全部元素都初始化为空字符串。
( 2)“数组名”的命名遵守标识符规则。
( 3)“下标”的一般形式为,[下界 to] 上界”。
下标的上界、下界为整数,不得超过 Long数据类型的范围,并且下界应该小于上界。如果不指定下界,下界默认为 0。
( 4)要注意区分“可以使用的最大下标值”和
“元素个数”。
( 5),As类型,用来说明,数组元素,的类型,
可以是 Integer,Long,Single,Double,Currency,
String( 定长或变长 ) 等基本类型或用户定义的类型,
也可以是 Variant类型 。 如果省略,As类型,,则数组为 Variant类型 。
( 6) 在同一个过程中,数组名不能与变量名同名,
否则会出错 。
( 7) 可以通过类型说明符来指定数组的类型 。
例如,Dim A%( 5),B! ( 3 To 5),C#( 12)
7.2.2 一维数组的引用数组的引用通常是对数组元素的引用 。 一维数组元素的表示形式为:
数组名 ( 下标 )
一般通过循环语句及 InputBox函数,文本框给数组输入数据 。 数组的输出一般用 Print方法,标签或文本框实现 。
【 例 7.2】 编写程序,把输入的 10个整数按逆序输出 。
Private Sub Command1_Click( )
Dim a( 10) As Integer,i%
Print "输入的数据为 "
For i = 1 To 10
a( i) = InputBox( "请输入一个整型数 ")
Print a( i),
Next i
Print
Print "逆序输出为 "
For i = 10 To 1 step -1
Print a( i),
Next i
End Sub
7.2.3 一维数组的应用举例
【 例 7.3】 从键盘上输入 40人的考试成绩,输出高于平均成绩的分数 。
分析:该问题可分三部分处理:一是输入 40个人的成绩;二是求平均分;三是把这 40个分数逐一和平均成绩进行比较,若高于平均成绩,则输出 。
程序如下:
Private Sub Command1_Click()
Dim score( 40) As Single,aver!,i%
aver = 0
For i = 1 To 40
score( i) = InputBox( "请输入成绩 ")
aver = aver + score( i)
Next i
aver = aver / 40
For i = 1 To 40
If score( i) > aver Then Print score( i)
Next i
End Sub
【 例 7.4】 从键盘上输入 10个整数,把这些数按由小到大的顺序排序输出。
排序的方法很多,如选择法、冒泡法等。这里介绍最容易理解的“冒泡法”。
设 10个数存放在 A数组中,分别为,A( 1),A
( 2),A( 3),A( 4),A( 5),A( 6),A( 7)、
A( 8),A( 9),A( 10)。
第 1轮:先将 A( 1)与 A( 2)比较,若 A( 1)>
A( 2),则将 A( 1),A( 2)的值互换,否则,不作交换;这样处理后,A( 1)一定是 A( 1),A( 2)
中的较小者。
再将 A( 1)分别与 A( 3),…,A( 10)比较,
并且依次作出同样的处理。最后,10个数中的最小者放入了 A( 1)中。
第 2轮:将 A( 2)分别与 A( 3),…,A( 10)比较,并依次作出同第 1轮一样的处理。最后,第 1轮余下的 9个数中的最小者放入 A( 2)中,亦即 A( 2)是
10个数中的第二小的数。
照此方法,继续进行第 3轮 …

直到第 9轮后,余下的 A( 10)是 10个数中的最大者。
至此,10个数已从小到大顺序存放在 A( 1)~ A
( 10)中。
为简单起见,我们以 7,5,3三个数为例,再做说明:
第 1轮:找出最小值 3作为第一个数组元素
7 5 3 比较 7和 5,7> 5,需要交换,交换后的序列为 5 7 3;
5 7 3 比较 5和 3,5> 3,需要交换,交换后的序列为 3 7 5;
第 2轮:找出剩下的元素中的最小值 5作为第二个数组元素
3 7 5 比较 7和 5,7> 5,需要交换,交换后的序列为 3 5 7。
剩下的一个元素 7为三个元素中的最大者,排序完成。
程序如下:
Private Sub Command1_Click()
Dim t%,i%,j%,a( 10) As Integer
For i = 1 To 10
a( i) = InputBox( "输入一个整数 ")
Next i
Print "输入的 10个整数为 "
For i = 1 To 10
Print a( i),
Next i
Print
For i = 1 To 9
For j = i + 1 To 10
If a( i) > a( j) Then t = a( i),a( i) = a( j):
a( j) = t
Next j
Next i
Print "排序后的结果为 "
For i = 1 To 10
Print a( i),
Next i
End Sub
【 例 7.5】 随机产生 10个两位整数,找出其中最大值、最小值。
分析:该问题可以分为两部分处理:一是产生 10
个随机整数,并保存到一维数组中;二是对这 10个整数求最大、最小值。
程序代码为:
Private Sub Command1_Click()
Dim min%,max%,i%,a( 10) As Integer
Randomize
For i = 1 To 10
a( i) = Int( Rnd * 90) + 10
Next i
Print "产生的随机数为 "
For i = 1 To 10
Print a( i),
Next i
Print
min = a( 1),max = a( 1)
For i = 2 To 10
If a( i) > max Then max = a( i)
If a( i) < min Then min = a( i)
Next i
Print "最大值为 "
Print max
Print "最小值为 "
Print min
End Sub
7.3 二维数组假如有 30个学生,每个学生有 5门考试成绩,如何来表示这些数据呢? VB中可以用有两个下标的数组来表示,如第 i个学生第 j门课的成绩可以用 S( i,j) 表示 。 其中 i表示学生号,称为行下标 ( i= 1,2,…,
30) ; j表示课程号,称为列下标 ( j= 1,2,3,4,
5) 。 有两个下标的数组称为二维数组 。
7.3.1 二维数组的定义对于固定大小的二维数组,可以用如下格式进行定义:
说明符 数组名( [下界 to]上界,[下界 to]上界)
[As 类型 ]
例如,Dim T( 2,3) As Integer定义了一个二维数组,名字为 T,类型为 Integer,该数组有 3行( 0~ 2)
4列( 0~ 3),占据 12( 3× 4)个整型变量的空间,如图 7-3所示。
说明:
( 1) 可以将二维数组的定义方法推广至多维数组的定义 。
例如,Dim D( 3,1 To 10,1 To 15) 定义了一个
3维数组,大小为 4 × 10 × 15。 注意在增加数组的维数时,数组所占的存储空间会大幅度增加,所以要慎用多维数组,尤其是 Variant 数组,因为他们需要更大的存储空间 。
( 2) 在实际使用时,可能需要数组的上界值和下界值,这可以通过 LBound函数和 UBound函数来求得 。
其格式为:
LBound( 数组名 [,维 ])
UBound( 数组名 [,维 ])
这两个函数分别返回一个数组中指定维的下界和上界 。
7.3.2 二维数组的引用二维数组的引用和一维数组基本相同,格式为:
数组名 ( 下标 1,下标 2)
对二维数组进行赋值或输出时,一般采用二重循环来实现 。
7.3.3 二维数组的应用举例
【 例 7.8】 打印 4名同学的英语,数学,法律 3门课的考试成绩,并计算出每个同学的平均成绩 。
分析:把 4名同学的姓名及各科的考试分数分别存入一个一维字符串数组 xm( 4) 和一个二维数值数组 a
( 4,3) 中,然后对数组 ( 主要是二维数组 ) 进行处理 。
程序如下:
Private Sub Command1_Click()
Dim a( 4,3) As Single,xm( 4) As String * 10,
i%,j%,aver!
Print Tab( 25); "成绩表 "
Print
Print "姓名 "; Tab( 15); "英语 "; Tab( 25);
"数学 ";
Print Tab( 35); "法律 "; Tab( 45); "平均分 "
Print
For i = 1 To 4
aver = 0
xm( i) = InputBox( "输入姓名 ")
Print xm( i);
For j = 1 To 3
a( i,j) = InputBox( "输入 " & xm( i) & "的一个成绩 ")
aver = aver + a( i,j)
Next j
aver = aver / 3
Print Tab( 15); a( i,1); Tab( 25); a( i,
2);
Print Tab( 35); a( i,3); Tab( 45); aver
Print
Next i
End Sub
7.4 可调数组通过前两节的学习,我们知道,定义数组,是用数值常数或符号常量定义数组的维数及下标的上、下界。 VB编译程序在编译时为数组分配了相应的存储空间,并且在应用程序运行期间,数组一直占据这块内存区域,这样的数组称为固定数组。但是,在实际应用中,有时事先无法确定到底需要多大的数组,数组应定义多大,要在程序运行时才能决定。如果定义的数组过大,显然会造成内存空间的朔选可调数组提供了一种灵活有效的管理内存机制,
能够在程序运行期间可以根据用户的需要随时改变数组的大小。
7.4.1 可调数组的定义可调数组的定义分为两步:
第一步:声明一个没有下标参数的数组。
格式为:
说明符 数组名() [As 类型 ]
第二步:引用数组前用 ReDim语句重新定义。
格式为:
ReDim [Preserve] 数组名( [下界 to ] 上界 [,[下界
to ] 上界 ……] ) [As 类型 ]
例如:
Private Sub Command1_Click()
Dim a() As Integer
Dim n%
……
n = Val( InputBox( "input n"))
ReDim a( n)
……
End Sub
说明:
( 1)格式中的“说明符”、,数组名”、,类型”等说明同一维数组的定义。
( 2)下界、上界可以是常量,也可以是有了确定值的变量。
( 3) ReDim语句用来重新定义数组,能改变数组的维数及上、下界,但不能用其改变可调数组的数据类型,除非可调数组被声明为 Variant类型。
( 4)每次使用 ReDim语句都会使原来数组中的值丢失,可以在 ReDim后加 Preserve参数来保留数组中的数据,但 Preserve只能改变多维数组中最后一维的大小,前几维的大小不能改变。
( 5) ReDim语句只能出现在过程中。
7.4.2 可调数组的应用举例
【 例 7.10】 编程输出 Fibonacci数列,l,1,2,3,
5,8,…… 的前 n项。
分析:在例 7.6中,是输出 Fibonacci数列的前 20项,
我们使用了固定数组;本例要求输出前 n项,n是一个变量,因此,应该使用可调数组。
程序代码如下:
Private Sub Command1_Click()
Dim Fib(),i%,n% ‘ 避免溢出,
定义数组为 Variant类型
n = InputBox( "输入 n的值( n>1) ")
ReDim Fib( n)
Fib( 1) = 1,Fib( 2) = 1
For i = 3 To n
Fib( i) = Fib( i - 1) + Fib( i - 2)
Next i
For i = 1 To n
Print Fib( i),
If i Mod 5 = 0 Then Print
'每行输出 5个数
Next i
End Sub
请思考:如果例 7.8中的学生数为 n人,课程为 m门,
应该如何编程实现?
7.5 控件数组本节介绍控件数组,控件数组为我们处理功能相近的控件提供了极大的方便 。
7.5.1 控件数组的概念在实际应用中,我们有时会用到一些类型相同且功能类似的控件 。 如果对每一个控件都单独处理,就会多做一些麻烦而重复的工作 。 这时,我们可以用控件数组来简化程序 。
控件数组由一组相同类型的控件组成,这些控件共用一个控件名字,具有相似的属性设置,共享同样的事件过程。控件数组中各个控件相当于普通数组中的各个元素,同一控件数组中各个控件的 Index属性相当于普通数组中的下标。
比如,假设有一个包含 3个按钮的控件数组
Command1,它的 3个元素就是 Command1( 0),
Command1( 1),Command1( 2)。
7.5.2 控件数组的建立控件数组中每一个元素都是控件,它的定义方式与普通数组不同。可以通过以下两种方法建立控件数组。
方法一:复制已有的控件并将其粘贴到窗体上。
方法二:将窗体上已有的类型相同的多个控件的
Name属性设置为同一值 。
7.5.3 控件数组的应用举例建立了控件数组之后,控件数组中所有控件共享同一事件过程 。 例如,假定某个控件数组含有 10个标签,则不管单击哪个标签,系统都会调用同一个 Click
过程 。 由于每个标签在程序中的作用不同,系统会将被单击的标签的 Index属性值传递给过程,由事件过程根据不同的 Index值执行不同的操作 。
【 例 7.12】 设计一个简易计算器,能进行整数的加,
减,乘,除运算 。 其运行界面如图 7-8所示 。
界面设计:
一个标签用于计算器输出;
数字按钮控件数组 Number;
操作符控件数组 Operator;
一个,=”按钮用于计算结果;
一个,Cls”按钮用于清屏 。
程序如下:
' 窗体级变量声明
Dim op1 As Byte ' 用来记录前面输入的操作符
Dim ops1&,ops2& ' 两个操作数
Dim res As Boolean ' 用来表示是否已算出结果
Private Sub clear_Click( )
dataout.Caption = ""
End Sub
Private Sub Form_Load( )
res = False
End Sub
' 按下数字键 0~ 9的事件过程
Private Sub number_Click( i1 As Integer)
If Not res Then
dataout.Caption = dataout.Caption & i1
Else
dataout.Caption = i1
res = False
End If
End Sub
' 按下操作键 +、-,×,/的事件过程
Private Sub operator_Click( i2 As Integer)
ops1 = dataout.Caption
op1 = i2 ' 记下对应的操作符
dataout.Caption = ""
End Sub
' 按下 =键的事件过程
Private Sub result_Click()
ops2 =dataout.Caption
Select Case op1
Case 0
dataout.Caption = ops1 + ops2
Case 1
dataout.Caption = ops1 - ops2
Case 2
dataout.Caption = ops1 * ops2
Case 3
dataout.Caption = ops1 / ops2
End Select
res = True ' 已算出结果
End Sub