高等学校计算机基础教育教材 上海中医药大学现代教育技术中心 计算机教学部
第五章 数 组 ( 4 学时) 5.1 数组的概念 5.2 静态数组及声明 5.3 动态数组及声明 5.4 数组的基本操作 5.5 控件数组 5.6 自定义数据类型 5.7 常用算法(二) 5.8 常见错误
5.1 数组的概念 1. 引例 例 5.1 例 5.1 若我们要求一个班 100 个学生的平均成绩,然后统计高于平均分 的人数。 按以前简单变量的使用和循环结构相结合,求平均成绩程序段如下: aver = 0 For i = 1 To 100 mark = InputBox(" 输入 " + i + " 位学生的成绩 ") aver = aver + mark Next i aver = aver / 100 但若要统计高于平均分的人数,则无法实现。 mark 是一个简单变量,存放的是最后一 个学生的成绩。 已有知识解决方法:再重复输入成绩,带来两个问题: ( 1 )输入数据的工作量成倍增加; ( 2 )若本次输入的成绩与上次不同,则统计的结果不正确。 解决此问题的根本方法,引入数组,始终保持输入的数据,一次输入,多次使用。
5.2 静态数组及声明 数组不是一种数据类型,而是一组相同类型的变量的集合,数组必须先声明后使用。 两类数组: 静态 ( 定长 ) 数组、动态 ( 可变长 ) 数组 1. 静态数组及声明 形式: Dim 数组名 ( 下标 1[, 下标 2…]) [As 类型 ] 声明了数组的名、维数、大小、类型 维数:几个下标为几维数组,最多 60 维。 下标: [ 下界 To ] 上界 省略下界为 0, 必须为常数。 每一维大小:上界-下界 +1 数组大小: 每一维大小的乘积 例: Dim mark(1 to 100) As Integer
Dim lArray( 0 To 3 , 0 To 4) As Long 共有 4×5 个元素 等价于 : Dim lArray(3 , 4) As Long 注意: (1) 下界缺省为 0 ,也可在重新定义数组的下界。例如: 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) 这个数组元素赋值
5.3 动态数组及声明 动态数组指在声明数组时未给出数组的大小 ( 省略括号中的下标 ) ,当要使用 它时,随时用 ReDim 语句重新指出数组大小。形式如下: ReDim 数组名 ( 下标 [ ,下标 2…]) [As 类型 ] 例 Sub Form_Load( ) Dim x( ) As Single 例 5.2 求若干个学生的平均分。 例 5.2 … n =Inputbox(“ 输入 n” ) ReDim x( n ) … End Sub 说明: Dim 、 Private 、 Public 变量声明语句是说明性语句,可出现在过程内或通用 声明段; ReDim 语句是执行语句,只能出现在过程内。 在过程中可多次使用 ReDim 来改变数组的大小和维数。 使用 ReDim 语句会使原来数组中的值丢失,可以在 ReDim 语句后加 Preserve 参数来保留数组中的数据。使用 Preserve 只能改变最后一维的大小,前面几维 大小不能改变。 ReDim 中的下标可以是常量,也可以是有了确定值的变量。 静态数组在程序编译时分配存储单元,动态数组在运行时分配存储单元。
5.4 数组的基本操作 1. 数组元素的赋初值 (1) 用循环 For i = 1 To 10 iA(i)=0 Next i 注意: 利用 Array 对数组各元素赋值,声明的数组是可调数组或连圆括号 都可省,并且其类型只能是 Variant 。 数组的下阶为零,上界由 Array 函数括号内的参数个数可决定,也 可通过函数 Ubound 获得。 (2) Array 函数 Dim ib As Variant ib = Array("abc", "def", "67") For i = 0 To UBound(ib) Picture1.Print ib(i); " "; Next i
2 .数组的赋值 在 VB6.0 中,提供了数组直接对数组的赋值。例如: Dim a() As Variant, b() As Variant, i% a = Array(1, 2, 3, 4, 5) ReDim b(UBound(a)) b = a For i = 0 To UBound(a) b(i) = a(i) Next i 注意:赋值号左边的数组只能声明为 Variant 的 可调数组或简单变量。
5.5 控 件 数 组 一组相同类型的控件组成。 它们共用一个控件名,具有相同 的属性,建立时系统给每个元素赋一个唯一的索引号 (Index) 。 控件数组共享同样的事件过程,通过返回的下标值区分控件 数组中的各个元素。 例: Private Sub cmdName _Click(Index As Integer) … If Index = 3 then ‘ 处理第四个命令按钮的操作 End If … End Sub 1. 在设计时建立控件数组 在窗体上画出控件,进行属性设置,这是建立的第一个元素 选中该控件,进行 “Copy” 进行若干次和 “Paste” 操作建立了所需 个数的控 件数组元素。 进行事件过程的编程。
例 5. 3 例 5. 3 建立含有四个命令按钮的控件数组,当单击某个命令按钮,分 别显示不同的图形或结束操作。 Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 …… " 画直线 " Case 1 …… " 画矩形 " Case 2 …… " 画圆 " Case Else End End Select End Sub 控件名 IndexCaption Command1 0 直线 Command1 1 矩形 Command12 圆 3 结束 Picture1 空白 ——
2 运行时添加控件数组 建立的步骤如下: 在窗体上画出某控件,设置该控件的 Index 值为 0 ,表示该控件为数 组,这是建立的第一个元素。 在编程时通过 Load 方法添加其余的若干个元素,也可以通过 Unload 方法删除某个添加的元素 每个新添加的控件数组通过 Left 和 Top 属性确定其在窗体的位置, 并将 Visible 属性设置为 True 。 例 5.4 利用在运行时产生控件数组,构成一个国际象棋棋盘。 例 5.4 当单击棋格,显示对应的序号, 并且将所有棋格颜色变反。
5.6 自定义数据类型 一组不同类型变量的集合。相当于 C 语言中的结构类型; Pascal 中 的记录类型。 1. 自定义类型的定义 形式如下: 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) 自定义类型中的元素类型可以是字符串,但应是定长字符串。 (3) 不要将自定义类型名和该类型的变量名混淆,前者表示了如同 Integer 、 Single 等的类型名,后者 VB 根据变量的类型分配所需的内存空间,存储数据。 (4) 自定义类型一般和数组结合使用,简化程序的编写。 2 .自定义类型变量的声明和使用 (1) 声明形式: Dim 变量名 As 自定义类型名 例 Dim Student As StudType (2) 引用 形式:变量名. 元素名 例 表示 Student 变量中的姓名,第 4 门课程的成绩,则表示如下: Student.Name , Student.Mark(4) 3 .自定义类型数组的应用 例 5.5 例 5.5 利用自定义类型数组,编写一个输入、显示、查询程序。
5.7 常用算法(二) 1. 统计 例 5.6 输入一串字符,统计各字母出现的次数,不区分字母大小写。 例 5.6 分析: 统计 26 个字母出现的个数,先声明一个具有 26 个元素的数组,每个元素的 下标表示对应的字母,元素的值表示对应字母出现的次数。 从输入的字符串中逐一取出字符,转换成大写字符(不区分大小写 ) ,进 行判断。 运行界面: For I = 1 To le c = UCase(Mid(Text1, I, 1)) If c >= "A" And c <= "Z" Then j = Asc(c) a(j) = a(j) + 1 End If Next I
2. 大量数据的输入 例 5.7 例 5.7 输入一系列的数据,并将它们分离后存放在数组中。对 输入的数据允许修改和自动识别非数字数据。 分析: ( 1 )利用文本框输入和编辑数据,输入时去除非法数字。 ( 2 )输入结束利用 Rplace 函数去除重复输入的分隔符; ( 3 )对利用 Split 函数按分隔符分离,放到数组中; ( 4 )还可利用 Join 函数将数组中各元素合并成一个字符串。
3. 数组元素的插入与删除 (1) 插入 在有序数组 a(1 to n)( 原有 n - 1 个元素 ) 插入一个值 Key 元素,算法: 查找要插入的位置 k ( 1<=k<=n - 1 ) 腾出位置,把最后一个元素开始到第 k 个元素往后移动一个位置 第 k 个元素的位置腾出,就可将数据 Key 插入 (2) 删除 要找到欲删除的元素的位置 k ;然后从 k+1 到 n 个位置开始向前移动; 最后将数组元素减 1 。
补充习题 随机产生 15 个不重复的 A ~ Z (包括 A 、 Z )的大写字母,存放在字符 数组中。 提示: ( 1 )产生字母 A ~ Z 可以通过调用函数 Chr() 、 Int ()、 Rnd ()找出 字母对应的 ASCII 码值。 ( 2 )每产生一个字母,在数组中查找已产生的字母,若找到,刚产 生的字母作废,找不到则产生的字母放入数组中,下标加 1 。 运行界面如下: 课后习题: pg105 页: 第 1 题 第 4 题 第 5 题 第 6 题