【VB开源代码栏目提醒】:网学会员鉴于大家对VB开源代码十分关注,论文会员在此为大家搜集整理了“第八章 VB自定义函数与子过程 PDF - 综合课件”一文,供大家参考学习
一、
VB程序的基本构成是过程。
二、
VB6.0中过程有两大类内部过程和外部过程。
1、内部过程系统提供的不需要用户编写如内部函数。
2、外部过程用户根据需要定义的供调用的程序段外部过程分为子过程、函数过程。
三、在
VB中使用过程编程有两个优点 1、过程可使程序划分成离散的逻辑单元每个单元都比没有使用过程的整个程序容易调试。
2、一个程序中的过程往往不必修改或只需稍作改动便可以成为另一个程序的构件。
四、Visual Basic 的两类过程 1、Sub 过程子过程不返回值或多个返回值。
2、Function 过程函数过程有一个返回值。
例8.1 设计程序将50100区间内的偶数拆成两个素数之和 分析可先将偶数拆分成两个数之和在分别对这两个数进行素数判定若都是素数就输出。
例如可将50拆分为:347、446、….. 473然后对每种组合中的两个数分别进行素数判断。
因此可以定义一个专门用于素数判断的函数过程。
Private Function primeByVal x As Integer As Boolean Dim I prime True 函数赋初值True For I 2 To Sqrx If x Mod I 0 Then 判断x是否可被i整除 prime False 函数取值False则x不是素数 Exit Function 函数结束 End If Next I End Function ??在事件过程中调用以上定义的函数得到结果。
Private Sub Form_Click Dim I N K I 1 计数 For N 50 To 100 Step 2 取偶数 For K 3 To N / 2 第一个数的取值区间折半 If primeK And primeN - K Then ??二次调用结果都是素数输出 Print I : N K N - K Exit For 退出k循环 End If Next K I I 1 Next N End Sub 8.2.2 函数过程的定义 函数过程在被调用前一定要先定义函数定义的方式一般有两种 1利用“添加过程”对话框定义 打开窗体或模块的
代码窗口单击“工具”菜单选择“添加过程”命令即可打开“添加过程”对话框。
在“添加过程”对话框中输入并选择相应的内容和项目即可。
在“名称”文本框内输入待定义函数过程的名称在“类型”选项组中选择“函数”单选按钮。
单击确定按钮则可建立一个函数过程的框架 。
2直接在
代码窗口定义 进入
代码窗口后在左侧显示对象名的下拉列表框中选择“通用”在右侧显示过程的下拉列表框中选择“声明”然后输入Function及函数名即可。
自定义函数过程的格式如下 Public PrivateStaticFunctionAs 函数名 Exit Function 函数名 End Function 1Public或Private表示函数是“公有的”或“私有的”。
Public表示该函数为公有过程定义后整个程序范围内均可调用该函数但调用时必须加上该函数所在的窗体或标准模块作为前辍而Private表示私有子过程用它定义的函数只能在本窗体或模块中被调用。
缺省默认是公有的。
2Static表示函数中的局部变量是静态变量在函数被调用后其值仍然被保留 3该项中的参数为形式参数又称哑元可以是变量名或数组名当参数为数组名时形参和实参在参数声明时应省略其维数但括号丌能省略。
当参数有多项时参数间要用逗号分隔开。
使用格式为ByValByRefAs 4ByVal表示调用时参数为值传递方式实参的值丌随形参值的变化而变化 5ByRef参数默认选项表示参数为地址传递方式实参的值随形参值的改变而改变数组只能以传地址的方式引用 6 As 表示函数返回值的类型默认为变体型。
在函数体内至少应对对函数名赋值一次。
7 函数名用于函数运行后返回一个值。
如在定义中未对函数名赋值则将返回一个默认值。
其中数值型为0字符型为“”变量型为Empty。
8 Exit Function用于退出函数过程该项一般嵌套在if结构中使用在满足if条件时退出该函数过程。
例8.2
设计一个程序统计字符串中西文字符个数。
算法汉字的Asc函数的返回值小于0西文字符的Asc函数的返回值大于0。
Function CountXwByVal S Dim I T K C For I 1 To LenS C MidS I 1 逐个地取出字符 If AscC 0 Then K K 1 字符ASCII码大于0则个数累加1 Next I CountXw K 返回函数值 End Function 例8.2 设计一个程序统计字符串中西文字符个数。
Private Sub Command1_Click Dim C1 C1 CountXwText1.Text ?? 调用CountXw函数 Picture1.Print Text1 在Picture1中显示统计的结果 Picture1.Print 有 C1 个西文字符数 End Sub 8.2.3 函数过程的调用 1函数调用的形式 其调用形式如下 变量函数过程名实参列表 其中实参
列表中的实参是传递给被调用过程的变量或表达式。
例题8.2中的C1 CountXwText1.Text 就是一次函数调用。
调用函数后函数过程名将有一个返回值函数是一个特殊的表达式。
因此函数不能作为单独的一条语句而必须要以给变量赋值或与命令一起使用的形式。
例如 If primeK And primeN - K Then 8.2 自定义函数过程 2函数过程调用的执行流程 在事件过程调用一个函数过程时程序在执行这两个过程时的流程如下图所示。
Function Hypotenuse xy Hypotenuse Sqr x 2 y 2 End Function Private Sub Command1_Click …… s Hypotenuseab …… End Sub ① ② ③ ④ ⑤ 函数过程调用的执行流程图函数过程调用的执行流程图 过程调用时执行顺序如下 1事件过程Command1_Click在执行到函数过程调用语句“s Hypotenuseab”时
程序执行控制权转移到Hypotenuse函数过程中 2执行控制权转移时实参a和b的值将分别传递给Hypotenuse函数中的形参x和y ① ② ③ ④ ⑤ 3x和y获得初值后即可执行函数过程中的程序
代码并给函数过程名赋值该值即为整个函数过程的返回值 4函数执行结束后函数的返回值将赋给主调事件过程的变量s 5变量s得到赋值后接着执行调用函数过程后面的剩余语句。
① ② ③ ④ ⑤ 引例 调用函数后将得到函数的返回值但是在有些问题的中过程执行结束后不需要返回值用函数过程实现就会非常困难而应该使用子过程的形式。
例8.3 试编写一个将两个数进行交换的过程供其它过程多次调用。
分析先编写一个具有将两个数进行交换的子过程需要进行两数交换时调用该子过程同时将待交换的两个数传送到该子过程中在子过程实现两数交换。
子过程执行结束后将被交换后的两个数返回到主调过程中。
??Cp子过程的定义 Private Sub CpA As Integer B As Integer 形参为传址方式 If A 0 Then Exit Sub End If A A B A和B的值交换带回主调过程 B A - B A A - B Print 在子过程中交换后的值 Print A A B B End Sub ??主调程序Cp子过程 Private Sub Command1_Click Dim Str1 Va
Vb Str1 输入对话框 Va InputBoxVa Str1
Vb InputBoxVb Str1 Print 在主调过程中调用子过程前的值 Print Va Va
Vb Vb 输出原始值 Call CpVa
Vb Print 在主调过程中调用子过程后的值 输出经子过程处理过后的返回值 Print Va Va
Vb Vb End Sub 程序运行后单击窗体以触发Form_Click事件过程运行结果如下图所示。
从程序中可以看到Va和
Vb的初值分别是45和23而在窗体中输出时Va和
Vb的值分别是23和45达到了两个数交换的目的。
8.3 子过程的定义和调用 8.3.1 子过程的定义 子过程以过程名来标识被其它过程调用。
子过程与事件过程有一定区别事件过程可以在该事件触发或调用时执行而用户自定义的子过程只有在被其它过程调用时才能执行。
子过程的定义跟函数过程的定义相类似在
代码窗口中输入Sub及子过程名即可
系统会自动加上End Sub与子过程名后的一对括号然后即可在子过程的框架中输入程序
代码。
子过程的定义格式 PrivatePublicStatic Sub Exit Sub End Sub ——————————— 说明 PublicPrivate与Static它们的含义和作用与函数过程中相应的这些关键词相同。
该项中参数的形式和调用方法也与函数过程相同。
Exit Sub退出过程该项一般嵌套在if结构中使用在满足if条件时退出该过程。
例分别计算两个数的和不差而当两个数的值均为0时则丌进行任何计算。
Sub Operationx As Integer y As Integer Dim t1 as Integer t2 as Integer If x 0 and y0 Then Exit Sub End If t1xy t2x-y Print “t1”t1 “t2”t2 End Sub 在Sub 过程不Function 过程之间的区别 1子过程名无类型说明在子过程中不能对子过程名进行赋值。
2 子过程的形式参数没有具体的值只代表参数的个数、位置、类型。
3子过程的调用必须是一条独立的语句。
8.3.2 子过程的调用 1使用Call语句调用 格式Call 子过程名实参列表 说明 ① 实参的个数数据类型都应与被调用过程的形参一一对应。
用Call语句调用时若有实参括号丌能省略否则可以省略括号。
② 若子过程要通过实参向主调过程中返回值则实参只能是简单变量、数组名或自定义类型变量。
例如 Private Sub Command1_Click a”Visual Basic” b “6.0” Call Linkab End Sub 此时将输入的值a和b作为实参调用Link子过程通过调用将两个实参传递给形参然后在过程中计算。
2直接使用过程名调用 格式子过程名 实参列表 说明此形式调用子过程时实参丌用加括号否则在有的编译版本中出现编译错误若有多个实参则实参之间用逗号分隔。
例如 Private Sub Command1_Click a”Visual Basic” b “6.0” Link a b End Sub 8.4.1 形参与实参 1、形参 指出现在Sub 和Function过程形参表中的变量名、数组名该过程在被调用前没有为它们分配内存其作用是说明自变量的类型和形态以及在过程中的作用。
形参可以是除定长字符串变量之外的合法变量名也可以带括号的数组名。
2、实参 实参就是在调用Sub 和Function过程时从主调过程传递给被调用过程的参数值。
实参可以是变量名、数组名、常数或表达式。
在过程调用传递参数时形参与实参是按位置结合的形参表和实参表中对应的变量名可以不必相同但它们的数据类型、参数个数及位置必须一一对应。
3、形参与实参的关系 形参如同公式中的符号实参就是符号具体的值在调用过程前必须得到赋值调用过程就是实现形参与实参的结合把实参的值通过调用传递给形参相当于把值代入公式进行计算。
8.4.2 地址传递与值传递 在Visual Basic中实参与形参的结合有两种方式即地址传递ByRef与值传递ByVal地址传递又称为引用。
10 10 20 a的地址 地址传递地址传递 值传递值传递 实参实参bb 形参形参yy 实参实参 aa 形参形参 xx 1地址传递 在
VB6.0中在形参前加ByRef或在缺省该关键字则实参与形参的结合就是地址传递方式。
例8.5通过调用子过程实现将两个字符串进行互换。
分析首先定义一个能够实现字符串交换的子过程Swap1该子过程包含两个形参。
在主调过程中分别对两个字符变量A和B进行赋值将这两个变量作为调用子过程Swap1的实参要使得形参的改变能够影响实参的值应该采用地址传递的方式。
程序
代码如下 ‘传址子过程Swap1 Public Sub Swap1X As String Y As String Dim T As String T X ‘下面三行语句用于交换形参的值 X Y Y T Print “传址子过程中互换变量值后” “X1” X “ ” “Y1” Y Print “_____________________________________________ Print End Sub ‘以下为主调过程事件过程 Private Sub Form_Click Dim A As String B As String ‘定义字符串变量A、B Cls ‘清除窗体文字 A ABCDE ‘为变量A赋值 B 12345 ‘为变量B赋值 Print 主过程在调用子过程之前 A1 A B1 B Print _____________________________________________ Print Swap1 A B ‘调用子过程Sub1 Print 主过程调用传址子过程之后 A1 A B1 B End Sub 程序运行结果如下图 从程序的运行结果可以看出对形参的改变就是对实参的改变。
如果丌希望这种改变则在被调用过程中丌要出现对形参值改变的语句或使用按值传送方式传递数据将丌会引起实参值的改变。
2值传递 传值就是通过传送实参的值而不是传送地址的方法给被调用过程中传递数据。
这样被调用的过程并没有访问实参的地址因而也不会改变实参的值。
格式 Private Sub JcByVal a …… End Sub 例8.6将两个字符串在子过程中实现互换但主调过程的字符串不互换。
分析首先定义一个能够实现字符串交换的子过程Swap1该子过程包含两个形参。
在主调过程中分别对两个字符变量A和B进行赋值将这两个变量作为调用子过程Swap1的实参要使得子过程中形参的值进行互换而不影响主调过程的实参应该采用值传递的方式。
代码如下 ‘传值子过程Swap1 Public Sub Swap1ByVal X As String ByVal Y As String Dim T As String T X X Y Y T Print 传值子过程中互换变量值后的变量数据 X1 X Y1 Y End Sub ‘以下为主调过程事件过程 Private Sub Form_Click Dim A As String B As String Cls 清除窗体文字 A ABCDE B 12345 Print 主过程在调用子过程之前的原变量数据 A1 A B1 B Print _________________________________________________ Swap1 A B Print 主过程调用传值子过程之后的变量数据 A1 A B1 B End Sub 运行结果如下图所示。
从程序的运行结果可以看出使用按值传送方式传递数据将不会引起实参值的改变。
也就是说两个形参的值虽然进行了互换但没有影响实参的值实参的值在调用子过程后仍然保留了初值。
8.4.3 数组参数的传递 在
VB6.0中允许使用数组作为实参传递到子过程的形参中数组传递必须采用地址传递的方式来传递参数数组参数在传递时应注意以下两个
问题 ① 在实参和形参列表中只写数组名忽略维数的定义但圆括号丌能省当数组作为参数传递时系统将实参数组的起始地址传给过程使形参数组也具有与实参数组相同的起始地址若参数是多维数组每维以逗号分隔 ② 被调过程可分别通过Lbound和Ubound函数确定实参数组的下界和上界。
例8.6 在主调过程定义一个44的二维数组在子过程中将数组对角线上的元素均加上常数15. ‘函数过程 Private Sub ArrayAdd A 数组作为形参只有传址方式 Dim I J For I 0 To 3 For J 0 To 3 If I J Then AI J AI J 15 主对角上元素加15 Next J Next I End Sub Private Sub Command1_Click Dim C3 3 I J I1 J1 Print 调用前 For I 0 To 3 For J 0 To 3 CI J IntRnd 101 : Print TabJ 5 1 CI J Next J Print Next I Call ArrayAddC For I1 0 To 3 返回后C数组发生改变 For J1 0 To 3 Print TabJ1 5 1 CI1 J1 Next J1 Print Next I1 End Sub 程序运行后如下图所示。
此时采用传址方式实现数组的整体赋值。