Visual Basic 中的过程和函数,我们使用过程和函数来创建模块化程序。 Visual Basic 语句分组在由Sub
,Function
和匹配的End
语句包围的块中。 两者之间的区别在于函数返回值,过程不返回值。
过程和功能是较大程序中的一段代码。 他们执行特定任务。 使用过程和功能的优点是:
- 减少代码重复
- 将复杂的问题分解成更简单的部分
- 提高代码的清晰度
- 重用代码
- 信息隐藏
过程
过程是Sub
,End Sub
语句内的 Visual Basic 语句块。 过程不返回值。
Option Strict On
Module Example
Sub Main()
SimpleProcedure()
End Sub
Sub SimpleProcedure()
Console.WriteLine("Simple procedure")
End Sub
End Module
此示例显示了过程的基本用法。 在我们的程序中,我们有两个过程。 Main()
过程和用户定义的SimpleProcedure()
。 众所周知,Main()
过程是 Visual Basic 程序的入口点。
SimpleProcedure()
每个过程都有一个名称。 在Main()
过程中,我们调用了用户定义的SimpleProcedure()
过程。
Sub SimpleProcedure()
Console.WriteLine("Simple procedure")
End Sub
程序在Main()
程序之外定义。 过程名称位于Sub
语句之后。 当我们在 Visual Basic 程序中调用过程时,该过程将得到控制。 执行该过程块内的语句。
过程可以采用可选参数。
Option Strict On
Module Example
Sub Main()
Dim x As Integer = 55
Dim y As Integer = 32
Addition(x, y)
End Sub
Sub Addition(ByVal k As Integer, ByVal l As Integer)
Console.WriteLine(k+l)
End Sub
End Module
在上面的示例中,我们将一些值传递给Addition()
过程。
Addition(x, y)
在这里,我们将调用Addition()
过程并将两个参数传递给它。 这些参数是两个 Integer 值。
Sub Addition(ByVal k As Integer, ByVal l As Integer)
Console.WriteLine(k+l)
End Sub
我们定义了过程签名。 过程签名是一种描述参数和参数类型的方法,通过该方法可以对函数进行合法调用。 它包含过程的名称,其参数及其类型,对于函数,还包含返回值。 ByVal
关键字指定我们如何将值传递给过程。 在我们的例子中,该过程获得两个数值 55 和 32。将这些数字相加并将结果打印到控制台。
函数
函数是Function
,End Function
语句内的 Visual Basic 语句块。 函数返回值。
有两种基本类型的功能。 内置功能和用户定义的功能。 内置函数是 Visual Basic 语言的一部分。 有各种数学,字符串或转换函数。
Option Strict On
Module Example
Sub Main()
Console.WriteLine(Math.Abs(-23))
Console.WriteLine(Math.Round(34.56))
Console.WriteLine("ZetCode has {0} characters", _
Len("ZetCode"))
End Sub
End Module
在前面的示例中,我们使用两个数学函数和一个字符串函数。 内置函数可帮助程序员完成一些常见任务。
在下面的示例中,我们有一个用户定义的函数。
Option Strict On
Module Example
Dim x As Integer = 55
Dim y As Integer = 32
Dim result As Integer
Sub Main()
result = Addition(x, y)
Console.WriteLine(Addition(x, y))
End Sub
Function Addition(ByVal k As Integer, _
ByVal l As Integer) As Integer
Return k+l
End Function
End Module
两个值传递给该函数。 我们将这两个值相加,然后将结果返回到Main()
函数。
result = Addition(x, y)
调用加法函数。 该函数返回结果,并将该结果分配给结果变量。
Function Addition(ByVal k As Integer, _
ByVal l As Integer) As Integer
Return k+l
End Function
这是加法功能签名及其主体。 它还包括用于返回值的返回数据类型。 在我们的例子中是Integer
。 使用Return
关键字将值返回给调用方。
按值传递参数,按引用传递
Visual Basic 支持将参数传递给函数的两种方法。 按价值和参考。 为此,我们有两个关键字。 ByVal
和ByRef
。 当我们按值传递参数时,该函数仅适用于值的副本。 当我们处理大量数据时,这可能会导致性能开销。
当我们通过引用传递值时,该函数会收到对实际值的引用。 修改后,原始值会受到影响。 这种传递值的方式更加节省时间和空间。 另一方面,它更容易出错。
我们应该使用哪种方式传递参数? 这取决于实际情况。 假设我们有一组数据,即员工工资。 如果我们要计算数据的某些统计信息,则无需修改它们。 我们通过价值观。 如果我们处理大量数据,并且计算速度至关重要,则可以参考。 如果我们要修改数据,例如 进行一些减薪或加薪,我们可以参考一下。
以下两个示例涵盖了这两个概念。
Option Strict On
Module Example
Dim a As Byte = 4
Dim b As Byte = 7
Sub Main()
Console.WriteLine("Outside Swap procedure")
Console.WriteLine("a is {0}", a)
Console.WriteLine("b is {0}", b)
Swap(a, b)
Console.WriteLine("Outside Swap procedure")
Console.WriteLine("a is {0}", a)
Console.WriteLine("b is {0}", b)
End Sub
Sub Swap(ByVal a As Byte, ByVal b As Byte)
Dim temp As Byte
temp = a
a = b
b = temp
Console.WriteLine("Inside Swap procedure")
Console.WriteLine("a is {0}", a)
Console.WriteLine("b is {0}", b)
End Sub
End Module
Swap()
过程在a
和b
变量之间交换数字。 原始变量不受影响。
Dim a As Byte = 4
Dim b As Byte = 7
最初,这两个变量被启动。
Swap(a, b)
我们称为Swap()
过程。 该过程将a
和b
变量作为参数。
temp = a
a = b
b = temp
在Swap()
过程中,我们更改了值。 请注意,a
和b
变量是在本地定义的。 它们仅在Swap()
程序内有效。
$ ./swap1.exe
Outside Swap procedure
a is 4
b is 7
Inside Swap procedure
a is 7
b is 4
Outside Swap procedure
a is 4
b is 7
输出显示原始变量不受影响。
下一个代码示例通过引用将值传递给函数。 原始变量在Swap()
过程中更改。
Option Strict On
Module Example
Dim a As Byte = 4
Dim b As Byte = 7
Sub Main()
Console.WriteLine("Outside Swap procedure")
Console.WriteLine("a is {0}", a)
Console.WriteLine("b is {0}", b)
Swap(a, b)
Console.WriteLine("Outside Swap procedure")
Console.WriteLine("a is {0}", a)
Console.WriteLine("b is {0}", b)
End Sub
Sub Swap(ByRef a As Byte, ByRef b As Byte)
Dim temp As Byte
temp = a
a = b
b = temp
Console.WriteLine("Inside Swap procedure")
Console.WriteLine("a is {0}", a)
Console.WriteLine("b is {0}", b)
End Sub
End Module
在此示例中,调用Swap()
过程将更改原始值。
Sub Swap(ByRef a As Byte, ByRef b As Byte)
...
End Sub
现在,我们使用ByRef
关键字来指示我们通过引用传递参数。
$ ./swap2.exe
Outside Swap procedure
a is 4
b is 7
Inside Swap procedure
a is 7
b is 4
Outside Swap procedure
a is 7
b is 4
在这里,我们看到Swap()
过程确实改变了变量的值。
递归
在数学和计算机科学中,递归是一种定义函数的方法,其中所定义的函数在其自己的定义内应用。 (维基百科)换句话说,递归函数调用自身以完成其工作。 递归是解决许多编程任务的一种广泛使用的方法。
一个典型的例子是阶乘的计算。
Option Strict On
Module Example
Sub Main()
Console.WriteLine(Factorial(4))
Console.WriteLine(Factorial(10))
End Sub
Function Factorial(ByVal n As UShort) As UShort
If (n=0)
Return 1
Else
Return n * Factorial(n-1)
End If
End Function
End Module
在此代码示例中,我们计算两个数字的阶乘。
Return n * Factorial(n-1)
在阶乘函数的主体内部,我们使用经过修改的参数调用阶乘函数。 该函数调用自身。
$ ./recursion.exe
24
3628800
这些就是结果。
模块作用域,程序作用域
作用域是可以引用变量的作用域。 在过程内部声明的变量具有过程作用域。 仅在此特定过程中有效。 在模块内部声明的变量具有模块作用域。 它在模块中的任何地方都有效。
Option Strict On
Module Example
Dim a As Byte = 2
Sub Main()
Dim b As Byte = 3
Console.WriteLine(a)
SimpleProcedure()
End Sub
Sub SimpleProcedure()
Console.WriteLine(a)
' Console.WriteLine(b)
End Sub
End Module
在前面的示例中,我们声明了两个变量。 变量 a 具有模块作用域,变量 b 具有程序作用域。
Dim a As Byte = 2
变量 a 在两个过程之外的 Example 模块内部声明。 在两个过程中均有效。
Sub Main()
Dim b As Byte = 3
...
End Sub
变量 b 在Main()
过程中声明。 仅在此有效。 在第二个过程中无效。
Sub SimpleProcedure()
Console.WriteLine(a)
' Console.WriteLine(b)
End Sub
注释打印b
变量的语句。 如果我们取消注释该行,则该示例将无法编译。
Option Strict On
Module Example
Dim a As Byte = 2
Sub Main()
Dim a As Byte = 3
Console.WriteLine(a)
End Sub
End Module
在前面的示例中,我们在两个不同的作用域中声明了一个具有相同名称的变量。 它们不会碰撞。 在Main()
过程中声明的变量将覆盖在模块作用域中声明的变量。
$ ./scope2.exe
3
输出。
静态变量
静态变量是已静态分配的变量,其生存期遍及整个程序运行。 (维基百科)默认的局部变量在函数的连续调用中不会保留其值。
Option Strict On
Module Example
Sub Main()
NonStatic()
NonStatic()
NonStatic()
NonStatic()
Console.WriteLine(NonStatic)
End Sub
Function NonStatic() As Integer
Dim x As Integer = 0
x += 1
Return x
End Function
End Module
在上面的示例中,我们有一个普通的非静态变量。 每次调用函数时,我们都会增加变量。 我们调用该函数 5 次。 但是,对于函数的每次调用都会启动非静态变量。
$ ./nonstatic.exe
1
在 5 个函数调用之后,x
变量等于 1。
首次调用函数时,静态变量仅启动一次。 之后,他们保留自己的价值。
Option Strict On
Module Example
Sub Main()
StaticFunction()
StaticFunction()
StaticFunction()
StaticFunction()
Console.WriteLine(StaticFunction)
End Sub
Function StaticFunction() As Integer
Dim Static x As Integer = 0
x += 1
Return x
End Function
End Module
连续 5 次通话后,x
等于 5。
Dim Static x As Byte = 0
静态变量是使用Static
关键字创建的。
$ ./static.exe
5
运行示例。