- Visual Basic從入門到精通(第2版)
- 龍馬高新教育策劃 國家863中部軟件孵化器編著
- 5464字
- 2019-01-02 05:00:34
第5章 應用程序提升的法寶—內置函數與過程
本章視頻教學錄像:1小時13分鐘
使用Visual Basic中的內置函數,程序員在實現許多功能的同時可以減少大量代碼的編寫,而巧妙地使用過程則可使計算機完成特定的功能。本章主要介紹Visual Basic中常用的內置函數、Sub過程和Function過程。
本章要點(已掌握的在方框中打鉤)
□ 了解數學函數
□ 了解字符串函數
□ 了解轉換函數
□ 了解時間日期函數
□ 了解隨機函數
□ 了解判斷函數
□ 了解格式化函數
□ 了解Shell函數
□ 掌握過程及過程的嵌套與遞歸調用
□ 了解參數傳遞
5.1 秘密武器——常用的內置函數
本節視頻教學錄像:38分鐘
巧妙地使用內置函數,程序員可以減少代碼的編寫量,輕松實現許多復雜的功能。本節介紹一些常用的內置函數。
5.1.1 數學函數
數學函數就是實現各種數學計算的函數,在Visual Basic中包含有豐富的數學函數供用戶使用。常用的數學函數如表所示。

例如,使用Abs函數來計算“3”和“-3”的絕對值。
01 Private Sub Form_Activate() 02 Print"3的絕對值是:"&Abs(3) '輸入正數3的絕對值 03 Print"-3的絕對值是:"&Abs(-3) '輸出負數3的絕對值 04 End Sub
運行窗體后,結果如圖所示。

5.1.2 字符串函數
在程序設計中,將能夠對字符串處理的函數稱為字符串函數。常用的字符串函數如表所示。

例如,使用Left()函數獲取某字符串中最左邊的6個字符。
01 Private Sub Form_Activate() 02 Dim str As String '定義字符串變量 03 str="Congratulations" '為字符串變量賦初值 04 Print"字符串最左邊的6個字符是:"&Left(str,6) '輸出字符串最左邊6位 05 End Sub
運行窗體后,結果如圖所示。

5.1.3 轉換函數
在編程處理數據的時候,有時需要在各種數據類型間進行轉換,Visual Basic中提供有很多數據類型轉換的函數,特別是各種進制數據的轉換以及字符串和數字的轉換函數。
1. 進制轉換函數
常見數據進制有十進制、二進制、八進制、十六進制等。十進制是我們最為常見和常用的數據進制,二進制是計算機的基礎進制,八進制和十六進制因為和二進制有著天然的親密關系,并且表示比二進制更方便,因此也成為計算機的常用表示方法。
在Visual Basic中進行數據進制轉換的函數中,常用的有以下幾種。
⑴ Hex()函數
求出參數的十六進制形式。
語法:
Hex(number)
number參數為任何有效的數值表達式或字符串表達式,不同取值情況下的函數返回結果如表所示。

例如輸入一個十進制數,將其轉換成十六進制,并將轉換后的結果輸出在窗體上。
01 Private Sub Command1_Click() 02 Print"您輸入的十進制數是"&Text1.Text '輸出獲得的十進制數 03 Print"轉成十六進制后為:"&Hex(Val(Text1.Text)) '輸出轉換后的結果 04 End Sub
輸入一個十進制數“15”,單擊【轉換】按鈕,結果如圖所示。

⑵ Oct()函數
求出參數的八進制形式。
語法:
Oct(number)
number參數為任何有效的數值表達式或字符串表達式,不同取值情況下的函數返回結果如表所示。

例如輸入一個十進制數,將其轉換成八進制,并將轉換后的結果輸出在窗體上。
01 Private Sub Command1_Click() 02 Print"您輸入的十進制數是"&Text1.Text '輸出獲得的十進制數 03 Print"轉成八進制后為:"&Oct(Val(Text1.Text)) '輸出轉換后的結果 04 End Sub
輸入一個十進制數“8”,單擊【轉換】按鈕,結果如圖所示。

