3-about sub&fun-ction

本文深入讲解了VB.NET中的过程,包括Sub过程和function过程的定义、调用方式及注意事项,探讨了参数传递机制,并提供了丰富的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

过程
过程分为两类,即子程序过程和函数过程,前者叫做Sub过程,后者叫做function过程。  

Sub过程
[Private][Public]Sub过程名[(参数表列)]
             语句块
             [Exit Sub]
             [语句块]
             [Return]
End Sub
Sub过程不能嵌套。也就是说,在Sub过程内,不能定义Sub过程或function过程;不能用GoTo语句进入或退出一个Sub过程,只能通

过调用执行Sub过程,而且可以嵌套调用。 
*通用过程不属于任何一个事件过程,因此不能用事件过程定义。通用过程可以在窗体、模块、类或结构中建立。如果在窗体中建

立通用过程,则可双击窗体进入代码窗口,在“类名”框中选择窗体名称,例如“Form1”,在“方法名称”框中选择“(Declarations)”,然后直接在窗口内键入过程名字,并按回车键。例如,键入“Sub Tryout( )”,按回车键后,窗口内显示:
Sub Tryout (   )
   
End Sub

调用Sub过程:一种是把过程的名字放在一个Call语句中,一种是把过程名作为一个语句来使用。
⒈ 用Call语句调用Sub过程
       格式:Call过程名[(实际参数)]
       用Call语句调用一个过程时,如果过程本身没有参数,则“实际参数”可以省略,但括号不能省略;如果过程本身带有参

数,则应给出相应的实际参数,并把参数放在括号中。

⒉ 省略关键字Call,把过程名作为一个语句来使用
'
'
'--------------------------------------------------------------------------------------------  

编写一个计算矩形面积的Sub过程,然后调用该过程计算矩形面积。
Sub Recarea(ByVal Rlen As Single, ByVal Rwid As Single)
          Dim Area As Single
          Area = Rlen * Rwid
          Debug.WriteLine("Total Area is" & Str(Area))
  End Sub
Private Sub Form1_load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim A, B As Single
        A = InputBox("What is the length?")
        A = Val(A)
        B = InputBox("What is the width?")
        B = Val(B)
        Recarea(A, B)
    End Sub

'其他
Sub Recarea(ByVal Rlen As Single, ByVal Rwid As Single, ByRef Area As Single)
          Area = Rlen * Rwid
    End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          Dim A, B, C As Single
          A = InputBox("What is the length?")
          A = Val(A)
          B = InputBox("What is the width?")
          B = Val(B)
          Recarea(A, B, C)
          Debug.WriteLine("Total Area is" & Str(C))
    End Sub
'
'
'--------------------------------------------------------------------------------------------

 function过程
[Private][Public] function过程名[(参数表列)][As类型]
 [语句块]
 [过程名=表达式]
 [Exit function]
 [语句块]
 [Return]
End function
调用Sub过程相当于执行一个语句,不直接返回值;而调用function过程要返回一个值,因此可以像内部函数一样在表达式中使用

。由function过程返回的值放在上述格式中的“表达式”中,并通过“过程名=表达式”把它的值赋给“过程名”。为了能使一个f

unction过程完成所指定的操作,通常要在过程体中为“过程名”赋值。例如:

function BinarySearch(Lower, Upper As Integer) As Boolean
           ……
 If  Lower = Upper Then
  BinarySearch=True ''返回值或return True
  Exit function
 Else
         BinarySearch=False
        End If
……
End function
Return语句有两个作用,一是返回函数值,二是退出function过程。
如果在function过程中省略“过程名=表达式”或“Return表达式”,则过程返回一个默认值。
 

编写一个求最大公约数的函数过程。
function gongyueshu(ByVal x As Integer, ByVal y As Integer) As Integer
          Dim reminder As Integer
          Do While y <> 0
            reminder = x Mod y
            x = y
            y = reminder
          Loop
          gongyueshu = x
 End function

打印0到1000之间的伪随机数,要打印的随机数的个数在运行时指定,要求每5个打印一行,生成随机数的操作用一个function过程

来实现 
Dim x As Integer
function rand() As Short
          Dim n As Short
          x = x * 29 + 37
          x = x Mod 1000
          n = x
          Return n
