1 / 65

第五章 数组

第五章 数组. 教学要求. 掌握数组的定义和使用 掌握动态数组的定义和使用 掌握控件数组的建立和使用 掌握常用算法. 教学内容. 5.1 数组的概念 5.2 数组的基本操作 5.3 动态数组 5.4 控件数组 5.5 程序示例. 5.1 数组的概念. 5.1.1 数组命名与数组元素 5.1.2 数组定义 5.1.3 数组的结构 5.1.4 数组函数及数组语句. 基本概念 前面所说的变量都是指简单变量,即一个变量名对应一个存储单元,只能存储一个值,各个变量之间无关联。

nusa
Télécharger la présentation

第五章 数组

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第五章 数组

  2. 教学要求 • 掌握数组的定义和使用 • 掌握动态数组的定义和使用 • 掌握控件数组的建立和使用 • 掌握常用算法 2

  3. 教学内容 5.1 数组的概念 5.2 数组的基本操作 5.3 动态数组 5.4 控件数组 5.5 程序示例 3

  4. 5.1 数组的概念 5.1.1 数组命名与数组元素 5.1.2 数组定义 5.1.3 数组的结构 5.1.4 数组函数及数组语句 4

  5. 基本概念 前面所说的变量都是指简单变量,即一个变量名对应一个存储单元,只能存储一个值,各个变量之间无关联。 本章我们要介绍的是一种下标变量——数组,是通过一个数组名和下标的组合来表示多个值。用一个相同的名字引用一组变量的数据。 数组,是VB支持的一种复合结构的数据类型。 数组,是用于保存一组具有相同数据类型的有序的变量的集合。 5

  6. 5.1.1 数组命名与数组元素 • 命名规则与简单变量相同。(参阅P45) • 数组名不是代表某一变量,而是一组变量。 • 数组元素: • 由数组名和该元素在数组中的编号(索引、下标)唯一确定,下标是连续的整数。 • 数组元素的一般形式: 数组名(下标1[,下标2,…]) • 数组的维数: • 一维数组——只需一个下标即可唯一确定一个数组元素 • 多维数组——有两个或两个以上下标的数组,每个下标对应一个“维”。 6

  7. 5.1.2 数组定义 • 数组必须先定义后使用。 • 定义数组时,确定其名称、数据类型、维数、每一维的上、下界。 • 数组定义时,系统分配连续的内存空间,用于依次保存所有数组元素。 • 固定大小数组与动态数组。 7

  8. 1、数组说明语句 [格式]: Public|Private|Static|Dim 数组名([<下界1> To]<上界1> [,[<下界2> To]<上界2>,…])As 类型 [说明]: • 声明关键字决定作用域,见下页 • <下界> TO <上界> 决定了每一维的大小,下界指下标的最小值,上界指下标的最大值,其中 [<下界> TO]可省略,此时,默认下界是0。 • 我们习惯于下标是从1开始,可在模块的“通用”声明段中使用如下语句 Option Base 1 则在缺省下界的情况下,默认下界是1。 8

  9. 注意:全局数组、 全局符号常量和全局定长字符串只能在标准模块中定义 9

  10. 举例 - Dim a(6) as integer • Private Name(1999 to 2002) as string *8 Dim b(2,1 to 2) as integer 数组元素分别为:a(0)、a(1)、a(2)、a(3)、a(4)、a(5)、a(6),共7个 数组元素分别为:name(1999) name(2000) name(2001) name(2002) , 用于保存长度为8的字符串数据。 数组元素分别为:b(0,1),b(0,2),b(1,1),b(1,2),b(2,1),b(2,2) 注意:在声明语句中的A(6)是数组说明符, 而在程序其他语句出现的A(6)是一个数组元素。 10

  11. 2 数组的上、下界 • 上、下界表示下标的最大、最小值; • 下界≤上界; • 在固定大小数组定义时,上、下界是常量或常量表达式,不得是变量; • 上、下界应是整数,若不是,则自动四舍五入。 举例: Dim m as integer Const n=5 as integer Dim a(n) as integer Dim b(1 to 6.6) as integer Dim c(1 to 2*3) as integer Dim d(0 to m) as integer × 11

  12. 3 数组的类型 • 可为任一简单数据类型 4 数组的大小 • 指数组中包含元素的个数。 • 一维数组元素个数:上界-下界+1 • 二维数组元素个数: (上界1-下界1+1)*(上界2-下界2+1) 12

  13. 5.1.3 数组的结构 • 数组的所有元素是按一定顺序存储在连续的存储单元的。 1.一维数组的结构 • 例:Dim stra(3) • 逻辑结构:(stra(0),stra(1),stra(2) stra(3)) • 存储结构:按照下标从小到大依次存储 13

  14. 2 二维数组的结构 • 例:Option base 1 Dim y(3,4) as integer • 逻辑结构: y(1,1),y(1,2),y(1,3),y(1,4) y(2,1),y(2,2),y(2,3),y(2,4) y(3,1),y(3,2),y(3,3),y(3,4) • 存储结构: “按列存放” 14

  15. 3 三维数组的结构 • 行、列和页组成的三维表。 • 逻辑结构:见书P88 • 存储结构:“逐页逐列” 15

  16. 5.1.4 数组函数及数组语句 1、返回上、下界函数: 上界:UBound(数组名[,d]) 下界:LBound(数组名[,d]) 说明:d代表维数。省略时表示返回第一维的值。 Dim A(5) As Integer, B(2, 3 to 5) As Integer a1=LBound(A) a1=UBound(A) b1=LBound(B,1) b2=LBound(B,2) b3=UBound(b,1) b4=UBound(b,2) Print a1;a2;b1;b2;b3; b4 举例: 结果:0 5 0 3 2 5 16

  17. (3) Erase 初始化数组语句 格式:Erase a1[,a2,...] 功能:对普通数组初始化(按数组类型给元素赋初值), 对动态数组进行存储空间释放。例:p.89 Option Base 1 Private Sub Form_Click() Dim a(3) As Integer a(1) = 1: a(2) = 2: a(3) = 3 Print a(1), a(2), a(3) Erase a Print a(1), a(2), a(3) End Sub 17

  18. (4) For Each-Next 数组循环结构 格式: For Each Element In <数组名> 语句块 [Exit For] 语句块 Next [Element] 功能:依次(存储次序)处理每一个数组元数,直到数组结束。 说明: Element是Variant变量,它逐个地代表数组中的每一个变量。 18

  19. 例: 请注意:只能一行或一列输出,不能以矩阵形式输出。参见p90 Private Sub Form_Click() Dim E(2, 3) As Integer, V As Variant Dim i As Integer, j As Integer For i = 1 To 2 For j = 1 To 3 E(i, j) = i * 10 + j Next j Next i For Each V In E Print V; Next V End Sub 处理顺序为该数组的存储顺序——按列! 19

  20. 5.2 数组的基本操作 5.2.1 数组元素的赋值 5.2.2 数组元素的输出 5.2.3 数组元素的引用 20

  21. 5.2.1 数组元素的赋值 1 用赋值语句给单个数组元素赋值。 Dim score(3) as integer score(1)=90 : score(2)=80 : score(3)=68 2 在循环结构中,用赋值语句逐一给数组元素赋值。 Dim a(1 to 6) as integer For i=1 to 6 a(i)=int(99*rnd)+1 Next i 3 在循环结构中,利用Inputbox函数给数组元素赋值。 一维数组用一层循环结构 Dim a(1 to 6) as integer For i=1 to 6 a(i)=inputbox(“请输入a(” & I & ”)”,”数组赋值”) Next i 21

  22. 4、Array赋值函数 格式:变体变量名=Array([n1,n2,...]) 功能:将一个变体型变量创建成为一个一维数组,并包含指定的元素。元素的引用方式与一般数组一样。 注意:Array赋值函数只能给变体型变量赋值。不能给其他类型的变量及任何类型的数组赋值。 Option Base 1 Private Sub Form_Click() Dim a As Variant, b As Integer a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) Print a(1), a(5), a(10) a = "Array" Print a b = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) End Sub 22

  23. 5.2.2 数组元素的输出 • 用Print方法显示在窗体或图片框上 • 赋值给文本框的Text属性,在文本框中显示 • 调试时,调用Debug的Print方法在“立即”窗口中显示 5.2.3 数组元素的引用 注意:在引用数组元素时,元素的下标一定要在定义的上下界范围之内,否则“数组越界”出错。 23

  24. Option Base 1 • Private Sub Form_click() • Dim compare(12) As Integer, i As Integer • Dim max As Integer, min As Integer • Randomize • For i = 1 To 12 • compare(i) = Int(90 * Rnd) + 10 • Print compare(i); • Next i • Print • Print "最大数是;"; max • Print "最小数是;"; min • End Sub 例5-1 产生12个两位数,从中找出最大值 、最小值 • max = compare(1): min = compare(1) • For i = 2 To 12 • If compare(i) > max Then • max = compare(i) • ElseIf compare(i) < min Then • min = compare(i) • End If • Next i 24

  25. 例: 有一个一维数组a(20) ,要求按照每行6个元素的格式输出。数组元素为100-200之间的随机数。 Option Base 1 Private Sub Form_Click() Dim a(20) As Integer Dim i As Integer, j As Integer For i = 1 To 20 a(i) = Int(101 * Rnd) + 100 Next i End Sub For i = 1 To 20 Print a(i); j = j + 1 Next i If j Mod 6=0 Then Print 25

  26. 例:二维数组的赋值与输出 Option Explicit Option Base 1 Private Sub Form_Click() Dim i As Integer, j As Integer Dim a(3, 4) As Integer Randomize For i = 1 To 3 For j = 1 To 4 a(i, j) = Int(Rnd * 31 + 20) Next j Next i For i = 1 To 3 For j = 1 To 4 Print a(i, j) ; Next j Print Next i End Sub 程序分析: 程序执行时,计数变量i和j的变化为: i=1时,j从1变化到4,结束内层循环,i变成2 i=2时,j从1变化到4,结束内层循环,i变成3 i=3时,j从1变化到4,结束内层循环,i变成4 结束外层循环。循环变量(i , j)的变化过程为 (1,1)(1,2)(1,3)(1,4) (2,1)(2,2)(2,3)(2,4) (3,1)(3,2)(3,3)(3,4) 正好和二维数组引用的下标一致。 For i = 1 To 3 For j = 1 To 4 s=s & a(i, j) Next j s=s & Chr(13) & Chr(10) Next I Text1.Text=s For i = 1 To 3 For j = 1 To 4 Picture1.Print a(i, j) ; Next j Picture1.Print Next i 二维数组引用必须用二重循环实现 26

  27. 程序执行结果界面 例:下列程序完成在窗体上输出二维数组每行元素之和。回答问题: 1、程序有没有错? 2、错在哪里?3、输出语句应出现在什么地方? Option Base 1 Private Sub Form_Click() Dim a(4, 5) As Integer Dim i As Integer, j As Integer Dim sum As Integer For i = 1 To 4 For j = 1 To 5 a(i, j) = Int(101 * Rnd) + 100 Print a(i, j); Next j Print Next i Print For i = 1 To 4 For j = 1 To 5 sum = sum + a(i, j) Next j Next I Print "第"; i; "行元素之和为:"; sum End Sub Sum=0 Print "第"; i; "行元素之和为:"; sum 27

  28. 有关二维数组的常见问题: • 转置 • 求对角线元素之和 • 求周边元素之和 • 求上、下三角形元素之和 • 求鞍点、最大、最小元素 • 二维数组相乘 28

  29. 例:产生一个3行4列的矩阵,数据为[20,50]之间的随机数,然后将矩阵转置输出。例:产生一个3行4列的矩阵,数据为[20,50]之间的随机数,然后将矩阵转置输出。 Option Base 1 Private Sub Form_Click() Dim i As Integer, j As Integer, a(3, 4) As Integer Randomize For i = 1 To 3 For j = 1 To 4 a(i, j) = Int(Rnd * 31 + 20) Print a(i,j); Next j Print Next I End Sub For j= 1 To 4 For i= 1 To 3 Print a( i , j); Next j Print Next i For i = 1 To 4 For j = 1 To 3 Print a(j ,i); Next j Print Next i 思考题: 求n阶方阵的转置矩阵,并输出? 29

  30. 练 习 1、分别求一个3*3二维数组的主、付对角线元素之和。 2、求二维数组周边元素之和。 30

  31. 5.3 动态数组 定义:在程序运行过程中,可重新定义大小的数组。 说明语句: ① Dim 数组名()as 类型 —在变量说明部分 ② ReDim [Preserve] <数组名>(维界定义)—在可执行语句中 Private Sub Form_Click() Dim Pin( ) As Integer '说明整型的动态数组Pin Dim x as Integer X=Val(Text1.text) ReDim Pin(x) '重新说明数组Pin ... End Sub 注意:- Redim 是可执行语句,只能出现在过程中 - 重新定义动态数组时,不能改变数据类型 - 重定义时,维界定义中可以有变量 31

  32. 说 明 - 如果Redim重定义的数组不存在,则相当于一个说明语句 - 当缺省Preserve参数时,定义后,原来存储在数组中的数据全部丢失,此时可重新定义数组的维数和各维的上下界。 - 当有Preserve参数时,可保留原数组中的数据,但不能改变数组的维数,且只能改变最后一维的维上界。 - 用Dim语句声明过的数组,只是一个空数组,系统并没有给它分配内存空间,此时,不能对数组元素进行存取操作,否则出错。必须用ReDim语句重新定义其大小,系统才给它分配内存,用户才能对此数组元素进行操作。 32

  33. 举例: Option base 1 Dim dynarry() as integer Dim x as integer,y as integer Dynarry(1)=1 Redim dynarry(9) Dynarry(1)=1 x=2:y=4 Redim dynarry(x,y) Dynarry(1,1)=1 Erase dynarry Dynarry(1,1)=1 非法语句,出错 给一维数组元素赋值 给二维数组元素赋值 非法语句,出错 33

  34. 举 例 Option Explicit Option Base 1 Private Sub Form_Click() Dim i As Integer, a() As Integer ReDim a(4) For i = 1 To 4 a(i) = i Print a(i); Next i Print ReDim Preserve a(6) a(5) = 5 a(6) = 6 For i = 1 To 6 Print a(i); Next i End Sub 如果省去 Preserve,会怎样? 34

  35. 例:找出1000以内的所有完数并以指定的格式在列表框中输出。所谓完数,是指它的所有的质因子之和等于它本身的数,如6=1+2+3。例:找出1000以内的所有完数并以指定的格式在列表框中输出。所谓完数,是指它的所有的质因子之和等于它本身的数,如6=1+2+3。 • 解题思路: • 第一步:找出确定一个数是完数 的方法; • 第二步:从1到1000依次判断。 • 算法实现: 两层循环: 内层循环用于找出某数 m 的所有因子并相加求和,并在循环结束后依据因子和是否与该数相等来判断该数是否是完数; 外层循环则用于穷举所有1000以内的整数。 35

  36. Private Sub Command1_Click() Dim i As Integer, j As Integer, s As Integer, k As Integer Dim str1 As String, a() As Integer For i = 1 To 1000 For j = 1 To i – 1 If i Mod j = 0 Then ’是因子,保存进数组并累加求和 s = s + j End If Next j If s = i Then ‘是完数,按指定格式输出 End If Next i End Sub s = 0: k = 0 注意s、k赋初值的位置 k = k + 1 ReDim Preserve a(k) a(k) = j str1 = CStr(i) & "=" For j = 1 To k str1 = str1 & CStr(a(j)) & "+" Next j List1.AddItem left(str1,len(str1)-1)

  37. 5.4 控件数组 5.4.1 基本概念 5.4.2 建立控件数组 5.4.3 使用控件数组 • Load语句 • Unload语句 37

  38. 5.4.1 基本概念 ——由一组具有相同名称的同类型控件组成。 ——控件数组中的每个控件都由其下标属性-Index标识。 即:控件数组名(下标) 如,Option1(0)、 Option1(1)、 Option1(2) ——控件数组中的每一个控件元素可有自己独立的属性设置,但共享同一个事件过程,即无论是控件数组中的哪一个控件响应用户的事件,都触发同一事件过程,但相对于简单控件,事件过程增加了Index参数,由其指明具体响应的控件。 例如:Private Sub Option1_Click(Index As Integer) … End Sub ——注意:控件数组的第一个下标为0 ——优点:使用控件数组编写代码简单、易于维护 38

  39. 5.4.2 建立控件数组 1. 创建同名控件 • 在窗体中放置一组控件(同类型),确定某个控件为第一个元素(可将其Index属性设为0)。 • 按顺序将其它控件的Name(名称)属性改成第一个控件名称(同名)。 • 系统提示“已有一个控件为***,创建一个控件数组吗?”,若第一个控件的Index属性已设为0,则不出现提示。 39

  40. 2. 复制现存控件 • 在窗体中放置一个控件,设置好相应的属性 • 选定该控件,单击“复制”按钮 • 单击“粘贴”按钮 • 系统提示”已有一个控件为***,创建一个控件数组吗?” • 单击“是”按钮 观察控件Index 属性, 系统给每个数组控件标明唯一的索引号, 即为该对象的Index属性(下标)。 40

  41. 例如:在窗体上有一个包含四个命令按纽的控件数组。这4个命令按纽的名称相同,均为Command1 ,系统通过下标---Index属性,区别4个不同的控件:Command1(0),Command1(1),Command1(2),Command1(3)。 这个由4个按纽组成的命令按纽控件数组,具有相同的事件过程,由参数Index决定,到底是哪个按纽被触发。在事件过程中,应根据Index参数,分别进行不同的操作。 Private Sub Command1_Click(Index as integer) … … Select case index Case 0 … Case 1 … …… End select …… End Sub 41

  42. 3.运行时,用语句添加、删除控件数组中的控件3.运行时,用语句添加、删除控件数组中的控件 LOAD 语句 [格式] load object(index) [功能] 在程序运行时,向控件数组中添加控件。 UNLOAD语句 [格式] unload object(index) [功能] 在程序运行时,删除控件数组中的控件。 明白了吗?还是上机验证一下吧! 注 意 - index可以跳序; - UNLOAD语句只能删除由LOAD 语句添加的控件; - 由LOAD 语句添加的控件,其Visible 属性为false,所以要在程序中设置True,才能在窗体上可见; - 由LOAD 语句添加的控件,其大小、位置与原控件一样,隐藏在其背后,所以要重新设置它的Top等属性; 42

  43. 演示裁判 43

  44. Private Sub Form_Load() • Dim i As Intege • For i = 0 To 5 • Text1(i).Text = “” • Label1(i).Caption = "裁判" & i + 1 • Next i • End Sub • Private Sub Command1_Click() • Dim i As Integer, score As Single • For i = 0 To 5 • score = score + Val(Text1(i)) • Next i • score = score / 6 • Text2.Text = Format(score, "##.##") • End Sub • Private Sub Text1_KeyPress(Index As Integer, KeyAscii As Integer) • If KeyAscii = 13 Then • If Index = 5 Then • Command1.SetFocus • Else • Text1(Index + 1).SetFocus • End If • End If • End Sub 44

  45. 5.5 程序示例 • 选择法排序 • 冒泡法排序 • 顺序查找 • 二分查找 45

  46. 例5-2:选择法排序。(设从大到小排序) [分析]:先将N个数存入数组A(N), 第一轮比较,将A(1)与A(2)比较,若A(1)<A(2),则交换A(1)和A(2)的值;再将A(1)与A(3) 、A(4) … A(N)依次按以上规则比较和交换,第一轮比较完毕,N个数中最大数存放到A(1)中 第二轮比较,将A(2)与A(3)、A(4)…A(N)依次比较,结束后,N个数中第二大数存放到A(2)中; 第三轮比较,将A(3)与A(4)、A(5)…A(N)依次比较,完毕后,N个数中第三大数存放到A(3)中; … 第N-1轮比较,A(N-1)与A(N)进行比较;完毕后,A(N-1)中存放第二小的数,显然A(N)中是最小的数。 这样,数组A中的N个元素经过N-1轮扫视,按从大到小的顺序排列。 46

  47. 第四轮比较: 6、5、4、2、1、3 6、5、4、3、1、2 第五轮比较: 6、5、4、3、2、1 第一轮比较: A(1) a(2) a(3) a(4) a(5) a(6) 2 1 3 4 5 6 3 1 2 4 5 6 4 1 2 3 5 6 5 1 2 3 4 6 6 1 2 3 4 5 第三轮比较: 6、5、2、1、3、4 6、5、3、1、2、4 6、5、4、1、2、3 第二轮比较: 6、2、1、3、4、5 6、3、1、2、4、5 6、4、1、2、3、5 6、5、1、2、3、4 [实例说明]:设无序数据为1、2、3、4、5、6,共有6个元素,进行6-1=5轮比较。5次比较情况如下: 47

  48. [选择排序程序] i 既控制外层循环执行的次数,又可作为被比较数的下标 For i=1 to N-1 For j= i+1 to N If A(i) < A(j) Then TEMP=A(i) A(i)=A(j) A(j)=TEMP End If Next j Next i j 既控制内层循环执行的次数,又可作为比较数的下标 48

  49. 直接排序法 • 选择排序法的改进,每轮扫视,只交换一次数据——A(I)仅与其后序元素中最大的元素交换。 • 实现:增设一个point变量,记录本轮最大元素的下标。在每轮扫视开始时,先设初值为I,然后让A(POINT)依次与其后元素比较,当比某元素小时,将该大元素的下标赋给POINT,即让A(POINT)指向本轮大的元素。 • 当每轮扫视结束后,比较I与POINT 的值,若不同,说明 A(I)中不是本轮的最大元素,则交换A(I)与A(POINT)中的元素,否则不交换。 49

  50. [直接排序程序] For i=1 to N-1 point=i For j= i+1 to N If A(point) < A(j) Then point=j Next j If i < > point then TEMP=A(i):A(i)=A(point):A(point)=TEMP End if Next i 50

More Related