第六章 过 程
本章要求:
1.掌握子过程 (Sub过程的定义, 调用 );
2.掌握函数过程 ( Function过程 ) 的定义, 调用;
3.掌握值传递, 地址传递的传递规则 。
本章重点:
1.Sub过程及 Function过程的定义与调用
2.过程调用中数据的传递 。
本章难点:
过程调用中数据的传递。
6.1 Sub过程
在 VB中,的 Sub子过程分为,事件过程和通用过程
6.1.1 事件过程
( 1) 窗体事件的语法
Private Sub Form_事件名 (参数列表 )
<语句组>
End Sub
( 2)控件事件的语法
Private Sub 控件名 _事件名 (参数列表 )
<语句组>
End Sub
6.1 Sub过程
6.1.2 通用过程( Sub过程)的定义
子过程的定义形式如下:
[Public|Private][Static] Sub 子过程名 ([形参表 ])
<局部变量或常数定义 >
<语句组>
[Exit Sub]
<语句组>
End Sub
说明,( 1) 子过程名:命名规则与变量名规则相同 。
子过程名不返回值, 而是通过形参与实参的传递得到结果,
调用时可返回多个值 。
6.1 Sub过程
( 2) 形式参数列表,形式参数通常简称, 形参,, 仅表示
形参的类型, 个数, 位置, 定义时是无值的, 只有在过程被
调用时, 虚实参结合后才获得相应的值 。
( 3) 过程可以无形式参数, 但括号不能省 。
( 4) 参数的定义形式:
[ByVal| ByRef]变量名 [( )][As 类型 ][,…],
ByVal表示当该过程被调用时,参数是按值传递的;缺省或
ByRef表示当该过程被调用时,参数是按地址传递的。
6.1 Sub过程
例 6.1 编一个交换两个整型变量值的子过程。
Private Sub Swap( X As Integer,Y As Integer)
Dim temp As Integer
Temp=X, X=Y, Y=Temp
End Sub
Private Sub command1_click()
Dim a%,b%
a=val(inputbox(“a=“))
b=val(inputbox(“b=“))
print,a=“;a,”b=“,b
call swap(a,b)
print,a=“;a,”b=“,b
End Sub
6.1 Sub过程
6.1.2 通用过程的建立
通过, 工具, 菜单中的, 添加过程, 命令, 出现, 添
加过程, 对话框 ( 见图 6.1), 选择过程类型 ( 子过程, 函
数, 属性, 事件 ) 及作用范围 ( 公有的 Public,私有的
Private), 单击确定后得到一个过程或函数定义的结构框
架 ( 模板 ), 如:
Public Sub Sort( )
……
End Sub
6.1 Sub过程
6.1.3 过程的调用
1 子过程的调用
子过程名 [参数列表 ]
或 Call 子过程名 (参数列表 )
说明:
( 1) 参数列表 称为实参或实元,它必须与形参保持个数相
同,位置与类型一一对应。
( 2)调用时把实参值传递给对应的形参。其中值传递(形
参前有 ByVal说明)时实参的值不随形参的值变化而改变。而
地址传递时实参的值随形参值的改变而改变。
6.1 Sub过程
( 3)当参数是数组时,形参与实参在参数声明时应省略
其维数,但括号不能省。
( 4)调用子过程的形式有两种,用 Call关键字时,
实参必须加圆括号括起,反之则实参之间用,,, 分隔。
例:调用上面定义的 Swap子过程的形式:
Swap a,b
Call Swap(a,b)
6.1 Sub过程
过程调用的执行过程:
Private Sub CmdOK()
……
Call Swap(a,b)
……
Swap a,b
End Sub
Private Sub Swap(x%,y%)
Dim temp%
Temp=X
X=Y
Y=Temp
End Sub
6.2 Function过程
Visual Basic函数分为内部函数和外部函数,外部函数
是用户根据需要用 Function关键字定义的函数过程,与子
过程不同的是函数过程将返回一个值 。
6.3.1 函数过程( Function过程)的定义
[Public|Private][Static]Function 函数名 ([<参数列表 >])[As<类型 >]
<局部变量或常数定义 >
<语句块 >
[函数名 =返回值 ]
[Exit Function]
<语句块 >
[函数名 =返回值 ]
End Function
6.2 Function过程
说明:
( 1) 函数名:命名规则与变量名规则相同 。
( 2) 在函数体内, 函数名可以当变量使用, 函数的返回值就
是通过对函数名的赋值语句来实现的, 在函数过程中至少要对
函数名赋值一次 。
( 3) AS类型:是指函数返回值的类型, 若省略, 则函数返回
变体类型值 ( Variant) 。
( 4) Exit Function:表示退出函数过程, 常常是与选择结构
( If或 Select Case语句 ) 联用, 即当满足一定条件时, 退出
函数过程 。
( 5)形参数列表:形参的定义与子过程完全相同。
6.2 Function过程
6.2.2 函数的调用
调用形式如下:
函数名 ( 实参列表 )
说明:
在调用时实参和形参的数据类型, 顺序, 个数
必须匹配 。 函数调用只能出现在表达式中, 其功能是求
得函数的返回值 。
6.3 过程之间参数的传递
Visual Basic中不同模块 ( 过程 ) 之间数据的传递有两种方
式:
? 通过过程调用实参与形参的结合实现;
?使用全局变量来实现各过程中共享数据。
6.3.1 形式参数与实际参数
1、形式参数
是指在定义通用过程时,出现在 Sub或 Function
语句中的变量名后面园括号内的数,是用来接收传送给子
过程的数据,形参表中的各个变量之间用逗号分隔。
6.3 过程之间参数的传递
2,实际参数
实际参数是指在调用 Sub或 Function过程时, 写入子过
程名或函数名后括号内的参数, 其作用是将它们的数据 ( 数值
或地址 ) 传送给 Sub或 Function过程与其对应的形参变量 。
实参可由常量, 表达式, 有效的变量名, 数组名 ( 后
加左, 右括号, 如 A( )) 组成, 实参表中各参数用逗号分隔 。
6.4.2 参数传递(虚实结合)
参数传递指主调过程的实参(调用时已有确定值和内存
地址的参数)传递给被调过程的形参,参数的传递有两种方
式:按值传递、按地址传递。形参前加, ByVal”关键字的是
按值传递,缺省或加, ByRef”关键字的为按地址传递。
6.3 过程之间参数的传递
传址与传值
传址,形参得到的是实参的地址,当形参值的改
变同时也改变实参的值。
传值,形参得到的是实参的值,形参值的改变不
会影响实参的值。
例 6.4 按地址传递参数
按地址传递参数时,系统将实际参数(简单变量、数组
或数组元素以及记录)的地址(即变量在内存中的位置)
作为形式参数的地址,以此访问实际参数的内容,也就
是说,形式参数和实际参数占用相同的内存单元。这种
方式下,当程序修改了形式参数的值时,实际上也就修
改了实际参数的值。
Sub Form_Click()
Dim a As Integer,b As Integer
a=10,b=20
tryout a,b
Print ?a=?; a,?b=?; b
End Sub
Sub tryout (x As Integer,y As Integer)
x=x + 100
y=y ? 6
Print ?x=?; x,?y=?; y
End Sub
2,按值传递参数
按值传递参数就是通过值传送实际参数,传送
的是实参的值而不是它的地址。在这种情况下,
系统把需要传送的变量复制到一个临时单元中,
然后把该临时单元的地址传送给被调用的通用
过程。由于通用过程没有访问变量(实参)的
原始地址,因而不会改变原来变量的值,所有
的变化都是在变量的副本上进行的 。
在 Visual Basic中,按值传递参数是通过关键字
ByVal来实现的。也就是说,在定义通用过程时,
如果形参前面有关键字 ByVal,则按值传递该参数,
否则按地址传递该参数。在传值方式下,Visual
Basic为形参分配内存空间,并将相应的实参值
拷贝给各形参。
在 【 例 6.9】 中,如果用传值方式编写通用过
程,则运行结果是不一样的。改为传值方式的
通用过程如下:
Sub tryout (ByVal x As Integer,ByVal y As Integer)
x=x + 100
y=y ? 6
Print ?x=?; x,?y=?; y
End Sub
事件过程 Form_Click不用作任何修改。程序运行后,输出
结果如下:
x=110 y=120
a=10 b=20
6.3.4 数组作过程的参数
Visual Basic允许把数组作为实参传送到过程中 。 数组
作参数是通过传地址方式传送 。 在传送数组时, 除遵守参数
传送的一般规则外, 还应注意以下几点:
1,为了把一个数组的全部元素传送给一个过程, 应
将数组名分别写入形参表中, 并略去数组的上下界, 但括号
不能省略 。
Private Sub Sort(a() As single)
……
End Sub
其中形参, a( )”即为数组 。
6.3.4 数组作过程的参数
2,被调过程可通过 Lbound和 Ubound函数确定实参数组的
上, 下界 。
3,当用数组作形参时, 对应的实参必须也是数组, 且类
型一致 。
4,实参和形参结合是按地址传递, 即形参数组和实参数组
共用一段内存单元 。
例如:定义了实参数组 b(1 to 8),给它们赋了值, 调
用 Sort()函数过程的形式如下:
Sort b( ) 或 Call Sort( b() )
实参数组后面的括号可以省略,但为便于阅读,建议
一般不要省略为好。
6.3.4 数组作过程的参数
调用时形参数组 a和实参数组 b虚实结合, 共用一段内存单
元, 如图所示 。 因此在 Sort()过程中改变数组 a的各元素值,
也就相当于改变了实参数组 b中对应的元素的值, 当调用结束
时, 形参数组 a成为无定义 。
b(1) b(2) b(3) b(4) b(5)
b(6) b(7) b(8)
a(1) a(2) a(3) a(4) a(5)
a(6) a(7) a(8)
参数为数组时虚实结合示意图
【 例 6.10】 在窗体层声明数组,Dim Values () As Integer
编写如下通用过程:
Static Sub changeArray (Min%,Max%,p() As Integer)
For i%=Min% To Max%
p(i%)=i% ^ 3
Next i%
End Sub
Static Sub PrintArray (Min%,Max%,p() As Integer)
For i%=Min% To Max%
Print p (i%)
Next i%
End Sub
6.3.4 数组作过程的参数
编写如下事件过程:
Sub Form_Click()
ReDim Values (1 To 5) As Integer
Call changeArray (1,5,Values ())
Call PrintArray (1,5,Values ())
End Sub
6.3.4 数组作过程的参数
【 例 6.11】 编写一个 Function过程,求数组的最大值。
求数组最大值的通用过程如下:
Private Function FindMax (a() As Integer)
Dim Start As Integer,Finish As Integer
Dim i As Integer
Start=Lbound (a)
Finish=Ubound (a)
Max=a (Start)
For i=Start To Finish
If a (i) > Max Then Max=a (i)
Next i
End Function
该过程先求出数组的上界和下界,然后从整个数组中找出
最大值。过程中的数组是一个形式参数,可以在下面的事
件过程中调用该过程,
Sub Form_Click ()
ReDim b (4) As Integer
b (1)=30
b (2)=80
b (3)=234
b (4)=874
c=FindMax (b ())
Print c
End Sub
执行程序后,单击窗体,输出结果为,874。
6.3.5 对象参数的传送
Visual Basic还允许用对象(窗体或控件)
作为通用过程的参数。其格式为:
Sub 过程名(形参表)
语句块
[Exit Sub]
语句块
End Sub
“形参表, 中形参的类型通常为 Control和
Form。注意,在调用含有对象的过程时,对象
只能通过传地址方式传送。因此在定义过程时,
不能在其参数前加关键字 ByVal。
1,窗体参数的传送
2,控件参数的传送
【 例 6.12】 编写一个通用过程,在过程中设置字体属性,并
调用该过程显示指定的信息。
Sub Fontout (TestCtrl1 As Control,TestCtrl2 As Control)
TestCtrl1.FontSize=16
TestCtrl1.FontName=?隶书 ?
TestCtrl1.FontItalic=True
TestCtrl1.FontBold=True
TestCtrl1.FontUnderline= False
TestCtrl2.FontSize=18
TestCtrl2.FontName=?Times new Roman”
TestCtrl2.FontItalic=False
TestCtrl2.FontUnderline=False
End Sub
上述过程有两个参数,其类型均为 Control。该过程用来设置控件
上所显示的文字的各种属性。为了调用该过程,在窗体上建立两
个文本框,然后编写如下的事件过程:
Private Sub Form_Load ()
Text1.Text=?欢迎光临 ?
Text2.Text=?中国 武汉光谷 ?
End Sub
Private Sub Form_Click ()
Fontout Text1,Text2
End Sub
运行上面的程序,单击窗体,执行结果如图 6.6所示。
6.4 过程的作用域
6.4.1 代码的模块
一般来说,VB应用程序由窗体模块、标准模块和类模块
组成。这三个模块中都可以包含声明和过程,它们形成了
工程的一种模块层次结构,既便于较好地组织工程,也便
于代码的维护。
1,窗体模块
每个窗体对应一个窗体模块,窗体模块包含窗体及其
控件的属性设置、窗体变量的说明、事件过程、窗体
内的通用过程和外部过程的窗体级声明等。
2,标准模块
6.4 过程的作用域
简单的 VB应用程序通常只有一个窗体,此时所有的代码都
存放在窗体模块中。但如果应用程序庞大而复杂时,就需
要多个窗体。在多窗体结构的应用程序中,有些通用过程
和函数需要在多个不同的窗体中共用,为了避免在每个需
要调用该通用过程或函数的窗体中重复键入代码,就需要
创建标准模块,标准模块中包含公共代码的过程。
3,类模块
在类模块中可以编写代码建立新对象,这些新对象可
以包含自定义的属性和方法,可以在应用程序内的过
程中使用。
6.4.2 过程的作用域
6.4 过程的作用域
如果使用 Public关键字定义过程,那么所有模块(包括窗
体模块、标准模块和类模块)中的过程都可以调用该过程,
这样的过程称作公有过程
如果使用 Private关键字定义过程,那么只有与该过程定
义在同一个模块中的其它过程才能调用该过程,而其它
模块中的所有过程却不能够调用该过程,就像它根本不
存在一样,这样的过程称作私有过程。
Static,它的作用是把函数中使用的所有局部变量都转换为
静态变量,这样,在每次调用这个过程时,系统将保留这些
局部变量的值。省略该关键字时,过程调用完毕后,系统将
释放局部变量。 Static关键字对所声明过程之外的变量不起
作用。
6.4 过程的作用域