VB习题过程和函数_第1页
VB习题过程和函数_第2页
VB习题过程和函数_第3页
VB习题过程和函数_第4页
VB习题过程和函数_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第五章 过程和函数对于复杂的程序,结构化程序设计就是对一个复杂的问题采用“分而治之”的策略模块化,把一个较大的程序划分成若干个模块,每个模块只完成一个或者若干个功能。VB也是如此,Visual Basic把程序按功能分为多个模块。每个模块的代码中又分为相互独立的过程,每个过程完成一个具体特定的任务。使用“过程”不仅是实现结构化程序设计思想的重要方法,而且是避免代码重复,便于程序调试维护的一个重要手段。在Visual Basic中就是使用子过程或函数过程来构建应用程序。5.1 VB应用程序结构在建立VB应用程序时,应先设计代码的结构。VB应用程序的结构通常如图5-1所示。VB应用程序.VBP窗体模块.Frm类模块.Cls标准模块.Bas函数过程(Function)Sub过程事件过程Sub过程函数过程(Function)VB将代码存储在3类不同的模块中:窗体模块,标准模块和类模块,如图5-2所示。在这3类模块中都可以包含常量和变量的声明以及Sub、Function过程。它们形成了工程的一种模块层次结构,可以较好地组织工程,同时也便于代码的维护。通过VB环境的工程资源管理器窗口可以清楚地看到一个工程中的模块层次结构。5.1.1 窗体模块每个窗体对应一个窗体模块,窗体模块包含窗体及其控件的属性设置、窗体变量的说明、事件过程、窗体内的通用过程、外部过程的窗体级声明。窗体模块保存在以.frm为扩展名的文件中。默认时应用程序中只有一个窗体,因此有一个以.frm为扩展名的窗体模块文件。如果应用程序有多个窗体,就会有多个.frm为扩展名的窗体模块文件。5.1.2 标准模块简单的应用程序通常只有一个窗体,这时所有的代码都放在该窗体模块中。而当应用程序庞大而复杂时,就需要多个窗体。在多窗体结构的应用程序中,有些程序员创建的通用过程需要在多个不同的窗体中共用,为了不在每个需要调用该通用过程地窗体重复键入代码,就需要创建标准模块,标准模块包含公共代码的过程。标准模块保存在扩展名为.bas的文件中,缺省时应用程序不包含标准模块。标准模块可以包含公有或模块级的变量、常量、类型、外部过程和全局过程的全局声明或模块级声明。缺省时,标准模块中的代码时公有的,任何窗体或模块的事件过程或通用过程都可以调用它。在许多不同的应用程序中可以重用标准模块,在标准模块中可以定义通用过程,但不可以定义事件过程。5.1.3 类模块在VB中,类模块是面向对象编程的基础,文件以.Cls为扩展名。程序员在类模块中编写代码建立新对象,这些新对象可以包含自定义的属性和方法,可以在应用程序中使用。类模块与标准模块的不同之处在于标准模块仅仅含有代码,而模块既含有代码又含有数据。5.1.4 VB过程分类1. 子过程1) 事件过程事件过程由VB自行声明,附加在窗体和控件上,用户不能增加或删除。当用户对某个对象发出一个动作时,Windows会通知VB产生了一个事件,VB会自动地调用与该事件相关的事件过程。事件过程只能放在窗体模块中。事件过程的常用格式如下:Private Sub _事件名( ) End Sub2) 通用过程通用过程由用户定义或删除修改,可以放在标准模块中,也可以放在窗体模块中,其格式如下: Private|Public Sub () End Sub2. 函数过程1) 系统函数VB为了简化程序设计,提供了许多内部函数供设计者调用,如Abs( ),Int( ),ASC( ),MID( )等。常用系统函数的使用在本书的第二章有详细介绍。2) 用户自定义函数除了有固定功能的系统函数之外,还允许用户编写自己的函数过程,被称为用户自定义函数,格式如下:Private|Public Function () As End Function5.2子过程SUB的定义和调用5.2.1创建子过程建立通用过程有两种方法:直接在“代码”编辑窗口中输入过程代码或使用“添加过程”对话框。1在“代码”编辑窗口中输入在“代码”编辑窗口中,把光标定位在已有过程的外面(即通用声明段),然后按如下格式输入通用过程:Private|Public Static Sub () 子过程体 Exit SubEnd Sub说明:1)Public|Private可以将子过程放入标准模块、类模块和窗体模块中。按照缺省规定,所有模块中的子过程为Public(公有的),这样在应用程序中可随处调用它们。如果选用Private,则只有该过程所在模块中的程序才能调用该过程。2) Static若使用Static关键字,则该过程中的所有局部变量的存储空间只分配一次,切这些变量的值在整个程序运行期间都存在,即在每次调用该过程时,各局部变量的值一直存在;若省略Static,过程每次被调用时重新为其变量分配存储空间,当该过程结束时释放其变量的存储空间。3) 过程名过程名的命名规则与变量名相同,长度不超过40个字符。一个过程名只能有唯一的名字,在同一模块中,同一名称不能既作Sub过程名又作Function函数过程名。4) 语句系列是过程的过程体,语句系列中可以用一个或多个Exit Sub语句从过程中退出。5) 形参表形参表中的语法为:ByVal 参数名1 As 类型名,ByVal 参数名2 As 类型名,其中ByVal表明该参数是值传递方式。形参表中出现的参数称为形式参数,简称形参。它并不代表一个实际的存在变量,在调用此过程时,存储对应实参传递过来的确定的值。类似于变量声明,它指明了从调用过程传递给被调过程变量的个数和类型。各变量名之间用逗号分隔,其中的形式参数被缺省为具有Variant数据类型,但建议将形参声明一个指定的数据类型。2使用“添加过程”对话框使用“添加过程”对话框建立过程的步骤为:(1) 打开要添加过程的代码编辑窗口。(2) 执行“工具”菜单中的“添加过程”命令,打开“添加过程”对话框,如图5-3所示。图5-3 过程添加对话框 (3) 在“名称”文本框中输入过程名。从“类型”中选择“子程序”类型。从“范围”组中选择范围,相当于使用Public或Private关键字。(4) 单击“确定”按钮。使用这个方法建立了一个过程模板,可以在模板上添加过程体代码。5.2.2调用子过程SUB过程可以被其它过程(包括事件过程和通用过程)调用。每次调用过程都会执行Sub和End Sub之间的语句系列。Sub过程以Sub开始,以End Sub结束。当程序遇到End Sub时,将退出过程,并立即返回到调用语句的后续语句中。1.调用方法调用Sub过程有两种方法:(1) 使用Call语句:Call ()(2) 直接使用过程名: ()2使用说明(1) 是实际参数表,实参必须用圆括号括起,参数与参数之间用逗号分隔。(2) 当用Call语句调用执行过程时,若无实参,其过程名后圆括号不能省略,若有参数,则参数必须放在括号之内。(3) 若省略Call关键字,则过程名后不能加括号,若有参数,则参数直接跟在过程名之后,参数与过程名之间用空格分隔,参数与参数之间用逗号分隔。例如,以下两个语句都调用Recarea过程:Call Recarea(6,7)Recarea 6,75.3 函数过程的定义和调用函数过程是过程的另一种形式,当过程的执行需要返回一个值时,使用函数就比较简单。Function过程和内部函数一样,可以在程序或函数嵌套中使用。5.3.1创建用户自定义函数过程 与Sub过程一样,Function过程也是一个独立的过程,可读取参数、执行一系列语句并改变其参数的值。创建用户自定义函数过程有两种方法:直接在“代码”编辑窗口中输入函数过程代码或使用“添加过程”对话框。1在“代码”编辑窗口中输入在“代码”编辑窗口中,把光标定位在已有过程的外面,然后按如下格式输入函数过程:函数过程体Private|Public Static Function () As =Exit Function=End Function说明:1) Public|Private与在子过程一样的作用范围。2) Static与在子过程一样的作用。3) 函数过程名函数过程名的命名规则与变量名相同,长度不超过40个字符,同样,一个过程名只能有唯一的名字在同一模块中,同一名称不能既作Function函数过程名又作Sub过程名。As 指定Function过程返回值的类型,可以是Integer,Long,Single,Double,Currency,String或Boolean。如果没有As子句,缺省的类型为Variant。4) 语句系列是函数的过程体,语句系列中可以用一个或多个Exit Function语句从函数中退出。5) 形参表形参表的含义与Sub相同。6) 表达式表达式的值是函数返回的结果。在程序中,通过赋值语句将值赋给函数名,该值就是Function过程返回的值。如果在Function过程中省略了“=”,则该过程返回一个默认值:数值函数过程返回0,字符串函数过程返回空字符串。因此,为了能使一个Function过程完成所指定的操作,通常要在过程中为函数赋值。2使用“添加过程”对话框使用“添加过程”对话框建立过程的步骤与添加子过程步骤一致,只是在“添加过程”对话框中选择类型为“函数”即可。5.3.2调用函数过程1调用方法函数过程的调用比较简单,可以像使用VB内部函数一样来调用Function过程,只需要在表达式中写上它的名字。其语法格式如下:变量函数名(实参1,实参2,实参3,实参n)显然,与调用子程序的方法不同,自定义函数的调用遵循内部函数(如Sin、Abs、ASC等)的调用规则,实参也必须用圆括号括起来。2使用说明实参可以是常量、变量、表达式或数组变量名。实参数据的类型应与子程序定义时的形式参数类型一致。当子程序的形参传送方式是地址传递时,调用时的实参必须是变量,不允许是常量或表达式。例如:a=Myfunction(5,10,1)3实例应用【例5.2】求1到6的阶乘之和,即1!+2!+6! 5.3.3函数过程与子过程的区别函数过程与子过程的区别如下:1)适用范围把某功能函数定义为函数过程或子过程,没有严格的规定,但只要能用函数过程定义的,一定能用子过程定义,反之不一定。因此子过程比函数过程适用范围广。但当只需要返回一个值时,习惯用函数过程,当需要返回多个值时,习惯用子过程。2)返回值函数过程有返回值,函数过程名也就有类型,同时在函数过程体内必须对函数过程名赋值。子过程名没有值,子过程名也就没有类型,不能在子过程体内对子过程名赋值。3实例应用【例5.3】VB提供了一个标准函数Replace(),实现查找与替换的功能。现在分别用用户自定义子过程和函数过程来实现。Public Function MyReplace(s$, OldS$, NewS$) As String Dim i%, lenOldS% lenOldS = Len(OldS) i = InStr(s, OldS) Do While i 0 s = Left(s, i - 1) + NewS + Mid(s, i + lenOldS) i = InStr(s, OldS) Loop MyReplace = sEnd FunctionPublic Sub sMyReplace(s$, OldS$, NewS$) Dim i%, lenOldS% lenOldS = Len(OldS) i = InStr(s, OldS) Do While i 0 s = Left(s, i - 1) + NewS + Mid(s, i + lenOldS) i = InStr(s, OldS) LoopEnd SubPrivate Sub Command1_Click() Dim str As String这三条语句是否能改成:Call sMyReplace(Text1, Text2, Text3)? Print MyReplace(Text1, Text2, Text3) str = Text1 Call sMyReplace(str, Text2, Text3) Text1.Text = strEnd Sub在上述Command1_Click中,替换后的值通过函数名返回,而在子过程中只有通过变量str作为数据通道来传递。特别指出,对象属性不能完成地址方式的传递。5.4 过程调用中的参数传递调用过程的目的,就是在一定的条件下完成某一工作或计算某一数值。调用过程时可以把数据传递给过程,也可以把过程中的数据传递回来。在调用过程中,必须考虑调用过程和被调用过程之间的数据的调用方式。VB中用参数来实现主调过程和被调过程间的数据传递。通常在编制一个过程时,要考虑它需要输入哪些量,进行处理后输出哪些量。正确地提供一个过程的输入数据和正确地引用其输出数据,时使用过程的关键问题,也就是通过调用过程和被调用过程之间的数据传递问题。5.4.1形式参数与实际参数1. 形式参数形式参数是接收数据的变量。形式参数表中的各个变量之间用逗号分隔。形式参数表中的变量类型可以是合法的简单变量,也可以是数组如A(),但不能是定长字符串。例如在形参表中只能用如Str1 As String之类的变长字符串作为形式参数,不能用Str1 As String*40之类地定长字符串作为形式参数,但定长字符串可以作为实际参数传递给过程。2. 实际参数实际参数是指在调用Sub或Function过程时,传递给Sub或Function 过程的常量、变量或表达式。实参表可由常量、表达式、合法的变量名、数组名(后跟左、右括号)组成,实参表中各参数用逗号分隔。5.4.2值传递和地址传递参数传递的方式有两种:值传递和地址传递。3实例应用下面是一个既有值传递又有地址传递的实例。【例5.4】先对a、b赋一个初值,然后调用子过程P1,因参数的传递方式不同,a、b参数的原值发生了变化。程序清单如下:Private Sub Form_Click() Dim a As Integer, b As Integer a = 20: b = 50 p1 a, b Print a=; a, b=; bEnd SubSub p1(x As Integer, ByVal y As Integer) x = x * 10 y = y + 20End Sub4实参与形参结合时应注意的问题1)个数、顺序、类型三一致。实参表与实参表中变量名不必相同,但两表中的个数必须相同,而且各实际参数的数据类型书写顺序必须与相应形式参数的类型要一致。2)形参是值传递时,对应实参可以是表达式、常量、数组元素。3)形参是地址传递时,对应实参只能是简单变量,而且是声明了与形参一致的类型。 4)数组、记录类型、对象做参数时只能是地址传递方式。5)当实参是对象的属性时,是值传递,即使形参是地址传递方式,也不会改变实参的值,也就是不会改变对象的属性值。5.4.3使用参数1. 使用可选参数1)定义可选参数一个过程在声明时定义了几个形参,则在调用这个过程时就必须使用相同数量的实参数。Visual Basic允许在形参前面使用Optional关键字把它设为“可选参数”。Optional关键字可以与ByVal、ByRef关键字同时修饰一个参数。如果一个过程的某个形参为可选参数,则在调用此过程时可以不提供对应于这个形参的实参。如果一个过程有多个形参,当它的一个形参设定为可选参数时,这个形参之后所有的形参都应该用Optional关键字定义为可选参数。2)调用可选参数调用一个具有多个可选参数的过程时,可以省略它的任意一个或多个可选参数。如果被省略的不是最后一个参数,它的位置要用逗号保留。如Call Sub1(int1,int2)表明省略了第二个参数。若一个可选参数没有被省略,则调用语句的实际参数与非可选参数相同。未得到实参值的形参在调用时被赋以形参类型的默认值。【例5.5】 下面的事件过程在调用一个具有可选参数的过程时,省略了相应的实参。Private Sub Command1_Click() 省略了第二个参数 Call mysub1(abcd)End SubSub mysub1(var1 As String, Optional var2 As Integer) 第二个参数可选 Text1.Text = var1 Text2.Text = var2 当前情况下,由于var2没有得到相应实参的值,因此var2在调用时被赋以Integer类型的默认值,即var2的值为0。End Sub2可选参数的缺省值前面讲过,一个可选参数被省略时,调用时赋给形参的是它的数据类型的默认值。如果希望在省略一个可选参数时,能够赋给形参一个其他特定的值,就要用到给可选参数设定默认值的方法。可以在声明过程时,通过给可选参数赋值的方法来设定可选参数的默认值。当调用此过程时即使未提供相应实参的值,形参也会以它的默认值来运行程序。例题:Private Sub Command1_Click() 省略了第二个参数 Call mysub1(abcd)End SubSub mysub1(var1 As String, Optional var2 As Integer = 10) 第二个参数可选,设定默认值时要注意,赋值号要放在类型名称的后面。 Text1.Text = var1 Text2.Text = var2 此时将var2变量的值10赋给Text2.TextEnd Sub5.4.4数组作为参数传递1数组传递原则整个数组可以作为一个实参传递给过程,但是要求过程在声明时相应的形参应加空格来表明是数组。调用时,相应的实参必须是数组,只要数组名,不必加括号。在调用子过程或者函数过程时,可以将数组或数组元素作为参数进行传递。使用数组元素传递是值传递方式。传递整个数组时,在实际参数与其所对应的形式参数都必须写上所要传递地数组名称和一对小圆括号,如arr(),在被调程序中,不可再用Dim语句来定义所要传递地数组。数组作为参数时必须是按地址传递的,不能使用ByVal关键字修饰。形参数组与实参数组的数据类型应一致。Sub subP(b() As Integer) For i = 1 To 4 b(i) = 2 * i Next iEnd SubPrivate Sub Command1_Click() Dim a(1 To 4) As Integer a(1) = 5 a(2) = 6 a(3) = 7 a(4) = 8 subP a 或者subP a() For i = 1 To 4 Print a(i) Next iEnd Sub上例中主调程序Command1_Click中调用语句subP a,实参数组a可以带括号也可以省略,形参数组b一定要带上空的括号,不能加下标。如果要传递数组中的某一元素,则在Call语句中只需直接写上该数组元素。例如:Call sub1(arr(3),10)。2实例应用【例5.6】折半查找已知一个数组a(m To n)中各元素的值是从小到大排列的,其中有一个元素的值为b。编程求出这个元素的下标。对于这个问题,最容易想到的方法就是“顺序查找法”。下面的函数Search1就是使用顺序查找法,从数组a中查找值为b的元素,并返回其下标。顺序查找法是从数组的第一个元素开始逐个地比较,虽然编程简单,但是执行效率却很低。在一个有k个元素的数组中查找一个值,平均需要进行k/2次比较。如果数组中有15个元素,则平均比较7.5次。相比之下,折半查找法是比较高效的查找方法。折半查找的思路是:先拿被查找数与数组中间的元素进行比较,如果被查找数大于元素值,则说明被查找数位于数组中的后面一半元素中。如果被查找数小鱼数组中中间元素值,则说明被查找数位于数组中的前面一半元素中。接下来,只考虑数组中包括被查找数的那一半元素。拿剩下这些元素的中间元素与被查找数进行比较,然后根据所在的大小,再去掉那些不可能包含被查找值的一半元素。这样,不断地减少查找方位,直到最后只剩下一个数组元素,那么这个元素就是被查找的元素。当然,也不排除某次比较时,中间的元素正好是被查找元素。折半查找中应该注意的是,如果数组中(或中间过程中)的元素个数是偶数,就没有一个元素正好位于中间,这时取中间偏前或中间偏后的元素来与被查找值进行比较不会影响查找结果的正确性。下面的函数Search2使用折半查找的方法从数组a中查找b值所在的元素,并返回它的下标。Function search2(a() As Integer, b As Integer) As Integer Dim m, n, int1 As Integer m = LBound(A. n = UBound(A. Do int1 = (m + n) 2 找到中间元素的下标 If b a(int1) Then 被查找值位于后半部分 m = int1 + 1 Else 被查找值恰好是中间元素 search2 = int1 Exit Function End If If m = n Then 只剩1个元素 search2 = m Exit Function End If LoopEnd Function分析程序,当被查找值正好是数组的第一个或最后一个元素时,函数Search2能否正确执行?虽然使用折半查找方法的编程稍微复杂一些,但是它的查找效率比顺序查找高得多。在k个元素中查找一个值,进行比较的次数不会超过。如果k为15,则折半次数不会超过4次。当k的值很大时,折半查找的优势就更能体现出来了。折半查找的局限在于,数组中的元素必须是排序了的(递增或递减)。否则,折半查找就无能为力了,只能尝试其他的查找方法,比如,顺序查找法。3注意事项注意:如果实参是一个动态数组,则相应的形参也可以被看做动态数组,在子过程中可以使用语句重新定义。因为数组是按地址传递的,所以,在子过程中改变数组维数、下标上下界以及元素值,同时也改变了父过程的数组。5.4.5值传递和地址传递的区别采用值传递只能从外界向过程(函数)传入信息,但不能传出,正是不能传出,过程结束后,形式参数的值就不会影响外界的任何量,因此说,值传递比较安全;而采用地址传递既能传入又能传出,是一种数据通信方式。值传递和地址传递的一个重要区别:值传递对应的实参是表达式,而地址传递对应的实参只能是变量。5.5过程和变量的作用域5.5.1 变量的作用范围变量的作用范围(作用域)指变量能被某一过程识别的范围。当一个应用程序出现多个过程或函数时,在它们各自的子程序中都可以定义自己的常量、变量,但这些常量或变量并不可以在程序中到处使用。从下表可以看出,在VB中,可以在过程或模块中声明变量,根据声明变量的位置,变量分为两类:过程级变量(局部变量)和模块级变量(窗体级变量和全局变量)。表 不同作用范围的3种变量声明及使用规则作用范围局部变量窗体/模块级变量全局变量窗体标准模块声明方式Dim、StaticDim、PraivatePublic声明位置在过程中窗体/模块的通用声明段窗体/模块的通用声明段能否被本模块的其他过程存取不能能能能否被其他模块存取不能不能能,但在变量名前要加窗体名能1.过程级变量在一个过程内部使用或关键字声明变量时,只有该过程内部地代码才能访问或改变该变量的值。过程级变量的作用范围限制在该过程内部。例如:Dim a As Integer, b As SingleStatic s1 As String如果在过程中未作说明而直接使用某个变量,该变量也被当成过程级变量。用Static说明的变量在应用程序的整个运行过程中一直存在,而用Dim说明的变量只在过程执行时存在,退出过程后,这类变量就会消失。过程级变量通常用于保存临时数据。过程级变量属于局部变量,只能在建立的过程内有效,即使时在主程序中建立的变量,也不能在被调用地子过程中使用。即局部变量的作用域仅限于它们自己所在的过程,使用局部变量的程序比仅是使用全程变量的程序更具有通用性。【例5.7】过程级局部变量实例程序代码清单如下:Private Sub Command1_Click() Dim a As Integer, b As Integer, c As Integer 过程级局部变量 a = 5: b = 3 Print Print Tab(15); a; Tab(25); b; Tab(34); c = a * b Print 调用Prod前; Tab(14); a; Tab(24); b; Tab(34); c Call Prod Print 调用Prod后; Tab(14); a; Tab(24); b; Tab(34); c Print Print 调用Sum前; Tab(14); a; Tab(24); b; Tab(34); c Print Call Sum Print 调用Sum后; Tab(14); a; Tab(24); b; Tab(34); cEnd SubSub Prod() 通用过程 Dim a As Integer, b As Integer, c As Integer 过程级局部变量 c = a * b Print Prod子程序; Tab(14); a; Tab(24); c; Tab(34); cEnd SubSub Sum() 通用过程 Dim a As Integer, b As Integer, c As Integer 过程级局部变量 c = a + b Print Sum子程序; Tab(14); a; Tab(24); c; Tab(34); cEnd Sub程序运行结果如下图5-6所示,从运行结果可以看出,主程序中的变量没有带到子过程中。在编写一个较复杂的程序时,可能有多个过程或函数。在书写过程(函数)说明时,往往而且应该把注意力集中在一个相对独立的子过程内。其中所用到的变量名如果都是局部的,则无论怎样处理都不会影响到外界。如果用到非局部量,一经改变就会影响到外界,考虑不周时容易引起麻烦,所以,为安全起见,过程(函数)体内应尽可能用局部变量。图5-6 程序运行结果2.模块级变量在模块的通用段中声明的变量属于模块级变量。模块级变量分为窗体模块级和全局级。1)窗体模块级变量窗体模块级变量在声明它的整个模块的所有过程中都能使用,但其他模块却不能访问该变量。声明方法是在模块的通用段中使用Private或Dim关键字声明变量例如:Private s As StringDim a As Integer, b As Single2)全局级变量全局级变量在所有模块的所有过程中都能使用的内存变量。它的作用范围是整个应用程序。全局级变量的声明方法是在模块的通用声明段中使用关键字Public来声明变量。例如:Public x As Integer, y As Double把变量定义为全局变量虽然很方便,但这样会增加变量在程序中被无意修改的机会,因此,如果有更好的处理变量的方法,就不要声明全局变量。【例5.8】Public a As Integer, b As Integer, c As Integer 写在通用的声明中Private Sub Command1_Click() a = 5: b = 3 Print Print Tab(15); a; Tab(25); b; Tab(34); c = a * b Print 调用Prod前; Tab(14); a; Tab(24); b; Tab(34); c Call Prod Print 调用Prod后; Tab(14); a; Tab(24); b; Tab(34); c Print Print Tab(15); a; Tab(25); b; Tab(34); c = a * b Print 调用Sum前; Tab(14); a; Tab(24); b; Tab(34); c Print Call Sum Print 调用Sum后; Tab(14); a; Tab(24); b; Tab(34); cEnd SubSub Prod() 通用过程 c = a * b Print Prod子程序; Tab(14); a; Tab(24); c; Tab(34); cEnd SubSub Sum() 通用过程 c = a + b Print Sum子程序; Tab(14); a; Tab(24); c; Tab(34); cEnd Sub程序运行结果如图5-7所示。从程序运行结果可以看出,在模块级中用声明的全局变量a、b、c,在各个过程中都能访问和修改。图5-7 程序运行结果5.5.2变量的生存期从变量的作用空间来说,变量有作用范围;从变量的作用时间来说,变量有生存期。假设过程内部有一个变量,当程序占有的内存单元是释放还是保留,根据变量在程序运行期间的生命周期,把变量分为静态变量和动态变量。静态变量不释放内存单元,动态变量释放内存单元,有时候可能需要某些局部变量是静态变量,而其他变量为动态变量。1.动态变量动态变量是指程序运行进入变量所在的过程时,才分配该变量的内存单元,经过处理退出该过程后,该变量占用的内存单元自动释放,其值消失,其内存单元能被其他变量占用。使用Dim关键字在过程中声明的局部变量属于动态变量,在过程执行结束后变量的值不被保留,在每一次重新执行过程时,变量重新声明。2.静态变量静态变量是指程序运行进入该变量所在的过程,修改变量的值后,退出该过程,其值仍被保留。即变量所占的内存单元没有释放。当以后再次进入该过程时,原来变量的值可以继续使用。使用Static关键字在过程中声明的局部变量属于静态变量。3全局变量全局变量的值在整个应用程序中始终不会消失和重新初始化,只有当整个应用程序执行结束时,才会消失。4实例应用【例5.9】在窗体上画一个名称为Command1的命令按钮,然后编写如下事件过程。Private Sub Command1_Click()Static x As IntegerClsFor i=l TO 2y=y+xx=x+2NextPrint x,yEnd Sub程序运行后,连续三次单击Command1按钮后,窗体上显示的结果是什么?分析:本题考的是Static语句,所需要的知识点是局部变量和静态变量。本题中x是以Static声明的,它的值在离开Command1_Click事件后是不会丢失的,而y是一个局部变量,它只在过程中有用,离开了过程就不起作用了。单击两次以后,x=8。单击三次以后,当i=l时,y=y+x=0+8=8,xx+2=8+2=10;当i=2时,y=8+10=18,x=10+2=12。因此窗体上显示的结果是12 18。5.5.3过程的作用范围表 不同作用范围的2种过程定义及调用规则作用范围模块级全局级窗体模块标准模块窗体标准模块定义方式过程名前加Private. 例:Private Sub MySub1(形参表)过程名前加Public或默认。 例:Public Sub MySub1(形参表)能否被本模块的其他过程调用能能能能能否被本应用程序其他模块调用不能不能能,但必须在过程名前加窗体名,例:Call 窗体名.My2(实参表)能,但过程名必须唯一,否则要加标准模块名,例:Call 标准模块名.My2(实参表)从表中可以看出,过程也有作用范围(作用域)。在VB中,过程的作用域分为模块级和全局级。1.模块级过程如果在Sub或Function前加关键字Private,则该过程是模块级过程,只能被本模块中的其它过程所调用,其作用域为本模块。2.全局级过程如果在Sub或Function前加关键字Public(可以缺省),则该过程是全局级过程,可被整个应用程序所有模块中定义的其它过程所调用,其作用域为整个应用程序。*3.调用其他模块中的过程在工程的任何地方都能调用其他模块中的全局过程。调用其他模块中的过程的技巧,取决于该过程是在窗体模块中,类模块中还是标准模块中。1)调用窗体中的过程所有窗体模块的外部调用必须指向包含此过程的窗体模块。如果在窗体模块Frm1中包含Sub1过程,则使用下面的语句调用Frm1中的过程: Call Frm1.Sub1(Arguments)2)调用标准模块中的过程如果过程名唯一,则不必在调用时加模块名。无论在模块内还是在模块外,结果总会引用这个唯一过程。如果两个以上的模块都包含同名的过程,那必须要用模块名来限定了。如果在同一模块内调用一个全局过程,则会运行该模块内的过程。例如,对于Mod1和Mod2中同为SubName的过程,从Mod2中调用SubName则运行Mod2中的SubName过程,而不是Mod1中的SubName过程。如果从其他模块调用全局过程名是必须指定那个模块名。例如,若在Mod1中调用Mod2的SubName过程,用后面的语句实现:Mod2.SubName(Arguments)。4. 实例应用全局级过程的调用。在应用程序中包括两个窗体Form1、Form2和一个标准模块Module1。在Form1窗体中定义了一个计算矩形面积的全局级Function过程,在标准模块Module1中定义了一个计算矩形周长的全局级Function过程。【例5.10】运用不同的模块完成计算圆和周长的计算。运行结果如图58所示。图5-8 不同窗体对过程的调用在form1.frm窗体中定义如下代码:Private Sub Command1_Click(Index As Integer) Dim a As Single, b As Single a = Val(Text1(0).Text) b = Val(Text1(1).Text) n = Index If n = 0 Then Label2(0).Caption = mianji(a, B. Else Label2(1).Caption = zhouchang(a, B. End IfEnd SubPrivate Sub Form_Load() Form2.ShowEnd SubPublic Function mianji(x As Single, y As Single) As Single mianji = x * yEnd Function在form2.frm窗体中定义如下代码:Private Sub Command1_Click(Index As Integer) Dim a As Single, b As Single a = Val(Text1(0).Text) b = Val(Text1(1).Text) n = Index If n = 0 Then Label2(0).Caption = Form1.mianji(a, B. Else Label2(1).Caption = zhouchang(a, B. End If End Sub在module1.bas窗体中定义如下代码:Private Sub Command1_Click(Index As Integer) Dim z As Single z = Val(Text1.Text) n = Index If n = 0 Then Label2.Caption = mianji(z) Else Label3.Caption = zhou_chang(z) End IfEnd SubPrivate Sub Form_Load() Form2.ShowEnd SubPublic Function zhouchang(x As Single, y As Single) As Single zhouchang = 2 * (x * y)End Function5.5.4高级变量1 使用多个同名变量如果不同模块中的公有变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们。例如,如果有一个在Frm1和Mod1中都声明了的公有Single变量SglY,则把它们作为Frm1.SglY和Mod1.SglY来引用便得到正确值。【例5.11】下面的例子有助于理解如何在不同的模块中使用同名的变量。运行结果如图59所示。图5-9 使用同名的变量设计方法如下:(1)在新工程中添加两个标准模块,并在窗体上增加一个标签Label1、一个文本框Text1和3个命令按钮Command1Command3。(2)在第一个标准模块Module1中声明一个变量x,并编写模块中的Test过程设置它的值:Public x As StringSub test() x = 标准模块1End Sub(3)在第一个标准模块Module2中声明一个变量x,并编写模块中的Test过程设置它的值:Public x As StringSub test() x = 标准模块2End Sub(4)在窗体模块中声明第3个变量x。名为Test的过程又一次设置它的值:Public x As StringSub test() x = 窗体模块End Sub(5)在3个命令按钮从Click事件过程中,每一个都调用了相应的Test过程,并在文本框中显示这3个变量的值。Private Sub Command1_Click() Module1.test Text1.Text = Module1.xEnd SubPrivate Sub Command2_Click() Module2.test Text1.Text = Module2.xEnd SubPrivate Sub Command3

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论