§3.7  过程
所谓过程,就是在程序中可以被调用的一段子程序。VB中的过程分为两类,第一类是系统提供的函数过程和事件过程,另一类是用户自定义的过程。自定义过程又分为:
1子过程:  以Sub保留字开始;
2函数过程:以Function保留字开始;
3属性过程:以Property保留字开始;
4事件过程:以Event保留字开始。
其中用户经常定义的是子过程和函数过程。
教学目标
使学习者能够编写有参和无参过程和自定义函数,来实现应用程序中的各种功能。
教学要求
了解:过程的概念、递归的概念
理解:函数和过程的区别、参数的传递方式;参数传递中传值和传地址的区别。
理解:过程和变量的作用域。
掌握:过程的定义及调用。
本节重点
  过程定义及调用的方法。
  过程和变量的作用域
本节难点
  过程参数的传递。
  过程的递归调用
本节应注意的问题
过程和自定义函数的区别、传址与传值的区别。
一、过程的定义
子过程和函数过程都是为完成某种特定功能而由用户编写的一组程序代码,不同之处是函数过程是带有返回值的特殊过程。定义子过程和函数过程有以下两种方法:
1、在模块中定义过程
在模块中定义过程的步骤如下:
(1)先打开要编写过程的窗体或模块的代码窗口;
(2)选择“工具”菜单中的“添加过程”;
(3)在“名称”框中填写过程名(不允许有空格);
(4)在“类型”选项组中决定所添加的是“子程序”还是“函数”过程;
(5)在“范围”选项组中决定过程被调用的范围。“范围”选项组中只有“公有的”和“私有的”两项,
其中“公有的”表示公共级的全局过程;“私有的”表示标准模块级或窗体级的局部过程。
2、在代码窗口中定义过程
在窗体或标准模块的代码窗口中定义过程是常用的过程定义方法,用户可通过用键盘输入程序语言直接定义过程或函数。
(1)自定义过程的形式如下:
[Static][Public][Private] Sub  <子过程名>[(参数列表)]
局部变量或常量定义
<语句组>
[Exit Sub]
<语句组>
End Sub
(2)自定义函数的形式如下:
[Static][Public][Private] Function  <函数名>([参数列表] )[As 类型]
局部变量或常量定义
<语句组>
<函数名>=返回值
End Function
自定义函数中有关内容的说明:
1自定义函数中可以插入Exit Function语句终止函数的运行,但终止函数运行前仍需写入“<函数名>=返回值”语句,以保证函数有返回值。
2Static、Public、Private分别表示静态、全局和局部量。
3函数定义中的“As 类型”表示该函数返回的类型,若缺省说明,则返回变体类型值。
4参数列表的形式为:
[By Val]<变量名>[()][As 类型] [,By Val]<变量名>[()][As 类型……]
    注:By Val表示值传递,否则为地址传递。
二、过程的调用
1、子过程的调用
语句格式:
[Call]  <子过程名>[(参数列表)]
注:其中Call命令可省略,省略Call命令时也必须省略“参数列表”的圆括号。
例:在窗体中定义一个命令按钮Command1,当用户单击命令按钮时,计算:3!+5!+7!,其中计算一个数阶乘的算法编写成子过程,并在事件过程中调用。
1首先编写计算一个数阶乘的子过程
Private Sub jc(ByVal j As Integer, ss)
  Dim i As Integer
  ss = 1
  For i = 1 To j
    ss = ss * i
  Next
End Sub
2编写命令按钮的事件驱动过程
Private Sub Command1_Click()
  Dim jj, x As Long
  Dim i, j As Integer
  ' 调用子过程求3的阶乘调用子程序的例子
  i = 3
  Call jc(i, ss)       
  x = x + ss
  ' 调用子过程求5的阶乘,在调用子过程时省略Call命令
  i = 5
  jc i, ss             
  x = x + ss
  ' 调用子过程求7的阶乘
  i = 7
  Call jc(i, ss)       
  x = x + ss
  print “3!+5!+7!=”;x
End Sub
2、函数过程的调用
由于函数过程可由函数名返回一个值,因此函数过程不能作为单独的语句加以调用,被调用的函数必须作为表达式的一部分,其调用方法与调用VB系统内部函数的方法相同。
例:将计算3!+5!+7! 的阶乘再用函数过程编程计算。
1首先编写计算一个数阶乘的函数过程
Private Function jc(ByVal i) As Long
  Dim j As Integer, k As Long
  k = 1
  For j = 1 To i
    k = k * j
  Next
  jc = k
End Function
2编写命令按钮的事件驱动过程
Private Sub Command1_Click()
  Dim i As Integer, m As Long
  x = jc(3) + jc(5) + jc(7)
  print “3!+5!+7!=”;x