⑶ Cint()函數
用于強制將一個表達式轉換成-32768~327 67的整型。
語法:
Cint(number)
number參數為任何有效的數值表達式或返回值為數值的字符串表達式。
例如輸入一個帶小數的數值,將其強制轉換成整型,并將轉換后的結果輸出在窗體上。
01 Private Sub Command1_Click()
02 Print"您輸入數值是"&Text1.Text '輸出獲得的十進制數 03 Print"強制轉換后為:"&Clnt(Val(Text1.Text)) '輸出轉換后的結果 04 End Sub
輸入任意有效的數值表達式或字符串表達式,單擊【轉換】按鈕,結果如圖所示。

2. 字符串和數字轉換函數
⑴ Str()函數
將數值型數據轉換為字符型數值。
語法:
Str(number)
number參數為長整型,其中可包含任何有效的數值表達式。
例如,將一個數字轉換成字符串。
01 Private Sub Form_Activate() 02 Print str(156.33) '返回" 156.33" 03 Print str(-156.33)'返回" -156.33" 04 End Sub

提示
當數字轉換成字符時,字符串的首位是一個空格或是正負號。
⑵ Val()函數
返回包含于字符串內的數字。
語法:
Val(string)
string參數可以是任何有效的字符串表達式。
例如,返回字符串中包含的數值。
01 Private Sub Form_Activate() 02 Print Val("111.11") '返回"111.11" 03 Print Val("-111.11") '字符中的空格被除去了,返回"-111.11" 04 End Sub

5.1.4 日期時間函數
在編寫程序的時候,往往會遇到各種樣式的日期和時間,例如在狀態欄中顯示當前的系統日期等。

下面介紹幾個常用的日期時間函數和日期時間轉換函數。
1. Date ( )函數
用于返回系統的當前日期。
語法:
Date
例如,在窗體上顯示系統的當前日期。
01 Private Sub Form_Activate() 02 Print"今天是:"&Date '返回系統當前日期 03 End Sub
結果如圖所示。

2. Day(date)函數
用于表示一個月中的某一日,返回值為1~31之間的整數。
語法:
Day(date)
date參數可以是任何能夠表示日期的可變類型數據、數值表達式、字符串表達式或它們的組合。如果date包含Null,則返回Null;如果不為空,則返回當前指定的日期的某一日。
例如,在窗體上顯示系統當前是本月的第幾天。
01 Private Sub Form_Activate() 02 Print"今天已是本月的第"&Day(Date)&"天!" '返回系統當前是本月第幾天 03 End Sub
結果如圖所示。

3. Month()函數
用于返回1到12之間的整數,表示一年中的某月。
語法:
Month(date)
date參數可以是任何能夠表示日期的可變類型數據、數值表達式、字符串表達式或它們的組合。如果date包含Null,則返回Null;如果不為空,則返回當前指定的日期的某一月。
例如,在窗體上顯示系統當前本年的月份。
01 Private Sub Form_Activate() 02 Print"現在已是本年的"&Month(Date)&"月份了!" '返回系統當前月份 03 End Sub
結果如圖所示。

4. Time()函數
用于返回當前系統時間(不包含日期)。
語法:
Time
例如,在窗體上顯示當前的時間。
01 Private Sub Form_Activate() 02 Print"現在是,北京時間:"&Time '返回系統當前時間 03 End Sub
結果如圖所示。

5. Weekday() 函數
返回某個日期是星期幾。
語法:
Weekday(date,[firstdayofweek])
Weekday函數語法中參數的含義如表所示。

firstdayofweek參數設置值如表所示。

Weekday函數的返回值如表所示。

例如,返回當前天數是本周的第幾個工作日。
01 Private Sub Form_Activate() 02 Print"今天已是本周的第"&Weekday(Date)&"個工作日了" '返回系統工作日 03 End Sub
效果如圖所示。

6. Year()函數
用于返回日期中的年份。
語法:
Year(date)
date參數可以是任何能夠表示日期的可變類型數據、數值表達式、字符串表達式或它們的組合。如果date包含Null,則返回Null;如果不為空,則返回當前指定的年份。
例如,在窗體上顯示系統日期是哪一年。
01 Private Sub Form_Activate() 02 Print"時間已經到了公元"&Year(Date)&"年!" '返回當前年份 03 End Sub
結果如圖所示。