End function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          Dim ranNum, m As Short
          x = 777
          ranNum = InputBox("需要输出多少随机数?")
          Debug.WriteLine("")
          Debug.WriteLine("输出0到1000之间的随机数:")
          Debug.WriteLine("")
          For m = 1 To ranNum
            If m Mod 5 = 0 Then
                Debug.WriteLine(Str(rand()) & "")
            Else 
                Debug.Write(Str(rand()) & "")
            End If
          Next m
End Sub


从键盘上输入一个数,输出该数的平方根。
function SquareRoot(ByVal X As Double) As Double
          Select Case Sign(X)
            Case 1
                Return Sqrt(X)
            Case 0
                Return 0
            Case -1
                Return -1
          End Select
End function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          Dim Msg As String
          Dim SqrN As Short
          Dim N As Double
          N = InputBox("请输入要计算平方根的数:")
          Msg = N & "的平方根"
   Select Case SquareRoot(N)
            Case 0
                Msg = Msg & "是0"
            Case -1
                Msg = Msg & "是一个虚数"
            Case Else
                Msg = Msg & "是" & Sqrt(N)
          End Select
          MsgBox(Msg, , "")
End Sub

传地址和传值。
其中传地址习惯上称为引用。引用方式通过关键字ByRef来指定,而传值方式通过关键字ByVal来指定。在默认情况下,Visual

Basic.NET使用的是传值方式。 通过“引用”方式把变量传送给Sub或function过程时,可以通过改变过程中相应的参数来改变该

变量的值。 形参前面有关键字ByVal,则该参数用传值方式传送;如果形参前面有关键字ByRef,则用引用(即传地址)方式传送

试验引用方式传送参数。
Sub tryout(ByRef x As Integer, ByRef y As Integer)
        x = x + 100
        y = y * 6
        MsgBox("x=" & Str(x) & "y=" & Str(y))
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim a As Integer, b As Integer
        a = 10 : b = 20
        tryout(a, b)
        MsgBox("a=" & Str(a) & "b=" & Str(b))
End Sub

数组名做参数,实现数组传送。
Sub changeArray(ByVal Min%, ByVal Max%, ByRef p() As Integer)
        Dim i As Integer
        For i = Min% To Max%
            p(i) = i ^ 3
        Next I
End Sub
Sub PrintArray(ByVal Min%, ByVal Max%, ByRef p() As Integer)
        Dim i As Integer
        For i = Min% To Max%
            Debug.WriteLine(p(i))
        Next I
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Values(4) As Integer
        Call changeArray(0, 4, Values)
        Call PrintArray(0, 4, Values)
End Sub


求数组元素的平方根
Imports System.Math           ′该行放在窗体代码的前面
Dim test_array(,) As Integer
Sub Sqval(ByRef a As Integer)
        a = Sqrt(Abs(a))
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ReDim test_array(4, 2)
        test_array(4, 2) = -36
        Debug.WriteLine(test_array(4, 2))
        Call Sqval(test_array(4, 2))
        Debug.WriteLine(test_array(4, 2))
End Sub

编写一个function过程,求数组的最大值。
Private function FindMax(ByRef a() As Integer)
        Dim Finish, i, Max As Integer
        Finish = Ubound(a)
        Max = a(0)
        For i = 0 To Finish
            If a(i) > Max Then Max = a(i)
        Next i
        Return Max
End function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim b() As Integer = {30, 2540, 5489, 954, 23, 65, 8}
        Dim c As Integer
        c = FindMax(b)
        MsgBox(c, , "")
End Sub


可选参数/
在Visual Basic.NET中,可以指定一个或多个参数作为可选参数。
⑴ 可选参数必须放在所有必选参数的后面。
⑵ 每个可选参数必须以Optional开头,而且必须有默认值。为了在调用时能得到正确的值,过程中应当有相应的判断语句。

*可变参数
过程通过ParamArray命令来定义:Sub过程名(ParamArray数组名)定义一个可变参数过程,用这个过程可以求任意多个数的乘积


Sub Multi(ByVal ParamArray Numbers( ) As Integer)
Dim n,x As Integer
n=1
For Each x In Numbers
 n=n*x
Next x
MsgBox(n)
End Sub


递归
编程序计算n!
function Factorial(ByVal N As Integer) As Double
        If N > 0 Then
            Factorial = N * Factorial(N - 1)
        Else
            Factorial = 1
        End If
