1.参数传递方式
在过程定义的参数表中出现的参数称为形式参数。在调用过程语句或表达式中出现的参数表称为实际参数。当调用过程时,调用语句中的实际参数就与定义过程语句中的形式参数在个数位置上一一对应起来,并以某种方式传递数据,这个过程称为参数传递。Visual Basic中过程的参数传递有两种方式:
按地址传递参数(ByRef)
在过程定义语句中,如果形式参数前用关键字ByRef标记或者省略标记,则按地址传递参数。按地址传递参数在Visual Basic 中是缺省的。
按地址传递参数是将实际参数的地址赋值给形式参数,过程执行时,按内存变量地址去访问,即当形式参数改变的同时也改变实际参数的值。
按值传递参数(ByVal)
如果形式参数前用关键字ByVal标记,则按值传递参数。过程执行时,传递的只是实际参数的副本,即对形式参数操作,不会影响到实际参数的本身。
参数传递的两种方式如图1所示,实参a与形参x若按值传递,则形参x得到的是实参a的值,形参x的变化不会影响实参a,即参数的传递是单向的;若按地址传递,形参x得到的是实参a的地址,形参x的改变也会改变实参a,即a的值最终变化为与x一致,也就是说参数的传递是双向的。

由于通用过程test的形参x的前面有关键字ByVal,这对形参x而言是按值传递参数,即在过程中x的值变化并不影响实参a的值,而形参y的前面有关键字ByRef,是按地址传递参数,所以y的变化要影响b的值,程序运行结果如图2所示。
从两种传递参数方式的特点可以总结出:当需要保护实际参数时,应采取按值传递,以防止实际参数被过程改变;当需要获取过程中的操作结果时,应该使用按地址传递方式。
传递数组参数
当用数组作为过程的参数时,用的是“传地址”方式,而不是“传值”方式,即不把数组的各元素值一一传递给过程,而是把数组的起始地址传给过程,使过程中的数组与作为实参的数组具有相同起始地址。用数组作为过程的参数时,可以在数组名的后面加上一对括号,以免与普通变量相混淆。
对数组参数的调用是按地址引用的,过程P的作用是将作为实际参数数组的元素重新赋值,因此输出结果为:2 4 6 8
2可选参数
在一般情况下,一个过程中的形式参数是固定的,调用时提供的实际参数也是固定的。在Visual Basic中,可以指定一个或多个参数作为可选参数。在调用时,可以有选择地传送不同的参数。
为了定义带可选参数的过程,必须在参数表中使用Optional关键字,并在过程体中通过IsMissing函数测试调用时是否传送可选参数。以下程序表示如果没有参数z,则n为x*y;如果有参数z,则n为x*y*z:
Sub multi(x%, y%, Optional z)
n = x * y
If
Not IsMissing(z) Then
n = n * z
End If
Print n
End Sub
上述过程有3个参数,前两个参数与普通过程中的书写格式相同,最后一个参数有关键字Optional指出,且没有指定数据类型,表明该参数是一个可选参数。
调用上面过程时,可以提供两个参数,也可以提供三个参数,都能得到正确结果。用下面的事件过程调用返回结果分别为200和6000。
Private Sub Command1_Click()
multi 10, 20
Call multi(10, 20, 30)
End Sub
值得注意的是过程中如果有可选参数,则该参数必须在参数列表中最后出现,其类型必须是Variant;通过IsMissing函数测试是否向可选参数传送实参值。IsMissing函数的返回值为Boolean类型。在调用过程时,如果没有向可选参数传送实参,则IsMissing函数的返回值为True,否则返回值为False。
3对象参数
窗体参数
VB中可以用数值、字符串、数组作为过程的参数,并可把这些类型的实参传送到过程,此外,还可以向过程传送对象,包括窗体和控件。
格式:
[Private|Public|Static]
Sub<过程名>[(形式参数表)]
过程语句
[Exit Sub]
End Sub
说明:
⑴ “形参表”中形参的类型通常为Control或Form。
⑵ 对象只能通过传地址方式传送。因此不能在参数前加关键字ByVal。
控件参数
和窗体参数一样,控件参数也能作为通用过程的参数,但控件参数的使用比窗体参数要复杂。因为不同的控件所具有的属性不同,所以在用指定的控件调用通用过程时,如果通用过程中的属性不属于控件,则会发生错误。

