第5章 过程和函数(3)

2020-05-13 10:08

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 \ End Sub

Sub p1(x As Integer, ByVal y As Integer) x = x * 10 y = y + 20 End Sub

图5-5 两种参数传递方式示意图

该程序实参是a,b,被形参是x、y,其中x是地址传递方式,y是值传递方式。当单击窗体,调用p1 a, b语句后,两种参数调用方式见示意图5-5。实参a的地址传递给形参x,也就是实参a与 形参x共同占用一个内存单元,当对形参x执行语句x = x * 10后,a,x的值都变成200。而实参b仅仅将值传递给形参y,当对形参y执行语句y = y + 20后,形参y的值变成70,但b的值仍然是50。因此单击窗体运行程序后,窗体上显示结果a = 200 ,b = 50。

4.实参与形参结合时应注意的问题

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(\ End Sub

Sub mysub1(var1 As String, Optional var2 As Integer) '第二个参数可选 Text1.Text = var1

Text2.Text = var2 '当前情况下,由于var2没有得到相应实参的值,因此var2在调用

时被赋以Integer类型的默认值,即var2的值为0。

End Sub

2.可选参数的缺省值

前面讲过,一个可选参数被省略时,调用时赋给形参的是它的数据类型的默认值。如果希望在省略一个可选参数时,能够赋给形参一个其他特定的值,就要用到给可选参数设定默认值的方法。可以在声明过程时,通过给可选参数赋值的方法来设定可选参数的默认值。当调用此过程时即使未提供相应实参的值,形参也会以它的默认值来运行程序。

例题:

Private Sub Command1_Click() '省略了第二个参数 Call mysub1(\ End Sub

Sub mysub1(var1 As String, Optional var2 As Integer = 10) '第二个参数可选,设定默认值

时要注意,赋值号要放在类型名称的后面。

Text1.Text = var1

Text2.Text = var2 '此时将var2变量的值10赋给Text2.Text End Sub

5.4.4数组作为参数传递 1.数组传递原则

整个数组可以作为一个实参传递给过程,但是要求过程在声明时相应的形参应加空格来表明是数组。调用时,相应的实参必须是数组,只要数组名,不必加括号。

在调用子过程或者函数过程时,可以将数组或数组元素作为参数进行传递。使用数组元素传递是值传递方式。传递整个数组时,在实际参数与其所对应的形式参数都必须写上所要传递地数组名称和一对小圆括号,如arr(),在被调程序中,不可再用Dim语句来定义所要传递地数组。数组作为参数时必须是按地址传递的,不能使用ByVal关键字修饰。形参数组与实参数组的数据类型应一致。

Sub subP(b() As Integer) For i = 1 To 4 b(i) = 2 * i Next i End Sub

Private 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 i End 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 ' 被查找值位于前半部分 n = int1 - 1

ElseIf 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 Loop

End Function

分析程序,当被查找值正好是数组的第一个或最后一个元素时,函数Search2能否正确执行?

虽然使用折半查找方法的编程稍微复杂一些,但是它的查找效率比顺序查找高得多。在k个元素中查找一个值,进行比较的次数不会超过

。如果k为15,则折半次

数不会超过4次。当k的值很大时,折半查找的优势就更能体现出来了。

折半查找的局限在于,数组中的元素必须是排序了的(递增或递减)。否则,折半查找就无能为力了,只能尝试其他的查找方法,比如,顺序查找法。

3.注意事项

注意:如果实参是一个动态数组,则相应的形参也可以被看做动态数组,在子过程中可以使用语句重新定义。因为数组是按地址传递的,所以,在子过程中改变数组维数、下标上下界以及元素值,同时也改变了父过程的数组。

5.4.5值传递和地址传递的区别

采用值传递只能从外界向过程(函数)传入信息,但不能传出,正是不能传出,过程结束后,形式参数的值就不会影响外界的任何量,因此说,值传递比较安全;而采用地址传递既能传入又能传出,是一种数据通信方式。

值传递和地址传递的一个重要区别:值传递对应的实参是表达式,而地址传递对应的实参只能是变量。

5.5过程和变量的作用域

5.5.1 变量的作用范围

变量的作用范围(作用域)指变量能被某一过程识别的范围。当一个应用程序出现多个过程或函数时,在它们各自的子程序中都可以定义自己的常量、变量,但这些常量或变量并不可以在程序中到处使用。

从下表可以看出,在VB中,可以在过程或模块中声明变量,根据声明变量的位置,变量分为两类:过程级变量(局部变量)和模块级变量(窗体级变量和全局变量)。

表 不同作用范围的3种变量声明及使用规则

全局变量 作用范围 声明方式 声明位置 能否被本模块的其他过程存取 能否被其他模块存取 局部变量 Dim、Static 在过程中 不能 不能 窗体/模块级变量 Dim、Praivate 窗体/模块的\通用声明\段 能 不能 窗体 标准模块 Public 窗体/模块的\通用声明\段 能 能,但在变量名前要加窗体名 能

1.过程级变量

在一个过程内部使用或关键字声明变量时,只有该过程内部地代码才能访问或改变该变

量的值。过程级变量的作用范围限制在该过程内部。例如:


第5章 过程和函数(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:数列求通项公式的常用方法

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: