《VB函数过程解读课件.ppt》由会员分享,可在线阅读,更多相关《VB函数过程解读课件.ppt(34页珍藏版)》请在三一办公上搜索。
1、第六章 过程(5学时),6.1 函数过程的定义与调用6.2 子过程的定义与调用6.3 参数传递6.4 变量、过程的作用域6.5 递归6.6 常用算法(三)6.7 重点和难点,除了系统提供的内部函数过程和事件过程外,用户可自定义过程: “Sub”保留字开始的为子过程 “Function”保留字开始的为函数过程一、函数过程的定义1. 引例6.1 已知多边形的各条边的长度,要计算多边形的面积。 计算多边形面积,可将多边形分解成若干个三角形。 计算三角形面积的公式如下:,定义函数过程Public Function area(x!, y!, z!) As Single Dim c! c = 1 / 2
2、* (x + y + z) area = Sqr(c * (c - x) * (c - y) * (c - z)End Function,调用函数过程:Sub command1_click() 输入若干个三角形边长 S=area(a,b,c)+area(c,d,e)+area(e,f,g) Print sEnd Sub,2函数过程的定义 自定义函数过程有两种方法: (1)利用“工具”菜单下的“添加过程”命令定义,生成一个函数的框架 (2)利用代码窗口直接定义 函数过程形式: Function 函数过程名(参数列表) As 类型 局部变量或常数定义 语句块 函数名 = 返回值 函数过程体 Exi
3、t Function 语句块 函数名 = 返回值 End Function,函数过程名:命名规则同变量名 参数列表形式: ByVal变量名()As 类型 称为形参或哑元,仅表示参数的个数、类型,无值。 函数名 = 返回值 在函数体内至少对函数名赋值一次 Exit Function :表示退出函数过程,例6.2同标准函数Replace一样,定义MyReplace(S,OldS,NewS)函数过程当调用MyReplace(abcdefgabcdecd,cd,3“) 时函数的返回值为ab3efgab3e3“ Function MyReplace(s$, OldS$, NewS$) As String
4、 Dim i%, lenOldS% lenOldS = Len(OldS) 取OldS字符子串长度 i = InStr(s, OldS) 在字符串中找有否OldS字符子串 Do While i 0 找到用NewS 字符子串替换OldS字符子串 s = Left(s, i - 1) + NewS + Mid(s, i + lenOldS) i = InStr(s, OldS)找下一个OldS字符子串 Loop MyReplace = s替换后的字符串赋值给函数过程名 End Function 假定S为“abcdefgabcdecd”,Oolds为 “cd”,News为 3 (“abcdefgab
5、cdecd”,“cd”,“3”) 第1 次 I=3 结果 “ab3efgabcdecd” (“ab3efgabcdecd”,“cd”,“3”) 第2 次 I=9 结果 “ab3efgab3ecd” (“ab3efgab3ecd”,“cd”,“3”) 第3 次 I=11 结果 ab3efgab3e3,3.函数过程的调用 函数过程的调用同标准函数调用,参与表达式运算,形式如下: 函数过程名(参数列表) 参数列表:称为实参或实元,它必须与形参个数相同,位置与类型一一对应 可以是同类型的常量、变量、表达式 执行流程:Private Sub Command1_Click() Text1 = MyRepl
6、ace(Text1, cd, 3) ST= (“Visual Basic 程序设计教程5.0版” Print MyReplace(ST, 5.0, 6.0)End Sub,Function MyReplace$(s$, OldS$, NewS$) Dim i%, lenOldS% lenOldS = Len(OldS) i = InStr(s, OldS) Do While i 0 s= Left(s, i - 1) + NewS + Mid(s, i + lenOldS) i = InStr(s, OldS) Loop MyReplace = s End Function,二、子过程 函数过
7、程的不足: (1)不是为了获得某个函数值,而是为了某种功能的处理,如例1.1。 (2) 要获得多个结果。 1.引例 编写一个两个数交换的过程供多次调用。 Swap (x,y)子过程的定义 主调程序调用Swap子过程 Public Sub Swap(x, y)Private Sub Form_Click() Dim t Dim a, b t = x a = 10 x = y b = 20 y = t Call Swap (a, b) End Sub Print a=;a,,b=; bEnd Sub,2 子过程定义 Sub 子过程名(参数列表) 局部变量或常数定义 语句 Exit Sub 语句 E
8、nd Sub3 子过程的调用 子过程名 参数列表 或 Call 子过程名(参数列表)4.子过程与函数过程区别:(1)函数过程名有值,有类型,在函数体内至少赋值一次; 子过程名无值,无类型,在子过程体内不能对子过程名赋值;(2)调用时,子过程调用是一句独立的语句。 函数过程不能作为单独的语句加以调用,必须参与表达式运算。(3)一般当过程有一个函数值,使用函数过程较直观; 反之若过程无返回值,或有多个返回值,使用子过程较直观。,例6.4 分别编一计算某级数部分和的子过程和函数过程,并调用。级数为: 精度为:,程序运行流程: Private Sub Command1_Click() Dim f1#,
9、 f2# f1 = jishu1(2#, 0.000001) Call jishu2(f2, 2#, 0.000001) Print f1=; f1, f2 = ; f2 End Sub,Function jishu1(x!, eps#) As Doubl jishu=表达式End Function,找函数名调用jishu1,函数名带了值返回,Sub jishu2(s#, x!, eps#) s=表达式End Sub,找子过程名调用jishu2,三、 参数传递 指主调过程的实参传递给被调过程的形参。 1. 传址与传值 传址:形参得到的是实参的地址,当形参值的改变同时也改变实参的值。 传值: 形
10、参得到的是实参的值,形参值的改变不会影响实参的值。 例6.5 两个变量的交换 Sub Swap1(ByVal x%, ByVal y%) t% = x: x = y: y = t End Sub Private Sub Command1_Click() a% = 10: b% = 20: Swap1 a, b 传值 Print A1=; a, B1=; b a = 10: b = 20: Swap2 a, b 传地址 Print A2=; a, B2=; b End Sub,Sub Swap2(x%, y%) t% = x: x = y: y = tEnd Sub,2. 数组参数的传递 当参数
11、是数组通过传址方式进行传递。注意: 在实参和形参中写数组名,忽略维数的定义,但圆括号不能省。 被调过程可通过Lbound和Ubound函数确定实参数组的下、上界。Lbound和Ubound函数的形式如下:L|Ubound(数组名,维数) 其中:维数指明要测试的是第几维的下标值,缺省是一维数组。例 6.7 编一函数tim,求任意一维数组中各元素之积。 调用tim,求和 Function tim(a() As Integer) Dim t#, i% t = 1 For i = Lbound(a) To Ubound(a)t = t * a(i) Next i tim = tEnd Function
12、,调用:Sub Command1_Click() Dim a%(1 To 5),b%(3 To 8)t1# = tim(a()t2 #= tim(b()Print t1, t2 End Sub,使用过程注意事项:1. 确定自定义的过程是子过程还是函数过程 函数过程名有值,子过程名无值。2过程中形参的个数和传递方式的确定 过程中参数的作用是实现过程与调用者的数据通信。 (1)从主调程序获得初值,值传递。 (2)将结果返回给主调程序,地址传递。3. 实参与形参结合时对应问题 个数、类型、位置、次序一一对应。 形参是值传递,对应实参可以是表达式、常量、数组元素。 形参是地址传递,对应实参只能是简单变
13、量。 数组、记录类型、对象只能是地址传递。,实验6.4回文数的判断中形参的确定 1. 函数过程,形参一个,值传递对所判断的数字;函数名是否为回文数。 Function IsH(ByVal ss As String) As Boolean 2. 子过程,形参两个,值传递对所判断的数字,地址传递是否位回文数。 Sub hui(ByVal ss As String, Tag As Boolean)实验6.2子过程DeleStr(s1,s2)形参的确定 s1,要处理的字符串,从主调程序得初值,删除子串后结果在S1中,所以地址传递。 s2删除的子串,值传递。实验6.3函数过程 MaxLength(s)形
14、参的确定 S要处理的字符串,值传递。 MaxLength函数名,最长的单词长度。,四、 变量、过程的作用域 作用域:变量、过程随所处的位置不同,可被访问的范围。 1.过程的作用域 窗体/模块级:加Private关键字的过程,只能被定义的窗体或模块中的过程调用。 全局级:加Public关键字(缺省)的过程,可供该应用程序的所有 窗体和所有标准模块中的过程调用。,2. 变量的作用域 局部变量:在过程内用声明的变量,只能在本过程中使用。 窗体/模块级变量:在“通用声明”段中用Dim语句或用Private语句声明的变量,可被本窗体/模块的任何过程访问。 全局变量:在 “通用声明”段中用Public语句
15、声明的变量,可被本应用程序的任何过程或函数访问。,例如在下面一个标准模块文件中不同级的变量声明:Public Pa As integer 全局变量Private Mb As string *10 窗体/模块级变量Sub F1( ) Dim Fa As integer 局部变量 End SubSub F2( ) Dim Fb As Single 局部变量End Sub,若在不同级声明相同的变量名,系统按局部、窗体/模块、全局次序访问如: Public Temp As integer 全局变量 Sub Form_Load() Dim Temp As Integer 局部变量 Temp=10 访问局
16、部变量 Form1.Temp=20 访问全局变量必须加窗体名 Print Form1.Temp, Temp 显示 20 10 End Sub,3. 静态变量 局部变量声明: Dim声明,随过程的调用而分配存贮单元,变量的初始化;过程体结束,变量的内容自动消失,存贮单元释放。 Static声明,每次调用过程,变量保持原来的值。 声明形式:Static 变量名 AS 类型 Static Function 函数过程名(参数列表) As 类型 Static Sub 子过程名(参数列表)过程名前加Static,表示该过程内的局部变量都是静态变量。例6.9 Private Sub Form_Click()
17、 Dim i% ,isum% For i = 1 To 5isum = sum(i)Print isum, Next i End Sub,Private Function sum(n As Integer) Dim j As Integer j = j + n sum = jEnd FunctionStatic j As Integer,结果?,1,2,3,4,5,Sub f1(x) x=f2(xx)*3End Sub,Sub Command1_Click() Call f1(y)End Sub,Function f2(x) f2=f3(x)+3End Sub,Function f3(x) f
18、3=x*xEnd Sub,Sub f1(x) Call f1(y)End Sub,过程的直接调用,Sub Command1_Click() Call f1(y)End Sub,过程的递归调用,五、递归,1.递归的概念 用自身的结构来描述自身就称为“递归”。例对阶乘的定义:,2. 递归过程 过程在自身定义的内部调用自己。 例6.10 编fac(n)=n! 的递归函数 Function fac(n As Integer) As Integer If n = 1 Then fac = 1 Elsefac = n * fac(n - 1) End If End Function,Sub Command
19、1_Click() Print “fac(4)=”;fac(4)End Sub结果:fac(4)=24,递推,回归,在递归处理中,用栈来实现。栈中存放形参、局部变量、返回地址。递推过程:每调用自身,当前参数压栈,直到达到递归结束条件。回归过程:不断从栈中弹出当前的参数,直到栈空。递归算法设计简单,但消耗的机时和占据的内存空间比非递归大。思考: 若上述fac函数中: If n = 1 Then fac = 1 即仅有语句: fac = n * fac(n - 1) 或 n=0 程序运行将造成何结果?由此可见构成递归的结构如下: 递归结束条件及结束时的值; 能用递归形式表示,并且递归向终止条件发展
20、。,例6.11利用递归求最大公约数,Public Function gcd(m As Integer, n As Integer) As Integer If (m Mod n) = 0 Then gcd = n Else gcd = gcd(n, m Mod n) End IfEnd FunctionPrivate Sub Form_Click() Print gcd(10, 4)End Sub,分析以下子过程的功能 ,当n=100,r=8,结果是多少? Public Sub f(ByVal n %, ByVal r %) If n r Then Call f(n r, r) Print n
21、 Mod r;End Sub Private Sub Command1_Click() Call f(100, 8) End Sub,显示结果 1 4 4,例6.12 打印分形图,递归常见错误: 1.递归调用出现“栈溢出” 在递归调用时,其中的参数要向终止方向收敛。 如下求阶乘的递归函数过程: Public Function fac(n As Integer) As IntegerIf n = 1 Then fac = 1Else fac = n * fac(n - 1)End IfEnd FunctionPrivate Sub Command1_Click() Print “fac(5)=”
22、;fac(5) Print “fac(5)=”;fac(-5) 栈溢出End Sub,1.数制转换 例6.13 将一个十进制整数m转换成 r (216)进制字符串。 方法:将m不断除 r 取余数,直到商为零,以反序得到结果。,6.6常用算法(三),2.例6.14加密和解密 简单加密的思想是: 将每个字母C加一序数K,式子 c=chr(Asc(c)+k), 例如序数k为5,这时 “A”“F”, “a”“f”,“B”“G” 当加序数后的字母超过“Z”或“z”则 c=hr(Asc(c)+k -26)。 解密为加密的逆过程。,3.查找 (1)顺序查找例6.15。 顺序查找根据查找的关键值与数组中的元素
23、逐一比较.数组可无序。Public Sub Search(a() As Variant, ByVal key As Variant, index%) Dim i% For i = LBound(a) To UBound(a) If key = a(i) Then 找到,元素的下标在index中,结束查找 index = i Exit Sub End If Next i index = -1 找不到, index形参的值为-1End Sub平均查找次数 n/2,Keya(mid) low=mid+1 查找区域缩小一半,继续,直到找到或查找区域中无元素.本例用递归实现6.16 Sub birsea
24、rch(a(), low%, high%, key , index%),(2)二分法查找 要查找的数组必须有序。 思想:要查找的关键值Key同数组的中间mid项元素比较:,444,Key,4.排序 选择、冒泡、插入法排序等。 前两种排序欲排序的数据全部输入后,再进行排序; 插入法排序每输入一项,马上插入到数组应在的位置,数组始终有序。 例6.17 实现的步骤: (1)输入欲排序的数据项x;在数组a中找x应所处的位置j; (2)从数组的最后一个元素开始到下标j依次往后移,使j位置空出; (3)将x放入位置j处,一个数据插入完成; (4)有若干个数重复(1)(3)。,5. 例6.18 高次方程求根
25、 有牛顿迭代法、二分法、弦截法等(1)牛顿迭代法 迭代公式: 思想: 对方程给定一个初值x0作为方程的近似根, 利用迭代公式,求得x1, 当x1为求得的近似根, 否则x1作为x0再迭代。,(2) 二分法求根 思想:已知求根区间a,b有一根,每次把求根区间缩小一半,直到找到解或求根区间足够小。 方法:求a,b的中点c,判断 f(c)=0, c为求得的根,结束; f(a)与f(c)同号,则a,c无根,代替a; 否则c,b无根,c代替b; 使求根区间缩小一半,重复上述步骤,直到区间小于精度。,Public Function halfRoot(ByVal a!, ByVal b!) Dim c! Do
26、 While Abs(b - a) 0.00001 c = (a + b) / 2 If f(c) = 0 Then Exit Do ElseIf f(a) * f(c) 0 Then a = c Else b = c End If Loop halfRoot = cEnd Function,6.例6.19数值积分 有矩形法、梯形法、抛物线法(又称辛卜生法)等。 梯形法积分的思想是: 将积分区间a,bn等分,小区间的长度为, 第i块小矩形的近似面积为: 整个积分的结果为这n块小面积的累加,即 :,Public Function trapez(ByVal a!, ByVal b!, ByVal
27、n%) As Single Dim sum!, h!, x! h = (b - a) / n sum = (f(a) + f(b) / 2 For i = 1 To n - 1 x = a + i * h sum = sum + f(x) Next itrapez = sum * hEnd Function,7.字符串处理例6.20编写一个英文打字训练的程序.要求如下:(1)在标签框内随机产生30个字母的范文;(2)当焦点进入文本框时开始计时,并显示当时时间;(3)在键入文本框按产生的范文输入相应的字母;(4)当键入满了30个字母结束计时,禁止向文本框输入内容 ,键入的字符逐一范文比较,显示打
28、字的速度和正确率。,6.7重点和难点,1. 确定自定义的过程是子过程还是函数过程 函数过程名有值,子过程名无值。 过程有一个返回值,则使用函数过程; 若返回多个值或无返回值,一般使用子过程。2过程中形参的个数和传递方式的确定 过程中参数的作用是实现过程与调用者的数据通信。 (1)从主调程序获得初值,值传递。 (2)将结果返回给主调程序,地址传递。3. 实参与形参结合时对应问题 个数、类型、位置、次序一一对应。 形参是值传递,对应实参可以是表达式、常量、数组元素。 形参是地址传递,对应实参只能是简单变量。 数组、记录类型、对象只能是地址传递。,4. 变量的作用域问题 局部变量、静态变量、全局变量特点、作用 5. 递归调用出现“栈溢出”递归过程中有终止的条件和终止时的值或某种操作; 每递归调用一次,其中的参数要向终止方向收敛。,