第五章 数组
主要内容
数组的概念
静态数组及声明 动态数组及声明 数组的基本操作 控件数组
自定义数据类型 常用算法(二) 常见错误
5.1 数组的概念
1.引例
若我们要求一个班100个学生的平均成绩,然后统计高于平均分的人数。按以前简单变量的使用和循环结构相结合,求平均成绩程序段如下:
aver = 0
For i = 1 To 100
mark = Val(InputBox(\"输入第 \" & i & \" 位学生的成绩\")) aver = aver + mark Next i
aver = aver / 100
但若要统计高于平均分的人数,则无法实现。mark是一个简单变量,存放的是最后一个学生的成绩。
从已有知识解决方法:再重复输入成绩,逐一与平均分比较。这样带来两个问题: (1)输入数据的工作量成倍增加;
(2)若本次输入的成绩与上次不同,则统计的结果不正确。
解决此问题的根本方法是:始终保持输入的数据,一次输入,多次使用,为此必须引入有关数组的内容。 2.数组的概念
数组并不是一种新的数据类型,而是一组相同类型的变量的集合。数组必须先声明后使用。
在VB中有两类数组,一类是静态(定长)数组另一类称为动态(可变长)数组。
5.2 静态数组及声明
在声明数组时就确定了数组元素的个数的数组称为静态数组。 定义格式: Dim 数组名(下标1[,下标2„]) [As 类型]
数组维数:定义数组是用几个下标就表示数组是几维数组,最多60维。
定义数组是下标的形式为 [下界 To ] 上界 省略下界则系统默认下界为0,下界上界的值必须为数值常数或常数表达式(也可含逻辑常数或数值字符串)。
Visual Basic 6.0 第 1 页 共24 页 1
第五章 数组 第2 页 共 24 页
数组每一维大小: 上界-下界+1。数组元素的个数(或称大小): 每一维大小的乘积
[例] Dim mark(1 to 100) As Integer
定义数组mark为一维整型数组,其下界为1,上界为100,大小为100(即mark
有100个元素)。 Dim lArray( 0 To 3, 0 To 4) As Long
它等价于: Dim lArray(3, 4) As Long
类型为长整型,二维数组,行下界为0,行上界为3,列下界为0,,列上界为4,共有 4×5个元素。
又如定义, Dim a(-3.5 To 9, 7)
定义了数组a为两维变体数组(这样数组内的元素的值类型可以不同,如 a(-1, 4) = \"aa\": a(-1, 5) = 3),其中行下界为 -4,行上界为9;列下界为0,列上界为7。 数组mark在内存中的分配形式(连续的一个区域):
mark(1) mark(2) mark(3) „„ mark(99) lArray(0,3) lArray(1,3) lArray(2,3) lArray(3,3) mark(100) lArray(0,4) lArray(1,4) lArray(2,4) lArray(3,4) 数组lArray在内存中的分配形式(连续的一个区域): lArray(0,0) lArray(1,0) lArray(2,0) lArray(3,0) 注意: lArray(0,1) lArray(1,1) lArray(2,1) lArray(3,1) lArray(0,2) lArray(1,2) lArray(2,2) lArray(3,2) (1) 下界缺省为0 ,也可在定义数组时改变确省的下界值为1(注意:下界缺省值只能
是0或1)。这就要求在窗体或模块的通用部分写上:Option Base 1。 (2) 错误的声明(下标是变量) n =Inputbox(“输入n”) Dim x(n) As Single
(3)在数组声明中的下标说明了数组的整体,即每一维的大小;而在程序其他地方出现的下标表示数组中的一个元素。两者写法形式相同,但意义不同。
[例如]
Dim x(10) As Integer ' 声明了x数组有11个元素 x(10)=100 ' 对x(10)这个数组元素赋值
(4)数组声明以后,就可以使用数组中的元素了,但要注意不要使数组的下标越界,以免程序在运行时出错(运行时系统会报下(上)界错误)。
[例如] Dim score( 1 to 50) as single
score(1), scor(15)是正确的使用数组元素,但 score(0)则不是正确的使用数组元素,而score(I+j*m)则应注意其表达式的结果是否在1~50之内,是则是正确引用,不是,则犯下标越界错误。数组的下标表达式结果可以是一个实数或数值型字符串,但
是最终对这个值四舍五入成整数。(特例,只有一位小数时,整数是偶数时则五舍)如元素a(2.5), a(3.5), a(-2.5), a(-3.5)分别相当于a(2)、a(4)、a(-2)、a(-4)。这一点对于定义数组也是适用的。考查定义:Dim a(-6.5 To 7.5)
Visual Basic 6.0 第 2 页 共24 页 2
第五章 数组 第3 页 共 24 页
As Single,它的下界是 -6,上界是8。
(5) 在通常情况下,数组中的各元素类型必须相同,但若数组类型为Variant时,可包含不同类型的数据。
5.3 动态数组及声明
动态数组指在声明数组时未给出数组的大小(省略括号中的下标),当要使用它时,随时用ReDim语句重新指出数组大小。
使用动态数组的优点:有效地利用存储空间,它在程序执行到ReDim语句时分配存储空间,而静态数组是在程序编译时分配存储空间的。 动态数组的定义:
建立动态数组的方法是:使用Dim、Private或Public语句声明时括号内为空的数组,然后在过程中用ReDim语句指明该数组的大小。
ReDim 形式如下:
ReDim 数组名(下标[,下标2„]) [As 类型] [例] Sub Private Form_Load( )
Dim sArray( ) As Single ‘定义sArray为单精度动态(不定长)数组
„
ReDim sArray(4,8)
‘重新定义sArray为数组5行9列共45个元素的二维数组存储空间
„
ReDim sArray(5) ‘重新定义sArray为6个元素的一维数组
„
End Sub 说明:
(1) Dim、Private、Public变量声明语句是说明性语句,可出现在过程内或通用声明段;而ReDim语句是执行语句,只能出现在过程内。
(2) 在过程中可多次使用ReDim来改变数组的大小,也可改变数组的维数。 (3) 每次使用ReDim语句都会使原来数组中的值丢失,可以在ReDim语句后加Preserve参数用来保留数组中的数据,但使用Preserve只能改变最后一维的大小,前面几维大小不能改变。
(4) ReDim中的下标可以是常量,也可以是有了确定值的变量。
(5)ReDim中As类型可以省略不写,如不省略,则类型必须与dim 定义时的类型一致(即重定义数组不能改变其原来的存储类型)。 (6)一个变体变量可以重定义为具有不同类型的数组。但如果是一个变体数组,在重定义时也只能是变体数组。例如:
Dim a() As Variant 或 Dim a()
ReDim a(8) As Variant 或 ReDim a(8) 正确 而
Dim a() As Variant
ReDim a(8) as integer 则错误
Visual Basic 6.0 第 3 页 共24 页 3
第五章 数组 第4 页 共 24 页
但
Dim a 或Dim a As Variant
ReDim a(8) As integer 正确(可继续重定义a为其他类型的数组,但如类型
不同就不能使用Presever来保留原数组的非覆盖部分的值了,如硬性使用关键字Presever系统则按出错处理。)如:
Private Sub Form_click() Dim a
ReDim a(8) As String
a(1) = \"12\": a(2) = \"4\": a(3) = #1/2/2003 12:03:00 PM# Print a(1), a(2), a(3) ‘显示 12 4 2003-1-2 12:03:00
ReDim Preserve a(9) As boolean ‘去掉Preserve 即可运行
Print a(1), a(2), a(7), a(8) ‘显示 False False False False End Sub
[例5.2] 输入若干名学生的成绩。计算平均分和高于平均分的人数并将这两项放在数组的后面。
[例5.2] 在myvb\\vb5\\ex5_2下
Private Sub Form_Load()
Form2.Caption = \"动态数组的应用(请单击)\" End Sub
Private Sub Picture1_Click() Dim mark() As Integer
Dim n%, i%, aver!, num%, n1 As String
Picture1.Cls '可以求不同的人数,而不退出程序 Randomize ‘随机数发生器,以系统时钟为参数 Do '保证输入的内容可用预定义数组
n1 = InputBox(prompt:=\"输入学生人数\ Title:=\"输入\
Loop Until n1 <> Empty And IsNumeric(n1) And Val(n1) > 1 n = n1
ReDim mark(1 To n) '定义动态数组 For i = 1 To n '产生n个学生的成绩 mark(i) = Rnd * 101 Next i
For i = 1 To n
aver = aver + mark(i) Next i
'重新定义数组大小,Preserve位置是固定的
ReDim Preserve mark(1 To n + 2)
Visual Basic 6.0 第 4 页 共24 页 4
第五章 数组 第5 页 共 24 页
mark(n + 1) = aver / n For i = 1 To n
If mark(i) > aver / n Then mark(n + 2) = mark(n + 2) + 1 Next i
For i = 1 To n
Picture1.Print Tab(10); \"mark(\"; i; \")=\"; mark(i) Next i
Picture1.Print Tab(10); \"平均成绩:\"; mark(n + 1)
Picture1.Print Tab(10); \"高于平均分成绩人数:\"; mark(n + 2) End Sub
5.4 数组的基本操作
设有以下声明语句:
Dim iA(1 TO 10) As Integer
Dim Sb(3,4) As Single,Sc(4,4) As Single Dim i%,j%,t%
1.数组元素的赋初值 (1 ) 用循环结构
For i = 1 To 10
iA(i)=0 Next i
(2) 利用Array函数
[例5.3] 在myvb\\vb5\\ex5_3下
Option Base 1 '改变系统默认数组下界为1
Private Sub Form_Load()
Form2.Caption = \"赋初值并显示(单击)\" End Sub
Private Sub Picture1_Click() '要想通过
Array函数给数祖赋初值,必须说明数组是变体变量
Dim a As Variant, b As Variant, i%, m%
a = Array(InputBox(prompt:=\"输入\‘数组
a的第一个元素值通过inputbox函数输入
b = Array(\"abc\‘数组b有三种类型的数据
Picture1.Cls
Picture1.Print \" arrar a list\" Picture1.Print \"---------------\" For i = 1 To UBound(a)
Picture1.Print a(i); Spc(2);
Visual Basic 6.0 第 5 页 共24 页 5
第五章 数组 第6 页 共 24 页
Next i
Picture1.Print
Picture1.Print \" arrar a vartype list\" Picture1.Print \"-----------------------\" For i = 1 To UBound(a) m = VarType(a(i)) Call type1(m) Next i
Picture1.Print: Picture1.Print '列出数组 a 各个元素的类型 Picture1.Print \" arrar b list\" Picture1.Print \"---------------\" For i = 1 To UBound(b) Picture1.Print b(i); Spc(2); Next i
Picture1.Print
'列出数组 b 各个元素的类型 Picture1.Print \" arrar b vartype list\" Picture1.Print \"-----------------------\" For i = 1 To UBound(b) m = VarType(b(i)) Call type1(m) Next i End Sub
Private Sub type1(k As Integer) '显示数据类型名称常数过程,顺回顾函数 Dim strtype As String
strtype = Switch(k = 0, \"vbEmpty\ k = 3, \"vbLong\ k = 7, \"vbDate\ k = 11, \"vbBoolean\ k = 14, \"vbDecimal\ Picture1.Print strtype; Space(2); End Sub
Switch
注意: (1) 利用Array对数组各元素赋值,声明的数组是可调数组或连圆括号都可省并且其类型只能是Variant。 (2) 数组的下界为0,也可通过option Base声明来决定由Array所产生的数
Visual Basic 6.0 第 6 页 共24 页 6
第五章 数组 第7 页 共 24 页
组的下界,这一点与Split函数不同(下界必须是0)。上界由Array函数括号内的参数个数可决定,也可通过函数Ubound获得。 2.数组的输入
可以通过文本控件输入,也可通过InputBox函数输入。
[例]利用For Each 变体变量 in 数组名 „ Next 语句给一个数组A赋值。
Private Sub Command1_Click() Dim A%(), B() As Integer Dim N%, i, k% Cls
N = Val(InputBox(\"输入数组A的上界\ ReDim A(N), B(N) k = 0
'For Each 的变量
参见MYVB\\VB5\\EX5_14
i必须是变体且i的值由系统自动计算,
'用语句是不能改变其值的;数组B和变量K必须开辟,B的下界必须是0。 'For Each 是不能保留数组B的值的。 For Each i In B
B(i) = Val(InputBox(\"输入数组元素的值\")) A(k) = B(i)
Print A(k) & \" , \"; k = k + 1 Next i
Print \"----------------------\" For k = 0 To UBound(A) Print A(k) & \" , \"; Next ReDim B(0) Print
Print \"---------------------\" Print LBound(B), UBound(B) End Sub
3.数组的赋值 相当于: For i = 0 To UBound(a) b(i) = a(i) Next i 在VB6.0中,提供了直接对数组的赋值。
[例如]
Dim a() As Variant, b() As Variant, i% a = Array(1, 2, 3, 4, 5)‘使用Array时a必须是变体
Visual Basic 6.0 第 7 页 共24 页 7
第五章 数组 第8 页 共 24 页
ReDim b(UBound(a)) b=a
数组对数组赋值时应注意:
(1)赋值号两边的数组的数据类型必须一致
(2)如果赋值号左边的数组必须定义成动态数组,则赋值时系统自动将动态数组Redim成右边同样大小的数值。
(3)如果赋值号的左边的是一个大小固定的数组,则数组赋值出错。 [例子]
Private Sub Picture1_Click() 'a,b
数据类型必须相同,b必须是动态数组
Dim a(5) As Integer, b() As Integer, i% For i = 0 To 5 a(i) = i Next i b = a
For i = 0 To 5
Picture1.Print b(i); Spc(3); Next i End Sub
4. 数组的输出
输出方阵sc中的下三角元素
For i = 0 To 4 For j = 0 To i
sc(i, j) = i * 5 + j Print sc(i, j); \" \"; Next j
Print ' 起换行效果 Next i
5. 求数组中最大元素及所在下标
Dim Max As Integer,iMax As Integer
„
Max=iA(1):iMax=1 ‘Max 存放最大元素的值,iMax 存放最大元素的下标 For i = 2 To 10 If iA(i)>Max Then Max=iA(i)
iMax=i
End If Next I
6. 将数组中各元素交换
Visual Basic 6.0 第 8 页 共24 页8
第五章 数组 第9 页 共 24 页
[例5.4] 将数组iA 的各元素倒排。即若iA各元素的值依次为1,5,7,35,-26,0,78。经过倒排后iA内的各元素依次是78,0,-26,35,7,5,1。
[例5.4] 在myvb\\vb5\\ex5_4下
Private Sub Picture1_Click() Dim iA As Variant, i%, j%, k%
iA = Array(1, 5, 7, 35, -26, 0, 78) '给数组赋初值 Picture1.Cls
Picture1.Print Tab(2); \" 交换前数组中的值 \" Picture1.Print Tab(2); \"--------------------------\" For i = LBound(iA) To UBound(iA) '打印原数组值 Picture1.Print iA(i); Spc(2); Next i
k = UBound(iA) '实现倒排 For i = LBound(iA) To k \\ 2
j = iA(i): iA(i) = iA(k - i): iA(k - i) = j Next i
Picture1.Print : Picture1.Print
Picture1.Print Tab(2); \" 交换后数组中的值 \" Picture1.Print Tab(2); \"--------------------------\"
For i = LBound(iA) To UBound(iA) '打印倒排后的数组值 Picture1.Print iA(i); Spc(2); Next i End Sub
5.5控件数组
1.控件数组的概念
控件是由一组相同类型的控件组成。 它们共用一个控件名,具有相同的属性,建
立时系统自动给每个元素赋一个唯一的索引号(Index)。
控件数组共享同样的事件过程,通过返回的下标值(系统赋予的索引号)来区分控件数组中的各个元素。
[例] Private Sub cmdName _Click(Index As Integer) „
If Index=3 then
‘ 处理第四个命令按钮的操作,第一个命令按钮的 End If „
End Sub
Index=0
2.控件数组的建立
(1)在设计时建立控件数组
在窗体上画出控件,进行属性设置,这是建立控件数组的第一个元素
Visual Basic 6.0 第 9 页 共24 页 9
第五章 数组 第10 页 共 24 页
选中该控件,使用“Copy”和“Paste”命令操作若干次,建立所需控件数组元素的个数,然后对各元素的位置进行适当调整。 对事件过程进行编程。
[例5.5] 建立含有四个命令按钮的控件数组,当单击某个命令按钮,分别显
示不同的图形或结束操作。
[例5.5] 在myvb\\vb5\\ex5_5下
Private Sub Command1_Click(Index As Integer) Picture1.ScaleMode = 1 '单位是缇,系统默认值 Picture1.Cls
Picture1.FillStyle = 6 '用交叉线填充 Picture1.FillColor = RGB(255, 255, 0) Select Case Index
Case 0
Picture1.Print \"画直线\"
Picture1.Line (200, 200)-(1600, 1600) Case 1
Picture1.Print \"画矩形\"
Picture1.Line (500, 200)-(1600, 1600), , B 'BF F Case 2
Picture1.Print \"画圆\"
'画长椭圆,大于1,Y轴长;小于1,x轴长 Picture1.Circle (1200, 800), 700, QBColor(5), , , 0.7 Case Else End End Select End Sub
标是画实心矩形
Private Sub Form_Load() Command1(0).Caption = \"直线\" Command1(1).Caption = \"矩形\" Command1(2).Caption = \"园\" Command1(3).Caption = \"结束\"
Form2.Caption = \"设计时建立的控件数组\" End Sub
(2)运行时添加控件数组 建立的步骤如下:
在窗体上画出某控件,设置该控件的Index值为0(一般设其visible属
性=False),表示该控件为数组,这是建立的第一个元素。
Visual Basic 6.0 第 10 页 共24 页 10
第五章 数组 第11 页 共 24 页
● 在编程时通过Load方法添加其余的若干个元素,也可以通过Unload方法删除某个添加的元素。
● 每个新添加的控件数组通过Left和Top属性确定其在窗体的位置,并将Visible 属性设置为True。
[例5.6] 利用在运行时产生控件数组,构成一个国际象棋棋盘。当单击棋格,显示对应的序号,并且将所有棋格颜色变反。
[例5.6] 在myvb\\vb5\\ex5_6下
程序代码
Private Sub Form_Load() ‘产生控件数组 Dim mtop%, mleft%, i%, j%, k As Integer Form2.Caption = \"运行时产生控件数组\" mtop = 0
Label1(0).Visible = False '使
label1(0)仅仅是为了运行时产生控件数组而设计的
引子,不可少
For i = 1 To 8 mleft = 50 For j = 1 To 8 k = (i - 1) * 8 + j
Load Label1(k) '加载一个控件数组元素。QBColor(0)色为黑,QBColor(15)
色为白
Label1(k).BackColor = IIf((i + j) Mod 2, QBColor(0), QBColor(15)) '设置颜色
Label1(k).Visible = True '使加载的控件可见,不可少
Label1(k).Top = mtop '确定加载控件的位置 Label1(k).Left = mleft Label1(k).Caption = \"\"
mleft = mleft + Label1(0).Width Next j
mtop = mtop + Label1(0).Height Next i
Visual Basic 6.0 第 11 页 共24 页 11
第五章 数组 第12 页 共 24 页
End Sub
Private Sub Label1_Click(index As Integer) ‘点击任一个标签,均使全体标签反色 Dim tag As Boolean, i%, j%, k%
Label1(index) = index '被点击的标签置其 For i = 1 To 8
caption属性为数组序号值
For j = 1 To 8 k = (i - 1) * 8 + j
If Label1(k).BackColor = &H0& Then '黑色 Label1(k).BackColor = &HFFFFFF '白色 Else
Label1(k).BackColor = &H0& End If Next j Next i End Sub
5.6自定义数据类型
数组能够存放一组类型相同的数据集合,要想存放一组能够存放不同类型的数据,
例如,存放一个学生的学号,年龄,家庭住址,手机号码,个人爱好,社会背景等,就必须要用自定义数据类型。因此可以说自定义数据类型是一组类型不同的变量的集合。
1.自定义类型的定义 形式如下:
[Public|Private]Type 自定义类型名
元素名[(下标)] As 类型名 „
[元素名[(下标)] As 类型名]
End Type
例如以下定义了一个有关学生信息的自定义类型: Type StudType
No As Integer ' 学号
Name As String * 20 ' 姓名 Sex As String * 1 ' 性别 Mark(1 To 4) As Single ' 4门课程成绩
Total As Single End Type
' 总分
注意:
(1)自定义类型一般在标准模块(.BAS)中定义,默认是Public;在窗体必须是Private。
(2)不要将自定义类型名和该类型的变量名混淆,前者表示了如同Integer、
Visual Basic 6.0 第 12 页 共24 页 12
第五章 数组 第13 页 共 24 页
Single等的类型名,后者VB根据变量的类型分配所需的内存空间,存贮数据。 (3)自定义类型一般和数组结合使用,简化程序的编写。 2.自定义类型变量的声明和使用 (1) 声明形式:
Dim 变量名 As 自定义类型名 [例] Dim Student As StudType
(2) 引用方式:
形式:变量名.元素名
[例] 要表示Student变量中的姓名,第4门课程的成绩,则用如下形式:
Student.Name,Student.Mark(4)
[示例]
Private Type MANType No As Integer ' 学号 Name As String ' 姓名 Sex As String * 1 ' 性别 Birthdate As Date ' 出生年月 Speciality as string ‘特长 End Type
Private Sub Command1_Click() Dim Man As MANType With Man
.No = 25000: .Name = \"秦雪梅\": .Sex = \"女\": .Speciality=\"鉴赏书画\" . Birthdate = #8/13/1800#
Print .No; \" \"; .Name; \" \"; .Sex; \" \"; Format(.Birthdate, \"yyyy年mm月dd日\") End With End Sub
说明:
同种自定义类型变量可相互赋值。它相当于将一个变量中的各元素的值对应的赋给另一个变量中的元素。
3.自定义类型数组的应用
自定义一个学生纪录类型,有姓名、专业、总分组成,声明一个存放最多100个学生纪录的数组;要求,按“新增”按钮,将文本框输入的学生信息加到数组中;按“前一个”或“后一个”按钮,显示当前元素的前或后的纪录;按“最高”按钮则显示总分最高的纪录;任何时候在窗体上显示数组中输入的纪录和当前数组元素的位置。
[例5.7]利用自定义类型数组,编一类似数据管理(输入、显示、查询)的程序。myvb\\vb5\\ex5_7
Type StudType
Name As String * 10
Visual Basic 6.0 第 13 页 共24 页 13
第五章 数组 第14 页 共 24 页
Special As String * 10 Total As Single End Type ‘该定义在
lbc5_7.bas中,是全局类型的
Dim n%, i% ‘窗体级变量
Dim stud(100) As StudType
Private Sub Command1_Click(Index As Integer) Dim max%, maxi%, j Select Case Index Case 0 ‘新增
If n < 100 Then ‘总条数
If Text1.Text <> \"\" Then n = n + 1 '必须有姓名 Else
MsgBox prompt:=\"人数已经达到100了\" Exit Sub End If
If n = 0 Or n = i Then Exit Sub i = n With stud(n) .Name = Text1 .Special = Text2 .Total = Val(Text3) End With
Text1.Text = \"\": Text2.Text = \"\": Text3.Text = \"\" Case 1 ‘前一个 If i = 0 Then Exit Sub If i > 1 Then i = i - 1 With stud(i) Text1 = .Name Text2 = .Special Text3 = .Total End With
Case 2 ‘后一个 If i = 0 Then Exit Sub If i < n Then i = i + 1 With stud(i) Text1 = .Name Text2 = .Special Text3 = .Total End With
Visual Basic 6.0 第 14 页 共24 页 14
第五章 数组 第15 页 共 24 页
Case 3 ‘最高
If n = 0 Then Exit Sub max = stud(1).Total maxi = 1 For j = 2 To n
If stud(j).Total > max Then maxi = j End If Next j
With stud(maxi) Text1.Text = .Name Text2.Text = .Special Text3.Text = .Total End With i = maxi End Select
Label5.Caption = i & \"/\" & n ‘位置 End Sub
Private Sub Form_Load() ‘准备 Dim stud(1 To 100) As StudType
Label1.Caption = \"姓名\": Label2.Caption = \"专业\": Label3.Caption = \"总分\" Label4.Caption = \"位置\": Label5 = \"\"
Text1.Text = \"\": Text2.Text = \"\": Text3.Text = \"\"
Command1(0).Caption = \"新增\": Command1(1).Caption = \"前一个\" Command1(2).Caption = \"后一个\": Command1(3).Caption = \"最高\" End Sub
5.7常用算法(二)
1. 统计
[例5.8]输入一串字符,统计各字母出现的次数,大小写字母不区分。
分析:
(1) 统计26个字母出现的个数,先声明一个具有26个元素的数组,每个元素的下标表示对应的字母,元素的值表示对应字母出现的次数。
(2) 从输入的字符串中逐一取出字符,转换成大写字符(使得大小写不区分),进行判断。 (3) 运行界面设计:一个文本框(用于输入),一个图片框(用于显示),
Visual Basic 6.0 第 15 页 共24 页 15
第五章 数组 第16 页 共 24 页
两个命令按钮(统计和退出) [例5.8]在myvb\\vb5\\ex5_8下
Private Sub Form_Load() Text1.Text = \"\" Text1.TabIndex = 0
'Text1.ScrollBars = 1,只读属性
Command1.Caption = \"统计\" Command2.Caption = \"退出\"
Form2.Caption = \"统计输入各字母的个数\" End Sub
Private Sub Command1_Click()
Dim Aph(1 To 26) As Integer, i%, length%, j%, c As String * 1 length = Len(Text1.Text) For i = 1 To length
c = UCase(Mid(Text1.Text, i, 1))
If c >= \"A\" And c <= \"Z\" Then j = Asc(c) - : Aph(j) = Aph(j) + 1 '大写字符 Next i
Picture1.Cls '清除已显示的内容 j = 0
For i = 1 To 26 If Aph(i) <> 0 Then
Picture1.Print Spc(2); Chr(i + ); \"=\"; Format(Aph(i), \"@@\"); '格式输出强拍占2位 j = j + 1
If j Mod 8 = 0 Then Picture1.Print '每行输出 End If Next i End Sub
A=65
8个
2.大量数据的输入
[例5.9] 输入一系列的数据,并将它们分离后存放在数组中。对输入的数据允许修改和自动识别非数字数据。
分析:
(1)利用文本框输入和编辑数据,输入时去除非法数字,只允许输入0~9、小数点、负号,逗号为分隔符。
(2)输入结束利用Replace函数去除重复输入的分隔符; (3)对利用Split函数按分隔符分离,放到数组中;
(4)还可利用Join函数将数组中各元素合并成一个字符串。
[例5.9]在myvb\\vb5\\ex5_9\\中lbc5_9.vbp
Dim A As Variant ‘A
是窗体级变量
Visual Basic 6.0 第 16 页 共24 页 16
第五章 数组 第17 页 共 24 页
Private Sub Command1_Click() '分隔 Dim temp As String, i% Picture1.Cls
Do '循环的作用是修改输入的数字串使其之间只能有一个逗号分割 temp = Text1.Text
Text1.Text = Replace(Text1.Text, \, \) Loop Until temp = Text1.Text A = Split(Text1, \For i = 0 To UBound(A) Picture1.Print A(i) Next i End Sub
Private Sub Command2_Click() '合并用空格分隔 Text2.Text = Join(A, \" \") '有待优化
End Sub
Private Sub Command3_Click() End End Sub
Private Sub Form_Load() Label1.Caption = \"输入数字串\" Label2.Caption = \"显示数组内容\"
Text2.Text = \"\"
Command1.Caption = \"分隔\" Command2.Caption = \"合并\" Command3.Caption = \"退出\" End Sub
Label3.Caption = \"合并结果\" Text1.Text = \"\"
Private Sub Text1_KeyPress(KeyAscii As Integer)
'在输入数字串文本框中输入合法的数字字串,否则不能拆分成正确的数字 Dim lenstr As Integer, j%
Dim stra As String, s As String * 1 s = Chr(KeyAscii) Select Case s
Case \"0\" To \"9\
Visual Basic 6.0 第 17 页 共24 页 17
第五章 数组 第18 页 共 24 页
Case Else
KeyAscii = 0 '非数字类字符,销去。 End Select End Sub
3.数组排序
(1)选择法排序
[例5.10] 对已知存放在数组中的n个数,用选择法按递增(从小到大)顺序排序。
方法:
8 6 9 3 2 7 2 6 9 3 8 7 2 3 9 6 8 7 2 3 6 9 8 7 2 3 6 7 8 9 2 3 6 7 8 9 (1) 从n个数的序列中选出最小的数(递增),与第1个数交换位置; (2) (3)
除第1个数外,其余n-1个数再
按(1)的方法选出次小的数,与第2个数交换位
置; (4) 重复(1)n-1遍,最后构成递增序列。 [例5.10]在myvb\\vb5\\ex5_10下
'窗体级变量a
Dim A As Variant '本题数组A只能为Variant,且下界从0开始 Private Sub Command1_Click() '显示(输入)
Dim temp As String, i% Picture1.Cls
Do '循环的作用是修改输入的数字串之间只能有一个逗号 temp = Text1.Text
Text1.Text = Replace(Text1.Text, \Loop Until temp = Text1.Text A = Split(Text1, \For i = 0 To UBound(A)
If i Mod 3 = 0 Then Picture1.Print ‘演示
程序将picture1改为text2了
Picture1.Print A(i); Spc(1); Next i
Private Sub Command2_Click() ‘排序 Dim i%, j%, n%, m%, iMin, t%
End Sub
'用split函数分解成的数组元素都是字符型的,要想变成数值必须定义一个数值数组 Dim ab() As Integer '定义动态数值数组定义 n = UBound(A) '字符数组的上界
Visual Basic 6.0 第 18 页 共24 页 18
第五章 数组 第19 页 共 24 页
m = n + 1 '数值数组的上界 ReDim ab(1 To m) '重新定义数值数组 For i = 0 To n
ab(i + 1) = val(A(i)) Next i
'选择法排序:
For i = 1 To m - 1 iMin = i
For j = i + 1 To m
If ab(j) < ab(iMin) Then iMin = j Next j
t = ab(i): ab(i) = ab(iMin): ab(iMin) = t Next i Picture2.Cls For i = 1 To m
Picture2.Print ab(i) ‘演示程序将Next i End Sub
Private Sub Command3_Click() End End Sub
Private Sub Form_Load()
Label1.Caption = \"输入内容,数字之间用逗号隔开\" Label2.Caption = \"显示数组内容\" Label3.Caption = \"排序结果\" Text1.Text = \"\"
Command1.Caption = \"显示\" Command2.Caption = \"排序\" Command3.Caption = \"退出\" End Sub
picture2改为text3了
‘输入数据:
Private Sub Text1_KeyPress(KeyAscii As Integer)
'在输入数字串文本框中要注意输入合法的数字字串
Dim lenstr As Integer, j%
Dim stra As String, s As String * 1 s = Chr(KeyAscii) Select Case s
Visual Basic 6.0 第 19 页 共24 页 19
第五章 数组 第20 页 共 24 页
Case \"0\" To \"9\ '只允许输入整型数串 Case Else
KeyAscii = 0 '非数字类字符,销去。 End Select End Sub
(2)冒泡法排序
冒泡法排序是对m个数进行m-1轮排序,每一轮将对为未排好的数进行两两比较,只要次序不对立即进行交换,一轮下来,该轮最后一个的次序就可确定下来,也此也就象冒泡一样而得名冒泡法。
冒泡法的核心程序段是(从小到大):
For i = 1 To m – 1 ‘进行
m-1轮比较
For j = m To i+1 step –1 ‘从m~i个元素进行两两比较
If ab(j) < ab(j-1) Then t = ab(j): ab(j) = ab(j-1): ab(j-1) = t Next j Next i
[例5.11]在myvb\\vb5\\ex5_11下
Private Sub Form_Click() ‘生成数组值
Dim i% Randomize m = 10
For i = 1 To 10
ab(i) = Int(Rnd * 1000) - 300 Next i
Call original_numeric(Picture1) Call bubble_method End Sub
Private Sub Form_Initialize()
Form2.Caption = \"冒泡排序(单击窗体)\" Label1.Caption = \"原始数据:\" Label2.Caption = \"排序结果:\" End Sub
Private Sub original_numeric(obj As Object) '输出过程,使用了一个对象型形参 Dim i% obj.cls For i = 1 To m
If i Mod 6 = 0 Then obj.Print
Visual Basic 6.0 第 20 页 共24 页 20
第五章 数组 第21 页 共 24 页
obj.Print ab(i); Spc(1); Next i End Sub
Private Sub bubble_method() '冒泡排序
Dim i%, j%, t%
For i = 1 To m - 1 '进行m-1轮比较 For j = m To i + 1 Step -1 '从 Next j Next i
Call original_numeric(Picture2) '输出结果 End Sub
m~i个元素进行两两比较
If ab(j) < ab(j - 1) Then t = ab(j): ab(j) = ab(j - 1): ab(j - 1) = t
4.数组元素的插入与删除 (1) 插入
在有序数组a(1 to n)(原有n-1个元素)插入一个值Key元素。使得插入key后的数
组仍然有序。 算法:
(1)在1 to n位置中,查找要插入的位置k(1<=k<=n-1);
(2)找到位置后腾出该位置,从最后一个元素开始到第K个元素往后移动一个位置; (3)将数据Key插入到腾出的第k个元素的位置。 1
4 7 10 13 16 19 22 25 示例:将14插入到以下数组中去
14
[例5.12]在myvb\\vb5\\ex5_12下
Dim a%(1 To 10) '窗体级数组 Private Sub Form_Load()
Form2.Caption = \"插入(单击第一个图片框)\" Label1 = \"插入前的数组值\" Label2 = \"插入后的数组值\" Label3 = \"插入值\"
End Sub
Private Sub Picture1_Click() Dim i%, k%, key%, key1 As Variant
Visual Basic 6.0 第 21 页 共24 页 21
第五章 数组 第22 页 共 24 页
Randomize Picture1.Cls Picture2.Cls Picture3.Cls key = Rnd * 20 + 5
For i = 1 To 9 '生成数组值 a(i) = key * i Next i
For i = 1 To 9
Picture1.Print a(i); Spc(1); Next i
Do '输入插入值
key1 = InputBox(prompt:=\"输入插入值\
Loop Until key1 <> Empty And IsNumeric(key1) '直接赋给key,不能解决按取消按钮问题 key = key1
Picture3.Print key '显示插入值 For k = 1 To 9 '找插入位置 If key < a(k) Then Exit For Next k
For i = 9 To k Step -1 '腾出插入位置 a(i + 1) = a(i) Next i
a(k) = key '插入
For i = 1 To 10 '显示插入后的数组 Picture2.Print a(i); Spc(1); Next i End Sub
(2) 删除
首先也是要找到欲删除的元素的位置k;然后从k+1到n个位置开始向前移动;最后将数组元素个数减1。
示例:将13从以下数组中删去
1
[例5.13]在myvb\\vb5\\ex5_13下
Dim a() As Integer '窗体级数组,动态的 Private Sub Form_Load()
Visual Basic 6.0 第 22 页 共24 页 22
4 7 10 13 16 19 22 25 第五章 数组 第23 页 共 24 页
Form2.Caption = \"删除(单击第一个图片框)\" Label1 = \"删除前的数组值:\" Label2 = \"删除后的数组值:\" Label3 = \"删除值\" End Sub
Private Sub Picture1_Click()
Dim i%, k%, key%, key1 As Variant, n% n = 10 '数组上界 Picture1.Cls Randomize
key = Rnd * 20 + 3 ReDim a(1 To n)
For i = 1 To 10 '生成数组值 a(i) = key * i Next i
For i = 1 To n
If i Mod 6 = 0 Then Picture1.Print
Picture1.Print a(i); Spc(1); Next i start:
Do '输入删除值
key1 = InputBox(prompt:=\"输入删除值\Loop Until key1 <> Empty And IsNumeric(key1) '直接赋给
key,不能解决按取消按钮问
题
key = key1
Picture3.Cls '必须 Picture3.Print key '显示删除值 For k = 1 To n '找删除位置 If key = a(k) Then Exit For Next k If k > n Then
MsgBox prompt:=\"删除值不在数组中\" Picture2.Cls For i = 1 To n
If i Mod 6 = 0 Then Picture2.Print Picture2.Print a(i); Spc(1); Next i
GoTo Continue 'Exit Sub Else
Visual Basic 6.0 第 23 页 共24 页 23
第五章 数组 第24 页 共 24 页
For i = k To n - 1 '删除 a(i) = a(i + 1) Next i End If Picture2.Cls
For i = 1 To n - 1 '显示删除后的数组 If i Mod 6 = 0 Then Picture2.Print Picture2.Print a(i); Spc(1); Next i
n = n - 1
If n >= 1 Then ReDim Preserve a(1 To n) Else Exit Sub Continue:
key1 = MsgBox(\"继续删除?\If key1 = vbYes Then GoTo start End Sub
5.8 数组中常见错误和注意事项
1.静态数组声明下标出现变量 n = InputBox(\"输入数组的上界\")
Dim a(1 To n) As Integer
2.数组下标越界 引用的下标比数组声明时的下标范围大或小。
Dim a(1 To 30) As Long, i%
a(1) = 1: a(2) = 1
For i = 3 To 30 a(i) = a(i - 2) + a(i - 1) Next I
3.数组维数错 数组声明时的维数与引用数组元素时的维数不一致。
Dim a(3, 5) As Long
a(I)=10
4.Aarry函数使用问题 只能对Variant 的变量或动态数组赋值。 5.获得数组的上界、下界 Ubound 、Lbound函数
Visual Basic 6.0 第 24 页 共24 页 24
因篇幅问题不能全部显示,请点此查看更多更全内容