5.1.5 隨機函數
在編程處理數據的時候,經常會用到隨機函數,包括Randomize函數和Rnd函數。
1. Randomize函數
Randomize函數是初始化隨機數生成器。
語法:
Randomize[number]
number:可選參數,是Variant類型的值或任何有效的數值表達式。
提示
若想得到重復的隨機序列,要在使用具有數值參數的Randomize之前直接調用具有負參數值的Rnd,使用具有同樣數值的Randomize是不會得到重復的隨機數序列的。
2. Rnd函數
Rnd函數用于返回一個Single類型的隨機數值。
語法:
Rnd[(number)]
如果number的值是Rnd生成,則number的值:
小于0:每次都使用number作為隨機數種子得到的相同結果。
大于0:序列中的下一個隨機數。
等于0:最近生成的數。
默認:序列中的下一個隨機數。
注意
Rnd函數返回小于1但大于或等于0的值。number的值決定了Rnd生成隨機數的方式。
對最初給定的種子都會生成相同的數列,因為每一次調用Rnd函數都用數列中的前一個數作為下一個數的種子。在調用Rnd之前,先使用無參數的Randomize語句初始化隨機數生成器,該生成器具有根據系統計時器得到的種子。
為了生成某個范圍內的隨機整數,可使用以下公式。
lnt((upperbound - lowerbound + 1) * Rnd + lowerbound)
這里,upperbound是隨機數范圍的上限,而lowerbound則是隨機數范圍的下限。
提示
若想得到重復的隨機數序列,在使用具有數值參數的Randomize之前直接調用具有負參數值的Rnd。使用具有同樣number值的Randomize是不會得到重復的隨機數序列的。
5.1.6 判斷函數
在進行數據驗證的過程中,使用判斷函數會為編程工作帶來極大的方便,判斷函數包括IsNull函數、IsNumeric函數和IsArray函數。
1. IsNull函數
IsNull函數用于返回一個Boolean類型值,指出表達式是否不包含任何有效數據(Null)。
語法:
lsNull(expression)
expression:必要參數,是一個Variant類型的值,其中包含數值表達式或字符串表達式。
2. IsNumeric函數
Isnumeric函數用于返回一個Boolean類型的值,指出表達式的運算結果是否為數值。
語法:
lsNumeric(expression)
expression:必要參數,是一個Variant類型的值,包含數值表達式或字符串表達式。
3. IsArray函數
IsArray函數用于返回一個Boolean類型的值,指出變量是否為一個數組。
語法:
lsArray(varname)
Varname:必要參數,是一個指定變量的標識符。
5.1.7 格式化函數
Visual Basic中的格式化函數也稱Format函數。
用于返回Variant(String)類型值,其中含有一個表達式,它是根據格式表達式中的指令來格式化數據的。
語法:
Format(expression[,format[,firstdayofweek[,firstweekofyear]]])
Format函數的語法具有下面幾個部分。

1.設置值
firstdayofweek參數有下面的設置。

2.說明
firstweekofyear參數有下面的設置。

