400 likes | 528 Views
第七章 过 程. 7.1 函数过程定义与调用 7.2 子过程定义与调用 7.3 过程的嵌套调用 7.4 过程的递归调用 7.5 参数传递 7.6 鼠标和键盘 7.7 过程的作用域 7.8 变量的作用域和生存期 7.9 应用举例 7.10 常用算法 (3). 结构化程序设计原则 — 把问题逐步细化,分成若干个功能模块. 引例 已知多边形各边的长度,求多边形的面积?. area = S1 + S2 + S3. Function area(x!,y!,z!) As Single End Function. Dim c!
E N D
第七章 过 程 • 7.1 函数过程定义与调用 • 7.2 子过程定义与调用 • 7.3 过程的嵌套调用 • 7.4 过程的递归调用 • 7.5 参数传递 • 7.6 鼠标和键盘 • 7.7 过程的作用域 • 7.8 变量的作用域和生存期 • 7.9 应用举例 • 7.10 常用算法(3)
结构化程序设计原则—把问题逐步细化,分成若干个功能模块结构化程序设计原则—把问题逐步细化,分成若干个功能模块 引例 已知多边形各边的长度,求多边形的面积? area = S1 + S2 + S3 Function area(x!,y!,z!) As Single End Function Dim c! c=1/2*(x+y+z) area=sqr(c*(c-x)*(c-y)*(c-z)) … S1=area(a,b,c):S2=area(c,d,e):S3=area(e,f,g)
7.1 Function过程 • Function过程的定义 [Private|Public][Static] Function 函数过程名 ([形参表]) [As 类型] …… 函数过程名=表达式 [Exit Function] …… End Function
[Private|Public][Static] Function 函数过程名 ([形参表]) [As 类型] …… 函数过程名=表达式 [Exit Function] …… End Function 说明 • Private与Public • Static • 函数过程名:命名规则与变量相同 • 形参表(形式参数):由逗号分隔的变量名或数组名()组成 • As 类型:函数返回值的类型 • 函数过程名=表达式 • Exit Function
7.1.2 Function过程的建立 • Function过程可以在标准模块或窗体的通用层中建立。 • 利用“工具”菜单下的“添加过程”命令定义 • 在代码窗口直接定义
7.1.3 Function过程的调用 • 函数过程的调用形式与内部函数一样,即以函数的形式出现在表达式中。 • 变量=函数过程名([实参表]) • 注意 • 实在参数与形式参数 • 参数传递:调用时把实参的值传递给形参的过程,一一对应。
Function函数过程的举例 【例7.1】编写函数过程计算n! 【思路】 • n!的功能要在函数过程中实现 • n!的值随传入的n值的不同而不同(确定形式参数); • 函数的返回值为n!计算结果(确定函数返回值的类型); • 在事件过程中调用该函数实现n!。 输入不同的n值 Function fact(n As Integer) As Long End Function 函数的返回值类型 获得计算值
函数过程名兼作结果变量 必须在函数过程体内至少对函数过程名赋值一次 Function fact(n As Integer) As Long End Function Dim i As Integer, f As Long f = 1 For i = 2 To n f = f * i Next i fact = f Private Sub Command1_Click() Dim n As Integer n = Val(Text1) Label2.Caption = Str(n) Text2.Text = fact(n) End Sub
【例7.2】调用计算n!的函数计算组合数。 【思路】组合数是求如 的数,计算的方法是分别求n! m!,组合数的大小为n!/(m!*(n-m)!)。 Private Sub Command1_Click() Dim m As Integer, n As Integer Dim comb As Single m = Val(Text1) n = Val(Text2) comb = fact(n) / (fact(m) * fact(n - m)) Text3.Text = comb End Sub
7.2 Sub过程 • Sub过程的定义 [Private|Public][Static] Sub 子程序过程名[(形参表)] …… [Exit Sub] …… End Sub
7.2.2 Sub过程的调用 • Sub过程的调用由专门的语句完成 • Call 子过程名 [(实在参数)] • 子过程名 [(实在参数)] Call test(n, 10) test n, 10
Sub过程的举例 【例7.3】计算一元二次方程的两个实根 【思路】一元二次方程的一般式为 它的两个根可以由 Sub quad( ) End Sub a!, b!, c! , x1!, x2! x1 = (-b + Sqr(b * b - 4 * a * c)) / (2 * a) x2 = (-b - Sqr(b * b - 4 * a * c)) / (2 * a) Sub Command1_Click() Call quad(a, b, c, x1, x2) root1 = x1: root2 = x2 End Sub
【例7-4】 7.3 过程的嵌套调用 【思路】利用过程嵌套调用 Private Function fact(n As Integer) Dim i As Integer, f f = 1 For i = 2 To n f = f * i Next i fact = f End Function Private Function comb(n As Integer, m As Integer) comb = fact(n) / (fact(m) * fact(n - m)) End Function Private Sub Command1_Click() Dim m As Integer, n As Integer m = Val(Text1) n = Val(Text2) Text3.Text = comb(n, m) End Sub
7.4 过程的递归调用 • 用自身的结构来描述本身就称为“递归” n! = n (n-1)! (n-1)! = (n-1) (n-1-1)! • VB允许一个自定义子过程或函数过程在过程体的内部调用自己,这样的子过程或函数称为递归子过程或递归函数
1 n=1 fact(n)= nfac(n-1) n>1 求n!的函数 n!=n*(n-1)! (n-1)!=(n-1)*(n-2)! …… Public Function fact(n) As Long If n = 1 Then fact = 1 Else fact = n * fact(n-1) End if End Function 2!=2*1! 1!=1
本程序,运行的结果是______,函数的功能是_______本程序,运行的结果是______,函数的功能是_______ Sub Command1_Click() Print f(100,8) End Sub n=12,r=8 n=1,r=8 n=0,r=8 n=100,r=8 Function f(n,r) If n<>0 then f = f(n\r,r) print n Mod r; End if End Function Function f (n,r) If n<>0 then f = f(n\r,r) print n Mod r; End if End Function Function f (n,r) If n<>0 then f = f(n\r,r) print n Mod r; End if End Function Function f (n,r) If n<>0 then f = f(n\r,r) print n Mod r; End if End Function
有递归结束条件或结束时的值 • 能用递归形式表示,并且递归向结束条件发展 [例7-7] 编写程序,输出菲博拉西数列 Private Function fibo(n) If n = 1 Or n = 2 Then fibo = 1 Else fibo = fibo(n - 1) + fibo(n - 2) End If End Function ‘递归结束条件时的值 ‘有递归趋势
7.5 参数传递 • 传地址[ByRef] • 当调用一个过程时,它将实参的地址传给形参。是默认的参数传递方法 • 传值ByVal • 当调用一个过程时,系统将实参的值复制给形参,实参与形参断开了联系
d d 4 4 e 传值 a = 1: b = 2: c = 3: d = 4 Call test1(a, b, c, d) Print a; b; c; d … Private Sub test1(b%, c%, d%, e%) e=b+c+d End Sub 6 ‘ 1 2 3 6 传地址 e 4 6 a = 1: b = 2: c = 3: d = 4 Call test2(a, b, c, d) Print a; b; c; d … Private Sub test2( b%, c%, d%, ByVal e%) e=b+c+d End Sub ‘ 1 2 3 4 [例7-9]
数组参数的传递 [7-12] • 只能通过传址方式传递 • 忽略维数定义 • 用Lbound和Ubound函数确定参数组的上下界 Private Sub Command1_Click() Dim a%(1 To 10) …… Call change(a()) …… End Sub Private Sub change(a() As Integer) …… End Sub
7.6 鼠标和键盘7.6.1 鼠标 • 鼠标事件 • MouseDown:当按下鼠标的任意一个键时被触发 • MouseUp:当鼠标的任意一个键释放时被触发 • MouseMove:当鼠标指针移动时被触发
Sub Form_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As Single)
7.6.2 键盘 • 键盘事件 • KeyPress:用户按下并释放一个ASCII码时被触发 • KeyUp:用户释放任意一个键时被触发 • KeyDown:用户按下任意一个键时被触发
Sub Form_KeyPress(KeyAscii As Integer) …… End Sub Sub Form_KeyUp(KeyCodeAsInteger,Shift As Integer) …… End Sub
7.7 过程的作用域 • 窗体/模块级 Private • 全局级 Public 应用程序 .vbp文件 窗体模块 .frm文件 标准模块 .bas文件 事件过程(Sub) 子过程(Sub) 函数过程(Function) 子过程(Sub) 函数过程(Function)
[例7-18]本例示意性说明全局级过程的调用 在Form1窗体中建立mianji函数过程 Public Function mianji(r As Single) mianji = 3.14 * r * r End Function 在标准模块中建立zhouchang函数过程 Public Function zhouchang(r As Single) zhouchang = 2 * 3.14 * r End Function 在Form2窗体中调用上面两个函数过程 Text2 = Form1.mianji(r) Text3 = zhouchang(r)
7.8 变量的作用域和生存期 将变量声明为静态变量,在程序运行中可保留变量的值
例:一个窗体文件中不同级的变量声明 Public Pa As integer ' 全局变量 Private Mb As string *10 '窗体/模块级变量 DimPa As integer Sub F1( ) Dim Fa As integer ' 局部变量 … End Sub Sub F2( ) Static Fb As Single ‘ 静态变量 … End Sub
[测试题] 下列程序的输出结果是( ) Dim a As Integer Private Sub Form_Click () dim b,c a=1 b=2 c=3 For i = 1 to 3 Call test Next i Print a, b, c End Sub Sub test() dim c Static b a = a+1 b = b+1 c = c+1 print a, b, c End Sub
7.9 应用举例[例7-21] • 程序中的p、x、a数组必须在通用位置定义吗? • sp这个变量的作用是? • mean()这个自定义过程的作用是什么? • 在按钮单击事件中完成了什么功能?
Private Sub gdbh(n, f) f = 0 If n = 2 Then f = 0 For i = 2 To Sqr(n) If n Mod i = 0 Then f = 1 Next i End Sub Private Sub Command1_Click() Dim m, m1, m2, n, f, p For m = 6 To 100 Step 2 p = " " m1 = 1 aa: m1 = m1 + 1 Call gdbh(m1, f) If f = 1 Then GoTo aa Call gdbh(m-m1, f) If f = 1 Then GoTo aa p = p & m & "=" & m1 & "+" & m2 List1.AddItem p Next m End Sub
7.10 常用算法(3)1.数组中元素的插入操作 • 条件:操作的是有序数组,插入后该数组仍然有序 • 实现方法如下: Dim a%(1 To 10) k [注意]要执行插入操作的数组在声明的时候要注意数组大小的合法性
查找x的插入位置 将大于x的数据依次 往后移动一个位置 Dim a(10) As Integer For i = 1 To 9 a(i) = Val(InputBox("输入数据")) Text1 = Text1 & a(i) & " " Next i x = Val(InputBox("输入要插入的数")) For k = 1 To 9 If x < a(k) Then Exit For Next k For i = 9 To k Step -1 a(i + 1) = a(i) Next i a(k) = x For i = 1 To 9 Text2 = Text2 & a(i) & " " Next i
• 2.有序数列的删除 • 条件:操作的是有序数组,删除后该数组仍然有序 • 实现方法如下: Dim a%() ReDim a(1 To 9) k
查找到预删除数据的位置k 从k+1到10位置上的数据向前移动 Dim a(10) As Integer For i = 1 To 10 a(i) = Val(InputBox("输入数据")) Text1 = Text1 & a(i) & " " Next i x = Val(InputBox("输入要删除的数")) For k = 1 To 10 If x = a(k) Then Exit For Next k For i = k To 9 a(i) = a(i + 1) Next i For i = 1 To 9 Text2 = Text2 & a(i) & " " Next i
习 题 7 7-1编写程序,利用Sub过程计算下式的值: s=a!+b!+c! a,b,c的值由键盘输入 7-2编写程序,打印100~200之间的所有素数。 要求: (1) 每行输出5个素数。 (2) 利用Function过程判断每个数是否为素数,是返回1,否则返回0。 7-3编写两个Function过程,分别计算40,16,34,26,52的最大公约数和最小公倍数。