1第八章数组一、引入课题例.输入100个学生的成绩,一起正序输出显示,换行后再一起反序输出。思路:为了将输入的100个学生的成绩,先一起正序输出显示,换行后再一起反序输出显示。就必须将这100个成绩一个一个保存起来,显示完一次后,才能再显示一次。不保存起来,就无法再显示。问题:如何将这100个成绩一个一个保存起来?基本方法:可以设立一个一个的变量,将这些成绩按顺序赋值给这些变量,就等于保存起来了。只要保存起来,就可以随意正序、反序输出显示了。问题:要设立几个变量才够呢?100个成绩就需要100个变量,如何设立100个变量呢?容易想到:用x1,x2,x3,……,x100?但是如何对x1,x2,x3,……,x100输入、输出呢?输入100个变量,重复输入100次,必须用循环!循环体如何写呢?是否可以写成:Fori=1To100xi=InputBox(请输入成绩X)Nexti不可以!xi只能代表一个变量,它不会随着I的变化,自动变成x1,x2,x3,……,x100,即xi不可能代表100个变量。即使输入100个成绩,最后xi只留下一个。那么应该怎么办呢?能不能将x与i分离,而且实现x不动,但i确实会随着Fori的变化而变化呢?可以!方法:VB的分离方法是x(i)象x(i)这样的变量称为“数组”(即一组数)。当i=1~100变化时,x(i)也跟着一起变化为x(1)、x(2)、x(3)、……、x(100),产生100个变量。于是,输入100个成绩可以这样解决:Fori=1To100X(i)=InputBox(请输入成绩X)NextiVB中象x(i)这样的变量称为“数组”。前面学的Integer、Long、Single、Double、String、Date、Boolean等都是VB的基本数据类型,可以处理少量的单个数据,称为简单变量。但无法处理大批量的数据。为了处理大批量的数据,VB提供了数组。1.数组的作用数组通常和循环一起使用可以大大减少编程的复杂性,有些算法不用数组就无法实现。例1:输入10名学生的成绩,并将它们的成绩打印到窗体上。PrivateSubForm_click()Fori=1To10x(i)=InputBox(请输入成绩X)NextiFori=1To10printx(i);2NextiEndSub2.数组的概念数组是一批数据或控件的集合。数组:由一定数目的同类元素按一定顺序排列而成的结构类型数据,是一组具有同一名字、不同下标的下标变量。一般格式:s(n)其中:s称为数组名,n是下标一个数组可以含有若干个下标变量(或称数组元素),下标用来指出某个数组元素在数组中的位置。如s(3)代表s数组中的下标为3的元素。例如,定义一个integer型数组a(10),它包含11个同类型的变量:a(0),a(1),……,a(10)Variant型数组则可以存放不同类型的数据3.数组元素和数组的维数数组的成员称为数组元素,其名称与数组名相同,其下标表示该元素在数组中的位置。因此,数组元素也称下标变量。数组的维数表示数组元素需要几个下标才能正确表示其在数组中的位置,它代表数组的逻辑结构,最多60维。一维数组的逻辑结构是线性的,只用一个下标表示各个元素在数组中的位置例a(10):含11个元素的一维数组a(0),a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10)二维数组的逻辑结构是一个二维表,用两个下标表示各个元素在数组中的位置:第一个下标表示行,第二个下标表示列。例b(2,3):含三行四列共12个元素的二维数组b(0,0)b(0,1)b(0,2)b(0,3)b(1,0)b(1,1)b(1,2)b(1,3)b(2,0)b(2,1)b(2,2)b(2,3)4.数组的存储结构数组在内存中占用一片连续的存储单元。一维数组的存储结构与逻辑结构相同,即各个元素按下标顺序依次存放;二维数组的存储结构是按行的顺序存储各个元素。例如,数组b(2,3)的存储形式为:b(0,0)b(0,1)b(0,2)b(0,3)b(1,0)b(1,1)b(1,2)b(1,3)b(2,0)b(2,1)b(2,2)b(2,3)三维数组是由若干个二维数组组成的,其存储结构是按顺序存储各个二维数组。例如,数组c(1,2,1)的存储形式为:c(0,0,0)c(0,1,0)c(0,2,0)c(1,0,0)c(1,1,0)c(1,2,0)c(0,0,1)c(0,1,1)c(0,2,1)c(1,0,1)c(1,1,1)c(1,2,1)说明:(1).数组是一些具有相同类型的数据的有序集合。所谓“有序”是指数组中的每个元素按照一定的顺序排列在一起。如:x(1)、x(2)、x(3)、……、x(100)就是数组x的100个元素,按1~100的编号顺序排列。(2).同一数组中的每个元素有统一的名称(变量名)。同一数组中的元素一般都是同一类型的数据。VB允许同一数组中的元素包含不同类型的数据。如:x(1)、x(2)、x(3)、……、x(100)都是Single型,它们统一的变量名是x,x也叫数组名。(3).数组用不同的序号来区别各个不同的元素。数组的序号称为“下标”。下标用来指出某个元素在数组中的排列位置。如:x(8)中的8就是下标,x(8)代表数组x中的第8个元素。x(8)不能写成x8或x[8]。(4).下标的形式可以是常量、变量、计算式。3如:x(99)、y(i)、Sum(a+b)。(5).数组可以拥有多个下标。具有一个下标的数组叫一维数组,具有两个下标的数组叫二维数组。如:x(I)是一维数组,s(x,y)是二维数组。(6).数组的操作一般与循环同时使用。如上例。(7).数组必须先定义,后使用。如上例。一、引入要使用数组,应当先定义数组。定义数组的作用:通知计算机为数组留出所需的内存空间,准备存放数据。数组的定义方式;◆Dim:用在窗体模块或标准模块及过程中,定义窗体或标准模块级数组;◆ReDim:用来重新定义动态数组;◆Static:用来说明该数组为静态数组;◆Global(Public):用在全局模块中(标准模块)中,说明数组为全局的;在这里我们可以和前面第4章的变量的作用域进行比较学习。名称作用域声明位置使用语句局部变量过程过程中Dim或Static模块变量窗体模块或标准模块模块的声明部分Dim或Pravite全局变量整个应用程序标准模块的声明部分Public或Global二、新课这里先介绍最常用的Dim方法。有2种格式:1.格式一一维数组Dim数组名(下标上界)[As类型]下标上界为常数、已有值的表达式或变量。下标下界为0。一维数组的大小为:下标上界+1。例:Dimmark(99)AsInteger声明了一维定长整型数组mark,共有100个元素,下标范围为0To99;mark数组的各元素是mark(0),mark(1),…,mark(99);mark(i)表示由下标i的值决定是哪一个元素。mark数组内存分配如下:每个数组元素有一个唯一的顺序号,下标不能超出数组声明时的上、下界范围,否则会产生“索引超出了数组界限”错误。数组元素的使用规则与同类型的简单变量相同二维数组声明Dim数组名(下标1,下标2…)[As类型]下标数决定了数组的维数,每一维的大小=上界+1;数组的大小为每一维大小的乘积。例Dimx(2,4)AsLong声明了一个长整型的二维数组x;共占据3×5个长整型变量的空间例如:DimAge(20)AsInteger’定义一维数组Age,最大下标20DimTest(2,3)AsDouble’定义二维数组Test,2个下标最大分别为2、3注意:(1)问题:数组定义后下标是从什么开始的?如Age(20)的元素有几个:Age(?),mark(i)mark(1)mark(2)…mark(99)mark(100)…4Age(?),……Age(?)。问题:能不能使用元素Age(-1)、Age(21)?Test(2,3)的元素有几个?是哪几个?(2)定义数组时As后可以是任何的基本类型。(初值:数值-0;字符-空串;布尔-False)问题:能不能省略“As类型”。如:DimSum(50)此时定义的数组Sum(50)是什么类型?(3)演示程序PrivateSubForm_click()Dims(10)AsIntegerFori=0To10S(i)=2*iPrints(;i;)=;s(i)NextiEndSub问题:程序中的Dims(10),它有哪几个元素?下标能否改成从1开始(以符合使用习惯)?要改怎么改?这个语句放在哪里?(用Optionbase语句设置,且只能出现在窗体层或模块层,不能出现在过程中,并且必须放在数组定义之前。)改成从1开始后Dims(10)的元素有哪几个?还有没有s(0)这个元素?不改行不行?比如Dims(10),不改下标从1开始,仍然从0开始,直接使用s(1)—s(10),会不会有问题?数组S(10)的下标能不能改成从2开始?用第一种定义格式不行,第二种定义格式可以:2.格式二一维数组一个数组若只有一个下标就能确定一个数组元素的数组中的位置,则称为一维数组;定义形式:Dim数组名([下标下界To]下标上界)As类型名称如:Dima(1to10)asintegerDims(2To10)'下标从2开始到10Dimx(-2To3)'此时有哪几个元素?DimP(1990To2002)'此时有哪几个元素?二维数组由具有两个或多个下标变量所组成的数组称为二维或多维数组。定义形式:Dim数组名([第一维下标下界To]第一维下标上界,[第二维下标下界To]第二维下标界)As类型名称如:Dima(1to10,3To20)asString第二种格式比较灵活。定义数组的讨论:(1)定义数组Dimx(10)时,括号内一般是常数,能不能是变量?不行!即使变量是有数值的也不行。即:x(n)、Sum(aTob)这样定义对不对?问题:数组定义后,使用时下标可否用变量?演示:上面的程序改为:5n=10Dims(n)AsInteger运行后提示s(n)“要求常数表达式”,即使改为s(5+5)都可以,就是不能用变量。注意:数组定义后,程序后面可以使用s(i)=2*I。讨论:定义数组时Dims(10)非要用变量Dims(n)行不行?可以!但Dim必须改成ReDim(重定义)或将数组定义成“动态数组”。演示:上面的程序改为:n=10ReDims(n)AsInteger运行后是正常的。(2)Dimx(10)后省略AsInteger,但又要把x(10)定义为整数,能不能用类型符号代替?类型符号应该放在Dimx(10)的什么位置?A)Dimx(10)%B)Dimx(10%)C)Dimx%(10)D)Dim%x(10)说明:①格式中的数组名的命名与简单变量名相同,可以是任意合法的变量名②类型名称可以是任何VB所定义的合法类型,包括基本类型和用户自定义类型;③格式[]中部分为可选部分,若省略,则下标下界默认为0,或通过下面方式定义下标下界的默认值:OptionBasen其中:n只能为0或1;Option只能出现在窗体层或模块层,且该定义必须在数组定义之前完成,若是多维数组则对每一维都有效。例如:OptionBase1‘设置下标默认为1Dima(5)asinteger‘a数组的各元素下标取值为:1~5Dimx(3,2)assingle‘x数组的第一维下标取值:1~3,第二维下标取值:1~2④数组必须先定义后使用,未定义不能使用,下标为整型常量;⑤当用Dim语句定义数组时,该语句把数组元素初始化为0或空字符串;⑥同一过程中,数组名不能与其他数组名或变量名相同;⑦数组声明中的下标不能是变量,只能是常量;⑧确定数组的上下界值的函数:LBound函数和UBound函数LBound函数返回数组某维的下界(最小下标)。用法:LBound(数组名,[维值])UBound函数返回数组某维的上界(最大下标)。用法:UBound(数组名,[维值])(1)对于一维数组,在使用