如果在格式化數字時沒有指定format,Format會提供與Str函數類似的功能,盡管它是國際化的。然而,以Format作用在正數上不會保留正負號空間,而以Str的話則會。
如果要格式化一個沒有本地化的數值字符串,應該使用一個用戶自定義的數值格式,以保證得到需要的外觀。
注意如果Calendar屬性設置是Gregorian,并且format指定了日期格式,那么,提供的expression必須是Gregorian。如果Visual BasicCalendar屬性設置是Hijri,則提供的expression必須是Hijri。
如果日歷是Gregorian,則format表達式的意義沒有改變。如果日歷是Hijri,則所有的日期格式符號(例如,dddd,mmmm,yyyy)有相同的意義,這些意義只應用于Hijri日歷。格式符號保持英文,用于文本顯示的符號(例如,AM和PM)顯示與該符號有關的字符串(英文或阿拉伯數字)。當日歷是Hijri時,一些符號的范圍會改變。
5.1.8 Shell函數
除了以上介紹的幾個函數外,本小節介紹Shell函數。Shell函數的作用是在Visual Basic應用程序的執行過程中調用執行其他的應用程序,凡是能在DOS下或Windows下運行的可執行程序,均可通過Shell()函數在Visual Basic應用程序中調用。
Shell()函數的語法如下。
Shell(命令字符串[,窗口類型])
命令字符串是要執行的應用程序名,包括路徑,它必須是可執行文件(擴展名為.com、.exe或.bat)。
窗口類型是指執行應用程序的窗口大小,可選擇0~4或6的整型數值。取1,表示正常窗口狀態。默認值為2,表示窗口被最小化成任務欄上的一個圖標。
5.2 提升法寶——過程
本節視頻教學錄像:32分鐘
過程就是一個具有相對獨立的代碼塊。在一個大型系統中,會有很多獨立的代碼塊,每個代碼塊將會完成一定的功能,最后把各個代碼塊組合起來就實現了大型系統的全部功能。
5.2.1 事件過程
當用戶對某個窗體或控件等對象發出了一個動作后,將會產生一個事件。Visual Basic會自動調用與該事件有關的過程,該過程就是一個事件過程。
事件過程的語法是:
Private Sub <對象名>_<事件名>([<形式參數表>]) <代碼段> End Sub
不同的對象所對應的事件過程的命名方式有所不同,窗體和控件都有各自的事件過程命名方式。
例如每個窗體都有自己的名稱,但是不論窗體的名稱是什么,在窗體的事件過程中統一用Form表示。在編寫控件的事件過程時,在代碼編輯窗口左側的對象下拉列表中選擇控件,在代碼編輯窗口右側的過程下拉列表中選擇相應的事件名。

5.2.2 Sub過程(子過程)
Sub過程是指根據特定的實際需要而編寫的,用來實現某種功能的代碼塊。例如,一本《Visual Basic 6.0從入門到精通》的書的出版是一個最終的結果,在這期間,出版社會找優秀的作者去寫這本書,然后再找排版人員對這本書進行排版,最后由編輯對書進行審校。一本書的出版,對出版社來說并不需要完全由自己親自去寫書、排版和審校,對于寫書和排版來說,只需要調用相應的人員去做即可。
子過程的語法是:
[Private|Public|Static]Sub <過程名>(<形式參數表>) <代碼段> End Sub
我們創建一個子過程的時候,不需要在某個特定窗體或者模塊內編寫,直接在代碼窗口中輸入子過程的代碼即可。下圖建立了一個新的子過程:SubTest。

創建一個通用過程的目的就是為了調用它。由于子過程是一個獨立的過程,不能通過語句直接返回值,所以要用以下兩種形式調用一個子過程。
⑴ 使用Call語句:Call <過程名>([<實參表>])。
⑵ 直接使用過程名:<過程名>([<實參表>])。
“實參表”是可選項,“實參表”中的參數必須與子過程的形式參數表中的參數一一對應,并且相應位置上的參數類型也要相同。實參表中的參數可以為常量、變量或者表達式,而子過程的形式參數表對過程傳遞參數的描述則包括形參變量的名稱和類型。
【范例5-1】 定義一個Sub子過程,主要用于進行階乘的運算。輸入一個數值,通過調用該Sub子過程,計算出該數值的階乘值。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中。選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 在Form1窗體中添加1個命令按鈕控件和1個文本框控件,并將命令按鈕控件的Caption屬性值設置為“計算”,將文本框控件的Text值設置為空。

