1、第9章 过 程 9.1 函数过程的定义和调用9.2 子过程的定义与调用9.3 参数传递9.4 变量与过程的作用域9.5 递归9.6 常用算法9.1 函数过程的定义和调用 1.引例:已知多边形的各条边的长度,要计算多边形的面积。计算多边形面积,可将多边形分解成若干个三角形。计算三角形面积的公式如下:a b d e f g S1 c S2 S3 )(21)()(zyxczcycxccarea定义函数过程areaPublic Function area(x!, y!, z!) As Single Dim c! c = 1 / 2 * (x + y + z) area = Sqr(c * (c - x
2、) * (c - y) * (c - z)End Function调用函数过程:Sub command1_click() 输入若干个三角形边长 S=area(a,b,c)+area(c,d,e) S=S+area(e,f,g) Print SEnd Sub函数过程的定义函数过程的定义自定义函数过程有两种方法:(1)利用工具工具| |添加过程添加过程命令定义,生成一个函数的框架。(2)利用代码窗口直接定义。函数过程形式:Function Function 函数过程名函数过程名( (参数列表) ) As 类型 局部变量或常数定义 语句块 函数名 = 返回值 函数过程体 Exit Function
3、语句块 函数名函数名 = = 返回值返回值End FunctionEnd Function函数过程的定义函数过程的定义函数过程名函数过程名:命名规则同变量名 参数列表形式参数列表形式: : ByValByVal 变量名变量名()As ()As 类型类型 称为形参或哑元,仅表示参数的个数、类型,无值。函数名函数名 = = 返回值返回值 在函数体内至少对函数名赋值一次Exit Function Exit Function :表示退出函数过程例:编一求最大公约数的函数过程 Function gcd( m%, n%) As Integer If m n Then t = m: m = n: n = t
4、 Do while n0 r = m Mod n : m = n: n = r Loop gcd = mEnd FunctionPrivate Sub Command1_Click() s= “VB程序设计教程程序设计教程5.0版版” Print MyReplace(s, 5.0, 6.0)End SubFunction MyReplace$(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 + le
5、nOldS) i = InStr(s, OldS) Loop MyReplace = s End Function函数过程的调用函数过程的调用 函数过程调用形式:函数过程名函数过程名(参数列表参数列表) 参数列表:称为实参或实元,它必须与形参个数相同,位置与类型一一对应。可以是同类型的常量、变量、表达式。End SubPrivate Sub Command1_Click() s= “VB程序设计教程程序设计教程5.0版版” Print MyReplace(s, 5.0, 6.0)S ”5.0” ”6.0”MyReplace$(s$, OldS$, NewS$) 程序运程序运行流程行流程 9.2
6、 子过程的定义与调用子过程的定义与调用 以下情况使用函数过程存在不足:v不是为了获得某个函数值,而是为了某种功能的处理。v要获得多个结果。VB中提供了使用更灵活的子过程。 子过程定义的方法同函数过程,形式如下:Sub 子过程名子过程名(参数列表) 局部变量或常数定义 语句 Exit Sub 语句End Sub子过程名、形参同函数过程中对应项的规定,当无形参时不要括号。子过程与函数过程的区别子过程与函数过程的区别(1) 函数过程有返回值,过程名就有类型;同时在函数过程体内必须对函数过程名赋值。子过程名没有值,过程名也就没有类型,同样不能在子过程体内对子过程名赋值。(2) 把某功能定义为函数过程还
7、是子过程,没有严格的规定。一般若程序有一个返回值时,函数过程直观;当有多个返回值时,习惯用子过程。(3) 形参个数的确定。形参是过程与主调程序交互的接口,从主调程序获得初值,或将计算结果返回给主调程序。不要将过程中所有使用过的变量均作为形参。(4) 形参没有具体的值,只代表了参数的个数、位置、类型;只能是简单变量、数组名、自定义类型,不能是常量、数组元素、表达式。 子过程的调用是一句独立的调用语句,有两种形式:子过程的调用是一句独立的调用语句,有两种形式:Call 子过程名子过程名(实参列表实参列表)子过程名子过程名 实参列表实参列表用用Call关键字时,若有实参,则实参必须用圆括号括起,关键
8、字时,若有实参,则实参必须用圆括号括起,无实参圆括号省略无实参圆括号省略注意:注意:若实参要获得子过程的返回值,则实参只能是若实参要获得子过程的返回值,则实参只能是与形参同类型的简单变量、数组名、自定义类型变量,与形参同类型的简单变量、数组名、自定义类型变量,不能是常量、表达式,也不能是控件名。不能是常量、表达式,也不能是控件名。将函数过程改为子过程,只需将函数过程的返回结果将函数过程改为子过程,只需将函数过程的返回结果作为子过程的形参。作为子过程的形参。 子过程调用子过程调用9.3 参数传递参数传递 传址的结合过程是:当调用一个过程时,它将实参的地址传递给形参。因此在被调过程体中对形参的任何
9、操作都变成了对相应实参的操作,实参的值就会随过程体内对形参的改变而改变。在调用过程时,一般主调过程与被调过程之间有数据传递,即将主调过程的实参传递给被调过程的形参,完成实参与形参的结合,然后执行被调过程体。在VB中,实参与形参的结合有两种方式,即传址传址(ByRef)和传值传值(ByVal),其中传址又称为引用,是默认的方法。区分两种结合的方法是在要使用传值的形参前加“ByVal”关键字。传址与传值传址与传值过程定义形参前加ByVal关键字表示传值,否则传址。传值的结合过程传值的结合过程:当调用一个过程时,系统将实参的值复制给形参,实参与形参断开了联系。被调过程中的操作是在形参自己的存储单元中
10、进行,当过程调用结束时,这些形参所占用的存储单元也同时被释放。因此在过程体内对形参的任何操作不会影响到实参。传址的结合过程传址的结合过程:当调用一个过程时,它将实参的地址传递给形参。因此在被调过程体中对形参的任何操作都变成了对相应实参的操作,实参的值就会随过程体内对形参的改变而改变。传址与传值传址与传值传值与传址的选用规则:(1) 形参是数组、自定义类型数组、自定义类型只能用传址方式传址方式;(2) 若要将过程中的结果返回给主调程序,则形参必须是传址方式。这时实参必须是同类型的变量名(包括简单变量、数组名、自定义类型等),不能是常量、表达式。(3) 若形参不是前两种情况,一般应选用传值传值方式
11、。这样可增加程序的可靠性和便于调试,减少各过程间的关联。例:例:编写交换两个数的过程,Swap1用传值传递,Swap2用传址传递 。 a的地址 10 10 10aa x x形参实参ByVal 传值传地址例:编一子函数过程,求任意一维数组中各元素之积,主调程序调用该函数,分别求:数组参数的传递数组参数的传递 在VB中允许参数是数组,数组只能通过传址方式进行传递。在传递数组时还要注意以下事项:(1) 在实参列表和形参列表中放入数组名,忽略维数的定义,但数组的圆括号不能省。(2) 如果被调过程不知道实参数组的上下界,可用LBound和UBound函数确定实参数组的下界和上界。511iiat1022i
12、ibt例 :编两个子过程:子过程一求数组中最大值和最小值;子过程二以每行5列显示数组结果。主调程序有10个元素,分别调用两个子过程。 可有一个或若干个标 准模块文件(.bas) 至少一个或若干个窗 体模块文件(.frm) 事件过程(Sub) 自定义子过程 (Sub) 自定义函数过程 (Function) 自定义子过程 (Sub) 自定义函数过程 (Function) 可有一个或若干个类模文件块(.cls) 应用程序 (.vbp文件) 9.4 过程与变量的作用域过程与变量的作用域 VB的应用程序由若干个过程组成,这些过程一般保存在窗体文件(.frm)或标准模块文件(.bas)中。变量在过程中是必
13、不可少的。一个变量、过程随所处的位置不同,可被访问的范围不同,变量、过程可被访问的范围称为变量、过程的作用域。 9.4.1 过程的作用域过程的作用域 1. 窗体/模块级所定义的子过程或函数过程前加Private关键字,过程只能被本窗体(在本窗体内定义)或本标准模块(在本标准模块内定义)中的过程调用。2. 全局级 加Public关键字(缺省)的过程,可供该应用程序的所有窗体和所有标准模块中的过程调用。(1) 在窗体定义的过程,外部过程要调用时,必须在过程名前加该过程所处的窗体名。(2) 在标准模块定义的过程,外部过程均可调用,但过程名必须惟一,否则要加标准模块名。 9.4.2 变量的作用域变量的
14、作用域 1. 局部变量在过程内用在过程内用Dim语句声明的变量语句声明的变量(或不加声明直接使用的变量),只能在本过程中使用的变量,别的过程不可访问。一旦该过程体结束,变量的内容自动消失,占用的存储单元释放。不同的过程中可有相同名称的变量,彼此互不相干。2. 窗体/模块级变量在通用声明段中用在通用声明段中用DimDim语句或用语句或用PrivatePrivate语句声明的变量语句声明的变量,可被本窗体/模块的任何过程访问。3. 全局变量在通用声明段中用在通用声明段中用PublicPublic语句声明的变量语句声明的变量,可被应用程序的任何过程或函数访问。只有当整个应用程序执行结束时,全局变量的
15、值才会消失。 变量的作用域变量的作用域 例如在下面一个标准模块文件中不同级的变量声明:Public Pa As integer 全局变量Private Mb As string *10 窗体/模块级变量Sub F1( ) Dim Fa As integer 局部变量End SubSub F2( ) Dim Fb As Single 局部变量End SubPrivate Function sum(n As Integer) Static j As Integer j = j + n sum = jEnd Function9.4.3 静态变量静态变量 声明形式:Static 变量名变量名 AS 类
16、型类型Static Function 函数过程名函数过程名(参数列表参数列表) As 类型类型Static Sub 子过程名子过程名(参数列表参数列表)过程名前加Static,表示该过程内的局部变量都是静态变量。静态变量在程序运行过程中可保留变量原来的值。而用Dim说明的变量,每次调用过程时,重新初始化。例6.10比较Dim和Static两者说明了变量的区别。 Private Sub Form_Click() Dim i% ,isum% For i = 1 To 5isum = sum(i)Print isum Next iEnd Sub递归过程递归过程在自身定义的内部调用自己。例例6.12编
17、fac(n)=n! 的递归函数Function fac(n As Integer) As Integer If n = 1 Then fac = 1 Elsefac = n * fac(n - 1) End IfEnd Function1) 1fac(*11)fac(nnnnn9.5 递归递归用自身的结构来描述自身就称为递归。最典型的例子是对阶乘运算作如下的定义: )!2() 1()!1()!1(!nnnnnn递推回归递推过程:每调用自身,当前参数压栈,直到达到递归结束条件。回归过程:不断从栈中弹出当前的参数,直到栈空。递归算法设计简单,但消耗的机时和占据的内存空间比非递归大。由此可见构成递归
18、的结构如下: 递归结束条件及结束时的值; 能用递归形式表示,并且递归向终止条件发展。fac(2)=2*fac(1)fac(1)=1fac(4)=4*6fac(3)=3*2fac(2)=2*1fac(3)=3*fac(2)fac(4)=4*fac(3)递归结构递归结构9.6 常用算法常用算法 1.1. 数制转换不同进制数之间的转换,可通过编程来实现;也可通过VB提供的内部函数:十进制转换为八进制函数(Oct)、转换为十六进制函数(Hex)来实现。例:编一函数,实现一个十进制整数转换成二至十六任意进制的字符。一个十进制正整数m转换成r进制数的思路是:将m不断除r取余数(若余数超过9,还要进行相应的
19、转换,例如10变成A,11变成B等),直到商为零,以反序得到结果,即最后得到的余数在最高位。 2.加密和解密在当今信息社会,信息的安全性得到了广泛的重视,信息加密是一项安全性的措施之一。信息加密有各种方法,最简单的加密方法是:将每个字母加一序数, 称为密钥。例如,加序数5,这时AF,a f,B G Y D,ZE;解密是加密的逆操作。例: 编一加密和解密的程序,即将输入的一行字符串中的所有字母加密,加密后还可再进行解密。 9.6 常用算法常用算法 3.查找查找查找在日常生活中经常遇到,利用计算机快速运算的特点,可方便地实现查找。查找是在线性表(在此为数组)中,根据指定的关键值,找出与其值相同的元素。一般有顺序查找和二分法查找。顺序查找根据查找的关键值与数组中的元素逐一比较,若相同,查找成功,若找不到,则查找失败。 例:实现顺序查找。4. 字符处理应用字符处理应用例:编写一个英文打字训练的程序,要求如下:(1) 在标签框内随机产生30个字母的范文;(2) 当焦点进入输入文本框时开始计时,并显示当时的时间;(3) 当输入了30个字母时结束计时,禁止向文本框输入内容,显示打字的速度和正确率。 9.6 常用算法常用算法