End function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim num As Integer
        Dim msg, NL As String
        msg = "Factorial is:"
        NL = Chr(13) & Chr(10)

  Do
            Dim r As Decimal     '块变量
            Dim msg1 As String   '块变量
            num = InputBox("Enter a number from 0 to 27(or –1 to end:")
            If num > 0 And num <= 27 Then
                r = Factorial(num)
                msg1 = Str(num) & msg & NL & Str(r)
                MsgBox(msg1, , "")
            End If
            msg1 = ""
        Loop While num >= 0
    End Sub

 

*用递归过程计算组合数。
Dim w As Integer
function comp(ByVal x As Integer, ByVal y As Integer, ByRef w As Integer)
        If x < 2 * y Then y = x - y
        w = w + 1
        If y = 0 Then
            comp = 1
        ElseIf y = 1 Then
            comp = x
        Else
            comp = comp(x - 1, y - 1, w) + comp(x - 1, y, w)
        End If
End function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim m, n, z As Integer
        m = InputBox("Enter a value of M:")
        n = InputBox("Enter a value of N:")
        z = comp(m, n, w)
        Debug.WriteLine("Number of recursion is" & Str(w))
        Debug.WriteLine("final result is" & Str(z))
    End Sub


Shell函数
        凡是能在Windows下运行的应用程序,基本上都可以在Visual Basic.NET中调用。这一功能通过Shell函数来实现。
 Shell(命令字符串,[,窗口类型][,等待] [,时间])

用Shell函数调用应用程序。
function retnum() As Integer
        Dim NL, msg As String
        NL = Chr(13) + Chr(10)
        msg = "1.运行看图软件ACDSee" + NL + "2.运行QuickTime"+ NL + "3.计算器"
        msg = msg + NL + NL + "请输入数字选择:"
        retnum = InputBox(msg, "输入", 1)
End function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim r, proID As Integer
        r = retnum()
        If r = 1 Then
            ProID = Shell("C:/Program Files/ACD Systems/ACDSee/acdsee.exe", _ AppWinStyle.MinimizedFocus))
        ElseIf r = 2 Then
            proID = Shell("C:/Program Files/Quick Time/QuickTimePlayer.exe", _ AppWinStyle.MaximizedFocus)

 ElseIf r = 3 Then
            proID = Shell("calc.exe", AppWinStyle.MaximizedFocus)
        Else
            MsgBox("请输入1-3的数")
        End If
    End Sub

 

实现一个十进制整数转换成二至十六任意进制的字符串。
function TranDec$(ByVal m, ByVal r)
        Dim imr(60) As Integer     '存放不断除r后得到的余数
        Dim strBase As String : Dim StrDtoR$ : Dim iB, i As Integer
        strBase = "0123456789ABCDEF"
        i = 0
        Do While m <> 0         '不断除某进制取余直到商为0
            imr(i) = m Mod r
            m = m / r
            i = i + 1
  Loop
        StrDtoR = ""
        i = i + 1
        Do While i >= 0         '形成某进制的字符串                       
            StrDtoR = StrDtoR + Mid$(strBase, imr(i) + 1, 1)'将余数转换成对应的字符
            i = i - 1
        Loop
        TranDec = StrDtoR
    End function

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim m0%, r0%, I%
        m0 = Val(TextBox1.Text)          '输入十进制正整数
        r0 = Val(TextBox2.Text)          '输入r进制
        If r0 < 2 Or r0 > 16 Then
            I = MsgBox("输入的r进制数超出范围", vbRetryCancel)
            If I = vbRetry Then
                TextBox2.Text = ""
            Else
                End
            End If
        End If
        Label3.Text = "转换成" & r0 & "进制数"              '转换标签随输入的进制改革
        TextBox3.Text = TranDec(m0, r0)                     '调用转换函数,显示转换结果
    End Sub


编一加密和解密的程序,即将输入的一行字符串中的所有字母加密,加密后还可再进行解密。:
Dim strInput, Code, Record, c As String
    Dim i%, length%, iAsc%
Private Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
        TextBox1.Text = ""
        TextBox2.Text = ""
        TextBox3.Text = ""