⑶ 在Form1窗體中雙擊【計算】按鈕,打開代碼窗口,輸入以下代碼(代碼5-1-1.txt)。
01 Private Sub Command1_Click() 02 Dim a As lnteger,s As lnteger,total As lnteger,j As lnteger,x As lnteger,str As String 03 x=Val(Text1.Text) '將獲取的文本內容轉換為數值型 04 s=0 's用于得到計算的最終結果 05 str="" '初始化字符串 06 For j=1 To x '開始計數循環 07 Call fact(j,total) '調用階乘計算的子過程,并向子過程傳遞兩個參數 08 s=s+total '記錄第1次運算的結果 09 str=str&j&"!+" '輸入階乘數 10 Next j '符合條件,進行下一次運算 11 str=str+"=" '得到最終計算結果 12 Print str;s; '輸出最終計算結果 13 End Sub
⑷ 在代碼窗口中編寫fact子過程的代碼(代碼5-1-2.txt)。
01 Private Sub fact(n As lnteger,t As lnteger) '定義形式參數表 02 Dim i,s As lnteger 03 s=1 '初始化變量,用于計算階乘的初始值 04 For i=1 To n 05 s=s*i '累積 06 Next i 07 t=s '得到結果 08 End Sub
提示
子過程是一個獨立的過程,可以寫在其他過程以外的任何地方,但不可以在已有過程的內部編寫。為了讀取程序方便,通常在只有一個子過程的情況下,可以將其放在代碼段的最后面或最前面。
【運行結果】
保存程序,單擊【啟動】按鈕,運行程序。在文本框中輸入數值“7”,單擊【計算】按鈕,結果如圖所示。

【拓展訓練5-1】
在Visual Basic中不僅可以調用有返回值的函數,同時還可以調用無返回值的函數。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 在Form1窗體中添加1個命令按鈕控件。

⑶ 在Form1窗體中雙擊【Command1】按鈕,進入代碼窗口,輸入以下代碼。
01 Private Sub Command1_Click() 02 Call XS'調用子函數 03 End Sub
⑷ 在代碼窗口中編寫XS子過程的代碼。
01 Private Sub XS() 02 Print"我是無參的" '輸出字符串 03 End Sub
⑸ 保存程序,按【F5】快捷鍵運行程序,單擊【Commad1】按鈕查看程序效果。

5.2.3 Function過程(函數過程)
函數過程也是用來完成具有特定功能的代碼段,其語法是:
[Private|Public|Static]Function <函數過程名>(<形式參數表>)[As<返回值類型>] <代碼段> <函數過程名>=<返回值> End Function
提示
Function過程和Sub子過程有不同的地方,函數過程可以向調用過程明確地返回一個值。所以調用函數過程比調用子過程多了一種形式,共有以下3種形式。
⑴ 使用Call語句:Call <函數名>([<實參表>])。
⑵ 直接使用過程名:<函數名>([<實參表>])。
⑶ 在表達式中調用:<返回值變量>=<函數名>([<實參表>])。
【范例5-2】 定義一個Function過程,輸入一個數值,通過調用Function函數,
計算出該數值的階乘值。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 在Form1窗體中添加1個命令按鈕控件和1個文本框控件,并將命令按鈕控件的Caption屬性值設置為“計算”,將文本框控件的Text值設置為空。

⑶ 在Form1窗體中雙擊【計算】按鈕,打開代碼窗口,輸入以下代碼(代碼5-2-1.txt)。
01 Private Sub Command1_Click() 02 Dim a As lnteger,s As lnteger,total As lnteger,j As lnteger,x As lnteger,str As String 03 x=Val(Text1.Text) '將獲取的文本內容轉換為數值型 04 s=0 's用于得到計算的最終結果 05 For j=1 To x '利用計數循環開始計數 06 s=s+fact(j) '調用過程函數 07 str=str&j&"!+" '格式化字符輸出形式 08 Next j 09 str=str&"=" '再次格式化字符輸出形式 10 Print str;s; '輸出最終計算結果 11 End Sub
⑷ 在代碼窗口中編寫fact子過程的代碼(代碼5-2-2.txt)。
01 Private Function fact(n As lnteger) '定義形式參數表 02 Dim i,s As lnteger 03 s=1 '用于得到結果 04 For i=1 To n 05 s=s*l '累積 06 Next l '滿足條件進行下次循環 07 fact=s '函數fact的返回值 08 End Function
【運行結果】
保存程序,單擊【啟動】按鈕,運行程序。在文本框中輸入數值“7”,單擊【計算】按鈕,結果如圖所示。