End Sub
注意:
(1)子过程和函数中定义的参数称为“形参”;调用子过程和函数时定义的参数称为“实参”,形参与实参在个数、类型和位置必须相一致并一一对应;
(2)调用子程序或函数时系统将实参的值传递给形参。若形参用ByVal定义,则调用时,实参的值不会随形参值的变化而改变;
(3)当参数为数组时,形参与实参声明时应省略其维数,但括号不可省略;
(4)调用子过程使用Call时,其实参必须用圆括号括起来。
三、过程参数传递
1、参数的传递方式
在调用过程时,主调过程与被调用过程或函数之间可能会有数据的传递,此种数据的传递称为过程参数传递。过程参数传递的方式有两种:传址和传值。
1 传址
传址的过程是:当主调程序调用过程时,将主调程序中的实参的地址传递给被调过程中的形参,因此实参的值会随形参值的变化而改变。传址又称为引用,是系统默认的方法。使用传址方式时,实参不允许是表达式或常数。
2 传值
传值的过程是:当主调程序调用过程时,将主调程序中的实参值复制给被调过程中的形参,因此被调过程对形参的值任何改变都不会影响到实参的值。使用传值方式时,必须在被调过程的形参定义时前面加“ByVal”关键字。
2、数组参数的传递
在VB中,允许参数是数组,数组通过传址方式进行数据传递。
四、变量、过程的作用域
在VB的应用程序中,任何一个变量或过程都会随所处位置及定义方式的不同,造成可被访问范围的不同。变量和过程可被访问的范围称为变量和过程的作用域。
1、过程的作用域
(1)局部过程(窗体/模块级)
局部过程主要是指在某窗体(也可以在标准模块)内用Private定义的过程,这种过程只能被本窗体(或本标准模块)中的过程调用。
(2)全局过程
全局过程主要是指在标准模块(也可以在窗体)内用Public定义(也可缺省定义)的过程,全局过程可供该应用程序的所有窗体和所有标准模块中的过程调用。在标准模块定义的过程,外部过程均可随时调用。在窗体中定义的全局过程,外部过程要调用时,必须在过程名前加该过程所处的窗体名,如:Form1.summ,其中Form1表示窗体名,summ表示过程名。
有关规则如下表所示:
作用范围
模块级
全局级
窗体
标准模块
窗体
标准模块
定义方式
过程名前加Private
过程名前加Public或缺省
能否被本模块其它过程调用
能否被本应用程序其它模块调用
不能
不能
能,但必须在过程名前加窗体名
能,但过程名必须唯一,否则要加标准模块名
2、变量的作用域
每一名程序设计人员必须熟悉和正确掌握应用程序中变量的作用域,否则所编程序在运行时会产生各种错误,使应用程序不能正确完成程序员所期望的各种功能。
(1)局部变量
局部变量是指在某一过程内用Dim或Static语句声明的变量,以及不加声明直接使用的变量。局部变量只能在本过程中使用,一旦本过程执行完毕,变量中存储的内容会自动消失,因此其它过程不可访问局部变量。在不同的过程中,允许有同名的局部变量,这些同名变量之间彼此互不相干。
(2)窗体或模块级变量
窗体或模块级变量指在窗体或模块的“通用声明”段中,用Dim或Private语句声明的变量。此类变量可在本窗体或模块的任何过程中使用。
(3)全局变量
全局变量只能在标准模块的“通用声明”段中,用Public语句声明的变量。全局变量可被应用程序的任何过程或函数访问,全局变量的值在整个应用程序中始终不会消失和重新初始化,只有当整个应用程序执行结束时,才会消失。
五、递归
1、递归的概念
在一个过程或函数中调用自身,称为“递归”。 递归算法可以使编程得到很大的简化,但消耗的机时和占据的内存空间较大。设计一个递归的子过程或函数必须其本身具备递归的条件,而且具备递归结束的条件。递归最典型的一个例子就是求阶乘,由于n!=n*(n-1)!,用阶乘本身来定义阶乘,这样的定义就称为“递归定义”。
2、递归子过程应用举例
汉诺塔问题:十九世纪末,欧洲出现了一种称为汉诺塔的游戏,游戏的规则是在一块铜板上有三根金钢针(编号依次是1,2,3),1号针上放着从大到小的64个盘子,然后要将这64个盘子从1号针移动到3号针上,以2号针作为中间过渡。游戏规定:每次只能移动一个盘子,
并且大盘子不能压在小盘子上面。
                  1                    2                      3
图3.2
通过计算,对于64个盘子的汉诺塔游戏至少需要移动1.8×1019次,若每秒移动一次则需要约一万亿年才能完成,因此我们在编制汉诺塔游戏程序时,应定义游戏中盘子的个数不大于10。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。