《《VB程序设计》第四章第四节 参数的传递.doc》由会员分享,可在线阅读,更多相关《《VB程序设计》第四章第四节 参数的传递.doc(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、VB程序设计第四章第四节参数的传递最后修改: 2010-6-2 23:16:59第四节参数的传递参数是在本过程有效的局部变量,用于传递信息。在调用一个有参数的过程时,首先进行的是“形参和实参结合”,实现调用过程的实参与被调过程的形参之间的数据传递,数据传递有两种方式:按值传递和按地址传递。例如,下面实例由于传递的参数个数不匹配而出错。Private Function Divisor(ByVal x As String,ByVal y As Integer) 函数Divisor计算最大公约数 End FunctionDivisor有两个参数,而调用语句中形参个数只有一个,代码如下:Private
2、 Sub Form_Click()Dim m As Integer, n As Integer, E As IntegerN=InputBox(请输入N )M=InputBox(请输入M )g=Divisor(n) 未提供m参数 Print n;和;m;的最大公约数是: ;gEnd Sub单击窗体运行程序时,则会显示出错信息,如图4-4-1所示。图 4-4-1一、形参和实参1.形参在被调用过程中的形参 ,出现在Sub过程和Function过程中。在过程被调用之前,形参并未被分配内存,只是说明形参的类型和在过程中的作用。形参列表中的各参数之间用逗号(,)分隔,形参可以是变量名和数组名,定长字符串
3、变量除外。2.实参实参是在主调过程中的参数,在过程调用时实参将数据传递给形参。形参列表 和实参列表中的对应变量名可以不同 ,但实参和形参的个数、顺序以及数据类型必须相同。因为“形实结合”是按照位置结合,即第一个实参与第一个形参结合 ,第二个实参与第二个形参结合 ,依此类推。例如,在求最大公约数的例Ex_Divisor1 中被调用函数和调用过程如下:Private Function Divisor(ByVal x As Integer,ByVal y As Integer)End SubPrivate Sub Form_Click()G=Divisor(n,m)End Sub当运行单击窗体事件调
4、用Divisor过程时,首先进行“形实结合”。形参与实参的结合对应关系是:nx,my。3.形参的数据类型在创建过程时,如果没有声明形参的数据类型,则默认为Variant型。例如,将例Ex_Divisor1函数过程中的x为Variant型,y为Integer型:Private Function Divisor(ByVal x,ByVal y As Integer)End Function对于实参数据类型与形参定义的数据类型不一致时, VB会按要求对实参进行数据类型转换,然后将转换值传递给形参。例如,将例Ex_Divisor1函数的实参n的数据类型改为Single型,被调函数如下:Private
5、Sub Form_Click() Dim n As Single,m As Integer, g As IntegerN=InputBox(请输入N )M=InputBox(请输入M )G=Divisor(n,m)Print n;和 ;m;的最大公约数是: ;gEnd Sub被调函数过程如下:Private Function Divisor(ByVal x As Integer, ByVal y As Integer)End Sub 运行上述程序,当从InputBox输入框中输入n为44.5,m为25。当执行“g=Divisor(n,m)”语句时,先将Single型的n转换成44(Intege
6、r),然后将44x,25y. 运行结果为: 44.5和25的最大公约数是:14.使用可选的参数参数列表中的参数可以是可选的,在参数表中含有Optional关键字的参数是可选的。如果某一参数为可选参数,则参数表中此参数后面的其他参数也必须是可选的,并要用 Optional来声明。例如,例Ex_Divisor1的被调函数定义修改为:Private Function Divisor(Optional x As Intege,Optional y As Integer)在Form_Click事件过程中,程序代码如下:g=Divisor(n) 未提供第二个参数g=Divisor(,n) 未提供第一个参数
7、在未提供可选参数时,实际上是将该参数作为具有Variant型的Empty来赋值。不过,在本程序中如果将m或n作为Empty,在Divisor函数中的mod运算时会出错。二、参数按值传递和按地址传递在VB中传递参数有两种方式:按值传递(Passed By Value)和按地址传递(Passed By Reference),其中按地址传递习惯上称为“引用”。1.按值传递参数按值传递使用ByVal关键字。按值传递参数时,VB给传递的形参分配一个临时的内存单元,将实参的值传递到这个临时单元去。实参向形参传递是单向的,如果在被调用的过程中改变了形参值,则只是临时单元的值变动,不会影响实参变量本身,当被调
8、过程结束返回主调过程时,VB将释放形参的临时内存单元。例Ex_Max用函数过程编写求a、b两数中最大数。Max函数为求最大数,在cmdStart_Click事件中调用Max函数,程序代码如下:Option ExplicitPrivate Function max(ByVal x As Integer, ByVal y As Integer)Dim z As IntegerIf x y Thenz = xx = yy = zEnd Ifmax = xText4.Text = xText5.Text = yEnd FunctionPrivate Sub Command1_Click()Dim a
9、As Integer, b As Integer, c As Integera = Val(Text1.Text)b = Val(Text2.Text)Text3.Text = max(a, b)Text6.Text = aText7.Text = bEnd Sub当在文本框txtA和txtB中输入变量a为7,b为8时,数据的传递过程如下:通过函数调用,给形参分配:临时内存单元x和y,将实参a和b的数据传递给形参。在被调函数中x、y和z交换数据,调用结束实参单元 a和b仍保留原值,参数的传递是单向的。运行结果界面如图4-4-2所示,被调函数Max中的x和y已经交换过了,分别为8和7,而主调函数
10、中的a和b仍为7和8。图 4-4-22.按地址传递参数在定义过程时,如果没有ByVal 关键字,默认的是按地址传递参数,或者用Byref关键字指定按地址传递。按地址传递参数,是指把形参变量的内存传递给被调用过程,形参和实参具有相同的地址,即:形参、实参共享同一段存储单元。因此,在被调过程中改变形参的值,则相应实参的值也被改变,也就是说,与按值传递参数不同,按地址传递参数可以在被调过程中改变实参的值。将例Ex_Max求两数中最大数的程序按值传递改为按地址传递,程序代码如下:Option ExplicitPrivate Function max(x As Integer, y As Integer
11、)Dim z As IntegerIf x 0multiply = multiply * nn = n - 1LoopEnd FunctionPrivate Sub Form_Click()Dim sum As Integer, i As IntegerFor i = 5 To 1 Step -1sum = sum + multiply(i)NextPrint sum=; sumEnd Sub运行结果:Sum=120120而不是希望的153,本程序只计算了5!= 120。因为,形参n是按地址传递的,在第一次调用Multiply函数后n的值为o,由于实参与形参共享地址单元,实参i的值也是0。当执
12、行“Sum=Sum+Multiply(i)”语句后,Sum的值是120,执行“Next”语句后在判断语句“For i :5 To 1 Step-1时就退出For循环。因此For循环只执行了一次,求了5!的值。解决办法:将函数定义改为按值传递:Private Function Multiply(ByVal n As Integer) As Integer将实参i改为表达式,因为表达式是按值传递的。把变量改为表达式的最简单的方法是用()将变量括起来。调用语句为:Sum=Sum十Multiply(i)三、数组参数在定义过程时,数组可以作为形参出现在过程的形参列表中。声明数组参数的语法如下:语法:形参
13、数组名( )As数据类型形参数组对应的实参必须也是数组,数据类型与形参一致,实参列表中的数组不需要用“()”。过程传递数组只能按地址传递,形参与实参共有同一段内存单元。在被调过程中不能用Dim语句对形参数组声明,否则会产生“重复声明”的编译错误。但是在使用动态数组时,可以用Redim语句改变形参数组的维界,重新定义数组的大小。当返回调用过程时,对应的实参数组的维界也跟随发生变化。例Ex_AverScore用同一个函数Average求正式员工和临时员工的的平均工资。运行结果的界面如图4-4-4所示。图 4-4-4程序代码如下:Option ExplicitPrivate Function ave
14、rage(stuarray() As Single, n As Integer)_ As Single求平均值Dim i As IntegerDim aver As Single, sum As SingleFor i = 1 To n - 1sum = sum + stuarray(i)Nextaver = sum / naverage = averEnd FunctionPrivate Sub cmdstart_Click()Dim salary1(5) As Single, salary2(8) As Singlesalary1(0) = 1900: salary1(1) = 1970:
15、 salary1(2) = 1915 设置初始值salary1(3) = 1600: salary1(4) = 1655salary2(0) = 2675: salary2(1) = 2780: salary2(2) = 2715salary2(3) = 2540: salary2(4) = 2990: salary2(5) = 2770salary2(6) = 2895: salary2(7) = 2765求正式员工工资Text1.Text = Int(average(salary2(), 8) * 100) / 100求临时员工工资Text2.Text = Int(average(sala
16、ry1(), 5) * 100) / 100End Sub程序分析:被调函数Average的数据类型为Single型。为了使同一个函数Average,在调用过程Form_Click事件中将数组的元素个数作为参数传递,然后通过Redim语句重新定义数组的大小,使Average函数具有通用性。因此,对于数组元素个数不定的函数、可以采用将元素个数作为参数传递的方法。程序中的“Int(Average(Salaryl(),5)*100)/100”是为了显示时取两位数。四、对象参数在VB中对象也可以作为形参,即对象可以向过程传递,对象的传递只能是按地址传递。对象作为形参时形参变量的类型声明为“Contro
17、l”,或声明为控件类型,例如,形参类型声明为“Label”或“Form”,则表示可以向过程传递标签控件或窗体。例Ex_FormArgul创建一个人员管理系统。在窗体frmFirst中创建了3个按钮,3个按钮组成按钮数组,不同按钮的Caption属性值不同,单击不同的按钮进入窗体frmSecond。窗体frmFirst和窗体frmSecond中的控件属性如表4-4-1所示。表 4-4-1对象控件名属性名属性值FormfrmFirstCaption人员管理CommandcmdEmpIndex Caption正式员工 cmdEmpIndex Caption退休员工 cmdEmpIndex Capti
18、on临时员工LabellabEmploIndex0 Caption正式在册的员工信息 labEmploIndex1 Caption退休的员工信息 labEmploIndex2 Caption临时的员工信息FormfrmSeconCaption空LabelLabel1Caption空为了使系统简单化,系统设计为在窗体frmFirst中单击不同按钮都打开同一个窗体frmSecond,但frmSecond显示不同的标题和标签内容,窗体frmSecond的标题和标签内容是通过过程参数传递的,如图4-4-5(a)是运行时窗体frmFirst,图4-4-5(b)是当单击按钮“正式员工”cmdEmploye
19、e(0)时的窗体frmSecond的显示情况。(a) (b)图 4-4-5采用将窗体和标签作为参数,通过按钮的不同索引值(index)传递按钮的“caption”属性给形式参数,使单击不同的按钮打开的窗体上显示不同的窗体标题和标签。程序代码如下:Private Sub frmselect(f As Form, cmdcap As String) 传递窗体参数f.Caption = cmdcap & 人员管理End Sub传递窗体参数Private Sub labselect(l As Control, cmdcap As String)l.Caption = 欢迎进入 & Chr(13) &
20、cmdcap & 人员管理l.FontSize = 16l.FontBold = Truel.Visible = Truefrmsecond.Showfrmfirst.HideEnd SubPrivate Sub cmdemployee_click(index As Integer)单击不同按钮将按钮的文本传递给frmsecond窗体标题Call frmselect(frmsecond, cmdemployee(index).Caption)Call labselect(frmsecond.Label1, cmdemployee(index).Caption)frmsecond.Showfrmfirst.HideEnd Sub程序分析:在Sub frmSelect函数中以窗体为形参,定义为“F As Form”;在Sub labSelect函数中以标签为形参,定义为“L As Label”。