【拓展訓練5-2】
本實例主要講解如何使用Visual Basic中提供的可視化圖形窗口來創建一個過程。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 雙擊Form1窗體,進入代碼窗口。
技巧
如果當前打開的窗口不是代碼窗口,則無法進行下面的操作。
⑶ 選擇【工具】【添加過程】菜單命令,打開【添加過程】對話框。
⑷ 在【名稱】文本框中輸入過程名,例如輸入“SubTest”。


⑸ 在【類型】選項組中選中【函數】單選按鈕。
注意
在【添加過程】對話框中的【類型】選項組中,可以選中【子程序】單選按鈕來創建一個子過程(Sub),或者選中【函數】單選按鈕來創建一個函數過程(Function)。

⑹ 在【范圍】選項組中,可以選中【公有的】單選按鈕來創建一個公有過程,或者選中【私有的】單選按鈕來創建一個私有過程。在這里選中【私有的】單選按鈕,然后單擊【確定】按鈕。
⑺ 這樣就完成了一個函數過程的創建,但該函數過程并不能實現任何功能,而需要向函數過程中添加實現程序功能的代碼。


5.2.4 參數的傳遞
我們使用過程的目的就是將一些數據傳遞給過程,過程經過計算后將結果傳遞出來。在調用的過程中,必須考慮調用過程和被調用過程之間的數據調用方式。在Visual Basic中,使用參數來實現主調過程和被調過程間的數據傳遞。
1. 形參與實參
參數在Visual Basic中根據功能被分為形式參數和實際參數兩種。在編寫過程的時候,我們并不知道所要計算數據的真實值,因此使用參數代表這些值,當真正的數值作為參數傳遞進入過程后,再將參數值替換為實際值。在過程中代表真正需要計算的值的參數就是形式參數,之所以稱其為形式參數,是因為它僅僅是形式上代表真正需要計算的值。
⑴ 形式參數。形式參數(簡稱形參)是接收數據的變量。形式參數表中的各個變量之間用逗號分隔。形式參數表中的變量類型可以是合法的簡單變量,也可以是數組,但不能是定長字符串。
⑵ 實際參數。實際參數(簡稱實參)是指在調用子過程或函數過程時,傳遞給子過程或函數過程的常量、變量或表達式。實際參數表可以由常量、表達式、合法的變量名、數組等組成,實際參數表中的各參數用逗號分隔。
2. 按地址傳遞和按值傳遞
知道了形參和實參之間的關系,現在需要知道形參和實參之間是如何傳遞數據的。實參與形參之間的參數傳遞方式有兩種,即按地址傳遞和按值傳遞。
⑴ 按地址傳遞(By Reference)。所謂按地址傳遞參數,就是將實參的地址傳遞給相應的形參,形參與實參使用相同的內存地址單元,這樣通過調用被調程序就可以改變實參的值。在進行地址傳遞時,實參必須是變量,常量或表達式無法進行地址傳遞。按地址傳遞是Visual Basic中系統默認的參數傳遞方式。
⑵ 按值傳遞(By Value)。所謂按值傳遞,就是當實參是常量時,直接將常量值傳遞給形參變量;當實參是變量時,僅僅將實參變量的值傳遞給形參變量。然后執行被調過程,在被調過程中,即使對形參發生改變也不會影響實參值的變化。我們可以把按值傳遞給形參的變量看做實參的一個“副本”或者“鏡像”,就像鏡子中的我們一樣,雖然鏡子中的樣子和真人一模一樣,但是鏡子中的影像消失了并不會導致真人消失。
【范例5-3】 對整型變量進行初始化,然后調用按地址傳遞和按值傳遞的函數,再將變量傳遞后的結果輸出,比較按地址傳遞和按值傳遞的區別。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 在Form1窗體中添加兩個命令按鈕控件,將Command1命令按鈕的Caption屬性設置為“按地址傳遞”,將Command2命令按鈕的Caption屬性設置為“按值傳遞”。