End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim strInput, Code, Record, c As String
        Dim i%, length%, iAsc%
        strInput = TextBox1.Text
        length = Len(RTrim(strInput))    '去掉字符串右边的空格,求真正的长度
        Code = ""
        For i = 1 To length
  c = Mid$(strInput, i, 1)     '取第i个字符
            Select Case c
                Case "A" To "Z"          '大写字母加序数5加密
                    iAsc = Asc(c) + 5
                    If iAsc > Asc("Z") Then iAsc = iAsc - 26 '加密后字母超过Z
                    Code = Code + Chr(iAsc)
                Case "a" To "z"
                    iAsc = Asc(c) + 5     '小写字母加序数5加密
                    If iAsc > Asc("z") Then iAsc = iAsc - 26
                    Code = Code + Chr(iAsc)
                Case Else                  '当第i个字符为其他字符时不加密
                    Code = Code + c
            End Select
        Next i
        TextBox2.Text = Code               '显示加密后的字符串
End Sub


顺序查找根据查找的关键值与数组中的元素逐一比较,若相同,查找成功,若找不到,则查找失败。
Public Sub Search(ByRef a() As Integer, ByVal key As Integer, ByVal index As Integer)
        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形参的值为-1
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim b() = {1, 3, 5, 7, 9, 2, 4}, k, n As Integer
        k = Val(InputBox("输入要查找的关键值"))
        Call Search(b, k, n)
        TextBox1.Text = n
End Sub


二分法查找的思路是,要查找的关键值同数组的中间项元素比较,若相同则查找成功结束;否则判别关键值落在数组的哪半部分,

然后保留一半,舍弃另一半。如此重复上述查找,直到查找到或数组中没有这样的元素。二分法查找每进行一次,就把数据的个数

减少一半。
 Sub birsearch(ByRef a(), ByVal low, ByVal high, ByVal key, ByVal index)
        Dim mid, min As Integer
        mid = (low + high) / 2        '取查找区间的中点
        If a(mid) = key Then
            index = mid               '查找到,返回查找到的下标
            Exit Sub
        ElseIf low > high Then        '二分法查找区间无元素,查找不到
            index = -1
            Exit Sub
        End If
 If key < a(mid) Then          '查找区间在上半部
            high = min - 1
        Else
            low = mid + 1             '查找区间在下半部
        End If
        Call birsearch(a, low, high, key, index)     '递归调用查找函数
  End Sub

主调程序调用:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim b() = {5, 13, 19, 21, 37, 56, 64, 75, 80, 88, 92}, n As Integer
        Call birsearch(b, LBound(b), UBound(b), 21, n%)
        TextBox1.Text = n
  End Sub

 

**对二次方程求根有求根公式,可求得精确解,二次以上的高次方程求解,通常用牛顿切线法、二分法、弦截法等迭代法求得方程

的近似解。二分法和弦截法都是在已知有根的一段区间内用逐步逼近的方法求根。
利用牛顿切线法求根。
Public Sub Newton(ByVal x0 As Double, ByVal x As Double, ByVal eps As Double)
        '迭代初值x0,求得的根x,精度eps
        Dim fx, f1x As Double
        Do
            fx = 3 * x0 * x0 * x0 - 4 * x0 * x0 - 5 * x0 + 13
            f1x = 9 * x0 * x0 - 8 * x0 - 5
            x = x0 - fx / f1x
            If Abs(x - x0) < eps Then Exit Do
            x0 = x
        Loop
        TextBox1.Text = x
    End Sub
‘主调程序调用
Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
        Dim root As Double
        Call Newton(3.0#, root, 0.00001)
    End Sub


**二分法求根的思路与二分法查找的思路相似,在二分过程中不断缩小求根的区间。即若方程f(x)=0在区间[a,b]有一个根,则f(a

)与f(b)的符号必然相反 。取c=(a+b)/2不断重复二分过程,将含根区间缩小一半,直到f(c)≤精度。

 

求定积分。数值积分是用近似计算方法,解决定积分计算问题,常用的方法有矩形法、梯形法、抛物线法(又称辛卜生法)等,按

积分划分的区间,又有定长和变长的不同实现方法。
Public function trapez(ByVal a As Double, ByVal b As Double, ByVal n As Integer) As Single
        Dim sum, h, x As Double : Dim i
        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 I
        trapez = sum * h
    End function
 Public function f(ByVal x As Double)
        f = x * x * x + 2 * x + 5           '对不同的被积函数在此作对应的改动
    End function
Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
        TextBox1.Text = trapez(1, 3, 30)
 End Sub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值