第六章数组课后复习材料.docx
- 文档编号:10844697
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:72
- 大小:84.41KB
第六章数组课后复习材料.docx
《第六章数组课后复习材料.docx》由会员分享,可在线阅读,更多相关《第六章数组课后复习材料.docx(72页珍藏版)》请在冰豆网上搜索。
第六章数组课后复习材料
第六章数组
【学习目的和要求】
1.掌握静态数组的定义和程序设计方法
2.掌握动态数组的定义和程序设计方法
3.熟悉控件数组的创建和使用
4.掌握数组常用算法的程序设计
【学习要点】
一.何时需要使用数组?
在程序设计过程中,如果需要对一组同类型的很多数据进行处理时,就必须使用数组进行程序设计。
比如求某班级80个学生某门课成绩的平均分,再统计所有高于平均分成绩的学生人数。
如果不用数组,通过简单变量,要么定义80个变量来保存学生的成绩,光赋值语句就得写80行,要么采用循环程序设计,定义一个变量,通过80次循环来接收每个学生的成绩,并计算平均分。
程序段如下:
DimcjAsInteger,sumAsInteger,aveAsSingle
DimiAsInteger
Fori=1To80
cj=InputBox("请输入第"&i&"个学生的成绩")
sum=sum+cj'求总分
Nexti
ave=sum/80'求平均分
问题是:
当求出平均分后,还需要统计成绩高于平均分的学生人数,而变量cj只能存放一个值,在本循环结束后,cj中存放的是最后一个学生的成绩,它无法同时保存80个学生的成绩,只能再编写程序重新输入80个学生的成绩,依次与平均分进行比较,程序段如下:
Fori=1To80
cj=InputBox("请输入第"&i&"个学生的成绩")
Ifcj>aveThenn=n+1'统计成绩高于平均分的人数
Nexti
Print"成绩高于平均分的人数有"&n&"个"
这样处理会带来2个问题:
1.数据的输入量变为原来的2倍
2.数据量很大,在第二次输入过程中很可能出现与第一次不一致的情况,造成数据统计的错误。
在类似的问题上,如果采用数组处理就可以有效解决上述问题。
数组在形式上可以看成为一组同类型的数据集合,每个数组元素拥有相同的名称,但根据其在数组中的位置分配一个唯一标识的序号,如本例中,可以定义一个数组cj(80)来表示成绩,数组名为cj,cj
(1)表示第1个学生的成绩,cj
(2)表示第2个学生的成绩,……,这样只要一次输入,就可以有效解决上面的问题。
二.数组的形式
1.一维数组
在上例中,只要用一个下标就可以标识一个数组元素,这样的数组称为一维数组。
比如定义一个一维数组a(10),表示数组名为a,数组中有11个元素(注意:
VB中数组的下标默认为从0开始),分别是a(0)、a
(1)、a
(2)、……、a(10)。
2.二维数组
从形式上看,可以把一维数组看成是一个数列,适合于类型相同的一组数据的处理,但有的时候用一维数组处理就不能满足要求了。
比如处理一个班50个人4门课的成绩,将其按总分从高到低的顺序进行排序。
很显然,这是一张二维表,每个人的4门课成绩构成表中的一行,要表示其中每个人的成绩,都需要指定行和列两个下标才能唯一的确定,这时就需要定义一个二维数组。
如定义一个数组cj(50,4),用cj(1,1)表示第一个人的第一门课成绩,cj(2,3)表示第二个人的第三门课成绩。
象这样,需要两个下标才能确定一个数组元素在数组中的位置,这样的数组称为二维数组。
从形式上看,二维数组就是一张二维表格。
比如定义一个二维数组a(1To3,1To4),共有12个元素,分成3行4列,其中每个元素的分布如下表5-1所示:
表5-1
a(1,1)
a(1,2)
a(1,3)
a(1,4)
a(2,1)
a(2,2)
a(2,3)
a(2,4)
a(3,1)
a(3,2)
a(3,3)
a(3,4)
3.多维数组
如果数组中的每个元素需要2个或2个以上的下标才可以标识,这样的数组统称为多维数组。
比如三维数组a(3,4,2)中的每个元素都需要3个下标才能够唯一的确定。
以后我们进行程序设计时,定义的数组一般不会超过三维,所以应重点掌握一维和二维数组的使用。
三.数组的定义
程序中用到的变量,可以不定义就使用,如果没有定义,系统会自动定义其类型为变体型。
但数组不可以直接使用,所有的数组只有先定义才可以使用。
VB提供了两类数组可以定义。
1.固定大小的数组定义
如果在程序设计时可以确定其大小和维数,这样的数组称为固定大小数组。
比如:
Dima(20)AsInteger,表示定义一个固定大小的数组a,有21个元素,下标从0到20。
固定大小的数组一经定义,以后在程序中就不能再改变其大小和维数。
例6-1以下定义数组的语句错误的是______。
A.Dima(-3to5)AsInteger
B.Dima(1to6.7)AsSingle
C.Dima(n)AsInteger
D.Dima(-2to3,2*3)AsInteger
分析:
选项A中定义一个整型的一维数组,分别为a(-3)、a(-2)、……、a(5),共9个元素;在VB中如果数组下标不是整数,系统会自动四舍五入取整,所以选项B等价于Dima(1To7)AsInteger;选项D表示定义一个整型的二维数组,其中第一维的下标从-2到3,第二维的下标从0到6,一共有6*7=42个元素;选项C是错误的,因为VB不允许用变量来定义数组,如果不能确定数组大小,定义时数组名后的()中也不能是变量,必须将其定义成动态数组:
Dima()AsInteger,数组名后的()中不写任何内容。
考虑以下定义数组的语句是否正确?
1)ConstnAsInteger=6
Dima(n)AsInteger
2)Dima(n)AsInteger
ConstnAsInteger=6
3)Dima(5To-3)AsInteger
分析:
定义1是正确的,这时n是符号常量,相当于常量6,所以Dima(n)AsInteger等价于Dima(6)AsInteger;定义2是错误的,因为在执行Dima(n)AsInteger之前并没有定义符号常量n,VB不允许用变量定义数组;定义3是错误的,因为定义数组时不允许其下界高于上界。
2.动态数组定义
如果在程序设计时不能确定数组的大小和维数,就必须定义动态数组。
动态数组的大小和维数可以在程序运行时根据需要改变。
动态数组的定义和固定大小数组不同,它一般分两个步骤进行:
1)用数组名加()来定义动态数组
比如需要定义一个整型的动态数组b,只能按以下格式定义:
Dimb()AsInteger
表示b是一个数组,但数组的大小和维数都不确定,以后在程序运行时可根据需要定义。
注意:
只能用数组名后加()来定义,不能写成b(n)或b(m,n)或b(,)等形式。
2)用Redim重新定义动态数组大小
动态数组只有用Redim重新定义后才可以使用。
比如上面定义的数组b,如果在程序运行时需要定义其为10个元素的一维数组,则可以执行语句Redimb(1to10),若需要定义其为3行4列的二维数组,则可以执行语句Redimb(1to3,1to4)。
一旦用Redim重定义动态数组后,该数组就可以象固定大小数组一样地使用。
3.OptionBase1
数组默认的下标下界是0,如果希望定义数组的下标从1开始,可以在模块的通用声明段中用OptionBase1说明。
注意:
1)OptionBase后面只可以是0或1,不能是其他数字。
比如不能通过OptionBase2让数组的下标从2开始。
2)OptionBase语句只可以出现在模块的通用声明段,不可以出现在过程中。
四.数组的使用
1.数组元素的引用
数组定义后,可以通过下标来引用数组的每个元素。
和数组的定义不同,引用数组元素时下标可以是变量、常量或表达式。
例6-2以下引用数组元素的语句中正确的是_______。
A.Dima(2,3)AsInteger
a
(1)=10
B.Dima(3To6)AsSingle
a
(1)=1
C.a(n+3)=a(n-1)+a(n)
D.Dima(5)AsSingle
a=1
分析:
选项A中定义一个3行4列的二维数组(注意:
每一维的下标下界默认为0),每个数组元素必须用两个下标表示,比如,第一个元素应该为a(0,0),第2行第2列的元素应该为a(1,1)。
不允许通过a
(1)企图引用二维数组中的某个元素,所以选项A是错误的;选项B中定义一个单精度型一维数组,规定下标的范围从3到6,不存在下标为1的元素,所以引用a
(1)会出现“下标越界”的错误;选项D中定义一个一维数组,数组名为a,拥有6个元素,分别是a(0)到a(5),对数组赋值只能分别对每个元素赋值,而不能通过给a赋值来达到给所有数组元素赋值的目的,程序中并不存在名称为a的变量,所以选项D是错误的;由于引用数组元素时允许下标是变量和表达式,所以选项C的含义是计算a(n-1)+a(n)的值,并将其赋给数组元素a(n+3),比如,当n为2时,该语句的功能是计算a
(1)+a
(2)的值,并将其赋给数组元素a(5),很显然,选项C是正确的。
归纳一下:
1)引用数组元素时要注意,下标不能越界,即数组元素的下标不允许比定义数组时的上界大,也不允许比下界小。
2)一维数组元素用1个下标引用,二维数组元素必须用2个下标引用,依次类推。
3)引用数组元素时,下标可以是变量和表达式。
4)对数组元素操作时,不可以直接引用数组名,只可以引用单个数组元素。
2.数组的相关函数
数组的相关函数只需要掌握以下三个:
1)LBound:
获得数组某一维下标的下界
格式:
LBound(数组名)或LBound(数组名,维数)
比如Lbound(a)表示返回数组a第一维下标的下界;Lbound(a,2)表示返回数组a第二维下标的下界。
2)UBound:
获得数组某一维下标的上界
格式:
UBound(数组名)或UBound(数组名,维数)
例6-3执行以下程序段,输出结果是_______。
Dima(-3To5)AsSingle
Dimb(3,4)AsInteger
PrintUBound(a),UBound(b,1)
PrintLBound(a),LBound(b,2)
分析:
根据UBound和LBound函数的功能可以知道,第一行的输出结果是53,第二行的输出结果是-30。
3)Array函数
利用Array函数可以将一个变体型变量创建成一维数组,同时实现数组元素的赋值。
例6-4执行以下程序段,第一行输出结果是_______,第二行输出结果是_______。
PrivateSubForm_Click()
Dima
DimiAsInteger
a=Array(1,2,3,4,5,6,7,8,9)
Fori=0To3
Printa(5-i);
Next
a=Array("abc","123","def")
Printa
(1)
EndSub
分析:
根据Array函数的功能,赋值语句a=Array(1,2,3,4,5,6,7,8,9)将变体型变量a创建成一个整型的一维数组,有9个元素,下标从0到8(注意:
默认下标的下界为0),其中a(0)的值为1,a
(1)的值为2,……,a(8)的值为9。
For循环的功能是分别输出a(5)、a(4)、a(3)、a
(2)的值,所以第一行输出结果为6543;执行赋值语句a=Array("abc","123","def")后,a被创建成一个字符串型的一维数组,有3个元素,下标从0到2,a
(1)的值为"123",所以第二行输出结果为123。
例6-5执行以下程序段,输出结果是_______。
PrivateSubForm_Click()
Dima(9)AsVariant
DimiAsInteger
a=Array(1,2,3,4,5,6,7,8,9)
Printa
(2)
EndSub
分析:
由于Array函数只能给变体型简单变量或变体型动态数组赋值,虽然程序中定义的a(9)是变体型数组,却是固定大小的数组,所以上述程序运行时会出错。
考虑一下:
如果将上述程序改成以下程序段,输出结果是多少?
Dima()AsVariant
DimiAsInteger
a=Array(1,2,3,4,5,6,7,8,9)
Printa
(2)
注意:
Array函数只能生成一维数组,不能生成多维数组;Array函数只能给变体型变量和变体型动态数组赋值,赋值时有多少个数值,生成的一维数组就有多少个元素,数组的类型由数值的类型决定。
3.数组相关语句
对于数组的相关语句,只需要大家掌握Erase语句的功能。
例6-6执行以下程序段,输出结果是_______。
OptionBase1
PrivateSubCommand1_Click()
Dima,b(5)AsInteger
a=Array(1,2,3,4,5)
b
(2)=a(a
(1)+2)
Printa
(2),b
(2)
Erasea,b
Printb
(2)
Printa
(2)
EndSub
分析:
程序中定义变量a为变体型变量,b为一维数组,有5个元素,下标从1到5。
执行语句a=Array(1,2,3,4,5)后将a创建成一维数组,有5个元素,值分别为1、2、3、4、5;因为a
(1)值为1,所以语句b
(2)=a(a
(1)+2)等价于将a(3)的值赋给b
(2),第一行的输出结果为23。
注意:
Erase语句对动态数组和固定大小数组有不同的功能。
若a是动态数组,执行语句Erasea的功能是释放动态数组a的空间,此时a没有任何元素,在内存中也没有空间分配,除非用Redim重新定义,否则该数组不可访问;若a是固定大小数组,执行语句Erasea的功能是将原来数组的值全部清空,但数组空间仍存在。
由于a是Array函数创建的动态数组,b是固定大小数组,程序中执行Erasea,b后,数组a的空间将被撤消,数组b的每个元素值将恢复初始值0,所以运行上述程序后,第二行的结果为0,但执行到Printa
(2)语句时程序会出现“下标越界”错,因为此时已经不存在数组元素a
(2)。
五.数组的输入输出操作
数组由于其构成和存储的特殊性,非常适合用循环程序来实现其各种操作。
1.一维数组的输入输出
例6-7定义一个包含20个元素的整型数组,让用户输入每一个值,并在窗体上打印输出。
分析:
假设数组名为a,数组元素下标从1变化到20,即a
(1)到a(20),每一个数组元素都执行统一的输入和输出操作,同样的操作要执行20次,很显然用循环处理更方便。
设一个循环控制变量,假设为i,每个数组元素可用a(i)来表示,i的值从1变化到20,在循环体中对每一个a(i)执行相关操作。
程序如下:
PrivateSubForm_Click()
DimiAsInteger,a(1To20)AsInteger
Fori=1To20
Rem从键盘输入a(i)的值,i的值从1变化到20,即输入a
(1)一直到a(20)的值
a(i)=InputBox("请输入a("&i&")的值")
Nexti
Rem输出a
(1)到a(20)的值
Fori=1To20‘步长缺省,默认为1
Printa(i);
Nexti‘Next语句完成给循环变量i增加步长的操作,即i=i+1
EndSub
不难发现,输入和输出都是20次循环,还可将以上程序简化为:
DimiAsInteger,a(1To20)AsInteger
Fori=1To20
a(i)=InputBox("请输入a("&i&")的值")
Printa(i);
Nexti
这样利用一次循环就可以同时实现输入和输出操作。
当然,以上程序段用Do-loop语句也可实现。
程序段如下:
DimiAsInteger,a(1To20)AsInteger
i=1
DoWhilei<=20
a(i)=InputBox("请输入a("&i&")的值")
Printa(i);
i=i+1‘该语句不可少(产生下一个元素的下标),否则就是死循环
Loop
但对处理数组这样循环次数确定的程序,用For-Next循环更方便。
归纳一下:
任何一维数组的处理均可用一重循环来实现。
假设数组名为a,下标从n1变化到n2,程序段可写成:
(斜体字表示根据特定要求写出相应代码)
DimiAsInteger,a(n1ton2)As指定数据类型
Fori=n1Ton2
对A(i)执行输入输出和其他处理
Nexti
考虑以下程序段,是否可以实现数组的输入和输出?
DimiAsInteger,a(1To20)AsInteger
Fori=1To20
a(i)=InputBox("请输入a("&i&")的值")
Nexti
Printa(i);
(答案:
可以实现输入,但无法实现数组元素的输出操作。
因为跳出循环后,i=21,这里的Printa(i)只能输出一个元素a(21),由于数组中并不存在下标为21的元素,所以会出现下标越界错误。
)
2.二维数组的输入输出
例6-8定义一个3行4列包含12个元素的二维整型数组a,随机产生两位正整数赋给数组的每一个元素,并在窗体上按3行4列打印输出。
分析:
这是一个典型的二维数组。
假设数组下标从1开始,二维数组a(3,4)排列成3行4列的矩阵,如下图显示:
(第一维下标表示行号,第二维下标表示列号)
a(1,1)a(1,2)a(1,3)a(1,4)‘第1行的4个元素,列号由1到4
a(2,1)a(2,2)a(2,3)a(2,4)‘第2行的4个元素,列号由1到4
a(3,1)a(3,2)a(3,3)a(3,4)‘第3行的4个元素,列号由1到4
如果用变量i表示行下标,用变量j表示列下标,每一个二维数组元素均可表示为a(i,j),其中i的值从1变化到3,j的值从1变化到4。
如:
当i值为2,j的值为3时,a(i,j)表示元素a(2,3);当i值为1,j的值为4时,a(i,j)表示元素a(1,4)。
因为对每一个i(i从1变化到3),j的值都是从1变化到4,所以这是典型的双重循环,可用外循环表示行的变化,行号从1到3,内循环表示每一行中列的变化,列号从1到4。
程序如下:
OptionBase1‘设定数组下标从1开始
PrivateSubForm_Click()
DimiAsInteger,jAsInteger
Dima(3,4)AsInteger
Randomize‘随机函数初始化
Fori=1To3‘行号从1变化到3
Forj=1To4‘列号从1变化到4
a(i,j)=Int(Rnd*90)+10‘随机产生数组元素a(i,j)的值
Nextj‘注意循环嵌套时内外循环不可交叉
Nexti
Fori=1To3
Forj=1To4
Printa(i,j);‘按行打印数组元素,每行的四个元素打印在一行中,不换行
Nextj
Print‘打印完一行后换行
Nexti
EndSub
当然,上述程序还可简化为:
OptionBase1
PrivateSubForm_Click()
DimiAsInteger,jAsInteger
Dima(3,4)AsInteger
Randomize
Fori=1To3
Forj=1To4
a(i,j)=Int(Rnd*90)+10
Printa(i,j);
Nextj
Nexti
EndSub
程序执行过程如下:
第1次外循环:
i=1,未超过终值3,执行内循环
j=1给a(1,1)赋值并输出,执行Nextj(j=j+1)
j=2给a(1,2)赋值并输出,执行Nextj(j=j+1)
j=3给a(1,3)赋值并输出,执行Nextj(j=j+1)
j=4给a(1,4)赋值并输出,执行Nextj(j=j+1)
j=5超过终值4,跳出内循环
输出换行符,准备在下一行输出
执行Nexti(i=i+1)
第2次外循环:
i=2,未超过终值3,执行内循环
j=1给a(2,1)赋值并输出,执行Nextj(j=j+1)
j=2给a(2,2)赋值并输出,执行Nextj(j=j+1)
j=3给a(2,3)赋值并输出,执行Nextj(j=j+1)
j=4给a(2,4)赋值并输出,执行Nextj(j=j+1)
j=5超过终值4,跳出内循环
输出换行符,准备在下一行输出
执行Nexti,i=i+1
第3次外循环:
i=3,未超过终值3,执行内循环
j=1给a(3,1)赋值并输出,执行Nextj(j=j+1)
j=2给a(3,2)赋值并输出,执行Nextj(j=j+1)
j=3给a(3,3)赋值并输出,执行Nextj(j=j+1)
j=4给a(3,4)赋值并输出,执行Nextj(j=j+1)
j=5超过终值4,跳出内循环
输出换行符,准备在下一行输出
执行NextI,I=I+1
i=4,超过终值3,外循环结束。
从上述运行过程可看出:
循环总共执行12次,对3行4列的二维数组中的每一个元素都进行了输入和输出操作,由此也可看出循环程序在处理数组问题的优越性。
归纳一下:
任何m行n列的二维数组的处理都可用双重循环来实现。
假设数组名为a,数组下标从1开始,程序段可写成:
(斜体字表示根据特定要求写出相应代码)
DimiAsInteger,jAsInteger
Dima(m,n)As指定数据类型
Fori=1Tom
Forj=1Ton
对a(i,j)执行输入输出和其他处理
Nextj
Nexti
依次类推,其他更高维数组的处理可通过三层及以上循环来实现,实现方法同上面类似。
注意:
和上述一维数组一样,一般情况下,不管是输入还是输出,用a(i,j)引用二维数组元素的语句必须在循环体内,不可以在循环外用a(i,j)引用,否则会出现下标越界错。
3.ForEach-Next结构语句
如果需要对数组中的每个元素执行某个操作,可以使用数组专门的ForEach-Next结构语句实现。
一般利用它实现数组元素的输出操作。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第六 数组 课后 复习 材料