变量的作用域决定了哪些子过程和函数过程可访问该变量。变量的作用域分为:局部变量、窗体/模块级变量和全局变量。有关规则如表5-2所示。
表5-2 变量的作用域
|
作用范围 |
局部变量 |
窗体/模块级变量 |
全局变量 | ||
|
窗体 |
标准模块 | ||||
|
声明方式 |
Dim 、Static |
Dim 、Private |
Public | ||
|
声明位置 |
在过程中 |
窗体/模块的 “通用声明”段 |
窗体/模块的“通用声明”段 | ||
|
能否被本模块的 其他过程存取 |
不能 |
能 |
能 | ||
|
能否被其他模块 存取 |
不能 |
不能 |
能,但在变量名前加窗体名 |
能 | |
1.局部变量
在过程内用Dim声明的变量(或不加声明直接使用的变量),只能在本过程中使用,别的过程不可访问。局部变量随过程的调用而分配存储单元,并进行变量的初始化,在此过程体内进行数据的存取。但是,一旦该过程体结束,变量的内容就会自动消失,并释放所占用的存储单元。不同的过程中可有相同名称的变量,彼此互不相干。使用局部变量有利于程序的调试。
2.窗体/模块级变量
在一个窗体/模块的任何过程之外,即在“通用声明”段中用Dim或Private语句声明的变量,可被本窗体/模块的任何过程访问。
3.全局变量
在一个窗体/模块的任何过程之外,即在“通用声明”段中用Public语句声明的变量,可被应用程序的任何过程或函数访问。全局变量的值在整个应用程序中始终不会消失和重新初始化,只有当整个应用程序执行结束时,才会消失。
例5-6 在下面一个标准模块进行不同级的变量声明。
Public a As integer ' 全局变量
Private b As string *8 ' 窗体/模块级变量
Sub F1 ( )
Dim x1 As integer ' 局部变量
…
End Sub
Sub F2 ( )
Dim x2 As Single ' 局部变量
…
End Sub
当同一模块中定义了不同级而相同名的变量时,系统优先访问作用域小的变量名。如:
Public Temp As integer ' 全局变量
Sub Form_Load()
Dim Temp As Integer ' 局部变量
Temp=10 ' 访问局部变量
Form1.Temp=20 ' 访问全局变量必须加窗体名
Print Form1.Temp, Temp ' 显示 20 10
End Sub
系统优先访问了局部变量Temp,若想访问局部变量,则必须在全局变量名Temp前加窗体/模块名。
从表5-2可知,局部变量除了用Dim语句声明外,还可用Static语句将变量声明为静态变量,它在程序运行过程中可保留变量的值。也即每次调用过程时,用Static说明的变量保持原来的值。而用Dim说明的变量,每次调用过程时,重新初始化。
声明形式:
Static 变量名 [As 类型]
Static Function 函数过程名([参数列表]) [As 类型]
Static Sub 子过程名[(参数列表)]
若子过程名、函数过程名前加Static,表示该过程、函数内的局部变量都是静态变量。
例5-7 动态变量与静态变量的使用示例。
Private Sub Form_ Click()
Dim i As Integer
For i=1 to 5
Dands
Next i
End Sub
Sub Dands()
Dim a As Integer ,x As String ' 定义动态变量a和x,每次调用重新初始化
Static b, y ' 定义静态变量b和y,保留变量的值
a=a+1 ' a为动态变量
b=b+1 ' b为静态变量
x=x & "*" ' x为动态变量
y=y & "*" ' y 为动态变量
Print "a=";a ,"b=";b, "x=";x, "y=";y
End Sub
程序的运行结果如图5-13所示。

图5-13 动态变量与静态变量示例
例5-8 下面程序中有三个同名的变量x,图5-14是运行该程序后,三次单击Command1后显示的结果。
Public x As Integer
Private Sub Command1_Click()
Dim x As Integer
x = x + 3
Call testsub
Print "Command1事件过程的x="; x, "全局的x="; Form1.x
End Sub
Public Sub testsub()
Static x As Integer
x = x + 1
Form1.x = x + 5
Print "testsub过程的x="; x, "全局的x="; Form1.x
End Sub
Private Sub Form_Load()
x = 1
End Sub

图5-14 例5-8程序运行结果
过程的递归调用是指一个过程直接或间接地调用过程本身。在递归调用中,一个过程执行的某一步可能要用到它自身上面调用的结果。
n!= 1 n=0 n?(n-1)! n>0
Visual Basic的过程具有递归调用功能。递归调用在处理阶乘运算、级数运算、幂指数运算等方面特别有效。例如,自然数n的阶乘可以递归定义为:
使用递归算法来描述显得非常简洁与清晰。
例5-9 利用递归求Fac(n)=n!
Private Sub Command1_Click()
Dim n As Integer
Cls
n = InputBox ("请输入0~50之间的整数!")
If n >= 0 And n <= 50 Then
Print n & "!="; fac(n)
Else
MsgBox "非法数据!", 0, "请输入0~50之间的整数!"
End If
End Sub
Public Function fac (n As Integer) As Double
If n > 1 Then
fac = n * fac (n - 1)
Else
fac = 1
End If
End Function
在函数fac(n)的定义中,当n>1时,连续调用fac自身共n-1次,直到n=1为止。现设n=4,则fac(4)的执行过程如图5-15所示。
fac(4)=4*fac(3) fac(3)=3*fac(2) fac(2)=2*fac(1) fac(1)=1 fac(4)=4*6 fac(3)=3*2 fac(2)=2*1

图5-15 fac(4)的执行过程
其中: ??}为递推轨迹,|------为返回轨迹。
例5-10 利用递归求最大公约数。