⑶ 在Form1窗體中雙擊【按地址傳遞】按鈕,打開代碼窗口,輸入以下代碼(代碼5-3-1.txt)。
01 Private Sub Command1_Click() 02 Dim a As lnteger,b As lnteger 03 a=20 '為變量a賦初值 04 b=30 '為變量b賦初值 05 Print"按地址傳遞(初始):a=";a,"b=";b '輸出變量a和b的初始值 06 Call dizhisub(a,b) '調用名稱為dizhisub的子過程 07 Print"調用子過程結束以后:a=";a,"b=";b '輸出調用函數后的結果 08 Print"" '輸出空行 09 End Sub
⑷ 在Form1窗體中雙擊【按值傳遞】按鈕,打開代碼窗口,輸入以下代碼(代碼5-3-2.txt)。
01 Private Sub Command2_Click() 02 Dim a As lnteger,b As lnteger 03 a=20 '為變量a賦初值 04 b=30 '為變量b賦初值 05 Print"按值傳遞(初始):a=";a,"b=";b '輸出變量a和b的初始值 06 Call zhisub(a,b)'調用名稱為zhisub的子過程 07 Print"調用子過程結束以后:a=";a,"b=";b '輸出調用函數后的結果 08 Print"" '輸出空行 09 End Sub
⑸ 在代碼窗口中編寫dizhisub的子過程的代碼。
01 Private Sub dizhisub(m As lnteger,n As lnteger) 02 Print"調用按地址傳遞的子程序(初始):m=";m,"n=";n '輸出形參m和形參n的初始值 03 m=50 '為形參m重新賦值 04 n=100'為形參n重新賦值 05 Print"調用按地址傳遞的子程序(子程序賦值以后):m=";m,"n=";n '輸出形參的新值 06 End Sub
⑹ 在代碼窗口中編寫zhisub的子過程的代碼。
01 Private Sub zhisub(ByVal m,ByVal n) 02 Print"調用按值傳遞的子程序(初始):m=";m,"n=";n'輸出形參m和形參n的初始值 03 m=50 '為形參m重新賦值 04 n=100'為形參n重新賦值 05 Print"調用按值傳遞的子程序(子程序賦值以后):m=";m,"n=";n '輸出形參的新值 06 End Sub
【運行結果】
保存程序,按【F5】快捷鍵,運行程序。分別單擊【按地址傳遞】按鈕和【按值傳遞】按鈕,可以看到按地址傳遞和按值傳遞后數值的變化。

5.2.5 過程的嵌套與遞歸
在Visual Basic中,在一個過程中調用另外一個或其他若干個過程的方法稱為過程的嵌套調用,在過程中直接或間接地調用過程自身的方法則稱為過程的遞歸調用。
1. 過程的嵌套調用
在Visual Basic中,過程的定義都是相互平行獨立的,一個過程內不能包含另一個過程,在程序代碼中每一個過程之間都用一條分割線隔開。

雖然不能嵌套定義過程,但在Visual Basic中提供有嵌套調用過程的方法,也就是主程序可以調用子過程,在子過程中還可以調用另外的子過程,這種程序結構稱為過程的嵌套。
2. 過程的遞歸調用
遞歸調用的方法有兩種:直接遞歸和間接遞歸。
⑴ 直接遞歸。直接遞歸的實例代碼是:
Private Sub Sub1() '定義過程Sub1 … Call Sub1 '調用自身
… End Sub
⑵ 間接遞歸。間接遞歸的實例代碼是:
Private Sub SubA() '定義過程SubA … Call SubB '調用SubB … End Sub Private Sub SubB() '定義過程SubB … Call SubA '調用SubA … End Sub
【范例5-4】 定義一個計算平方根的子過程,并在子過程中調用自己,以實現對某個數進行平方根的運算。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 在窗體中添加兩個命令按鈕控件、兩個標簽控件和兩個文本框控件,將兩個文本框的Text屬性值設置為空,將兩個命令按鈕控件和兩個標簽控件的Caption屬性值按下表進行設置。

⑶ 將Form1窗體上的控件排列整齊,如圖所示。

⑷ 在Form1窗體中雙擊【計算】按鈕,打開代碼窗口,輸入以下代碼(代碼5-4-1.txt)。
01 Private Sub Command1_Click() 02 Dim x,x1,x2 As Single
03 x1=1 '為變量x1賦初值 04 x2=Val(Text1.Text) '為變量x2賦初值,并將其轉換成數值型 05 x=x2 '將變量x2的值賦給變量x 06 Call sqrt(x1,x2,x) '調用計算平方根的子過程 07 Text2.Text=x '將結果顯示在Text2中 08 End Sub
⑸ 在Form1窗體中雙擊【清除】按鈕,打開代碼窗口,輸入以下代碼。
01 Private Sub Command2_Click() 02 Text1.Text="" '清空文本框1中的內容 03 Text2.Text="" '清空文本框2中的內容 04 End Sub
⑹ 在代碼窗口中編寫sqrt的子過程(代碼5-4-2.txt)。
01 Private Sub sqrt(y1,y2,y) 02 Dim n As lnteger '定義變量n,用于記錄計算的次數 03 Dim y3 As Single '定義變量y3,用于接收計算后的值 04 Do While Abs(y1-y2)>0.000001 '判斷是否大于0.000001,小于則退出循環體 05 y3=(y1+y2)/2 '將傳遞后的y1與y2相加并對2求模 06 lf(y3*y3-y)<=0 Then '判斷平方根值是否小于等于零 07 y1=y3 '小于等于0則將平方根的值賦予y1 08 Else 09 y2=y3 '大于則將平方根的值賦予y2 10 End lf 11 n=n+1 '計算的次數加1 12 Loop 13 y=y1 '得到結果,賦值給形參 14 Print"經過"&n&"次計算,得到"&Text1.Text&"的平方根"'輸出最終結果 15 End Sub
【運行結果】
保存程序,按【F5】快捷鍵,運行程序。在【請輸入一個大于1的數】文本框中輸入數值“3”,單擊【計算】按鈕,結果如圖所示。

【拓展訓練5-3】
階乘運算的方法很多,在這里使用遞歸的方法進行一次階乘的運算。
⑴ 啟動Visual Basic 6.0,在彈出的【新建工程】對話框中選擇【標準EXE】圖標,然后單擊【打開】按鈕。
⑵ 在Form1窗體上添加一個命令按鈕控件。

⑶ 雙擊From1窗體上名稱為Commad1的命令按鈕控件,打開代碼窗口,輸入以下代碼(拓展代碼5-3-1.txt)。
01 Private Sub Command1_Click() 02 Dim s As Long '定義長整型變量,用于接收7的階乘值 03 Dim i As lnteger '定義整型變量,用于計數循環 04 s=0 '為變量s賦初值 05 For i=1 To 7 Step 1 '進行階乘運算循環 06 s=s+Factorial(i) '調用Factorial函數過程 07 Next i 08 Print"用遞歸方法求得1!+2!+…+7!的和為:";s '輸出最終的結果 09 End Sub
⑷ 在代碼窗口中編寫Factorial函數過程(拓展代碼5-3-2.txt)。
01 Public Function Factorial(ByVal n As lnteger)As Long 02 lf n=1 Then '如果接收到的數為1 03 Factorial=1 '返回1的階乘值 04 Else '否則遞歸調用函數過程 05 Factorial=Factorial(n-1)*n '返回值不為1的其他階乘值 06 End lf 07 End Function
⑸ 保存程序,按【F5】快捷鍵運行程序,單擊【Command1】命令按鈕,結果如圖所示。

5.3 高手點撥
本節視頻教學錄像:3分鐘
本章中有兩個問題,不但是本章難點,也是一些考試中常出現的問題,需要我們格外注意。
1. 確定自定義的過程是子過程還是函數過程
一般來說,函數過程名有值,子過程名無值。有一個返回值,則使用函數過程;有多個返回值或無返回值,一般使用子過程。
2. 實參與形參結合時對應問題
在使用實參與形成那對照時,要注意個數、類型、位置、次序的一一對應。
形參是按值傳遞,對應實參可以是表達式、常量、數組元素。
形參是按址傳遞,對應實參只能是簡單變量。
數組、記錄類型、對象只能是按地址傳遞。
5.4 實戰練習
一、思考題
1. 簡述調用Sub子過程與Function函數過程的區別是什么。
2. 參數傳遞有哪幾種,它們的區別是什么?
二、操作題
使用Function函數實現兩數平均值的計算。