講師:戴志華 hana@arbor.ee.ntu.edu.tw 國立台灣大學電機工程研究所 Visual Basic 程式設計 講師:戴志華 hana@arbor.ee.ntu.edu.tw 國立台灣大學電機工程研究所
第五章 副程式與函式 副程式 函式 傳值與傳址 遞迴 訊息對話盒
為什麼要有副程式? 程式中有許多重覆的動作 如下頁的例子 思考方向: 將某獨立、常重覆的部份發包出去 營養午餐與外叫便當的例子
為什麼要有副程式?(cont’d) * ** *** **** For i=1 to 8 If (i<=4) Then For j=1 to i Print “*”; Next j Else For j=1 to 9-i End if Print Next i For i=1 to 8 If (i<=4) Then >>畫i個*<< Else >>畫9-i個*<< End if Print Next i 化簡
副程式-Subroutine 在程式編輯器輸入 Private Sub printStar() [Private|Public|Static] Sub 副程式名 ([參數]) 程式碼 End Sub 在程式編輯器輸入 Private Sub printStar()
副程式-Subroutine(cont’d) 使用工具列 選擇程式編輯器,按Tool/Add Procedure
第一個副程式 VB會自動宣告num Private Sub printStar (num As Integer) Dim i As Integer For i=1 to num Print “*”; Next I Print End Sub For i=1 to 8 If (i<=4) Then 1.[printStar i] 2.[Call printStar(i)] Else 1.[printStar 9-i] 2.[Call printStar(9-i)] End if Print Next i 副程式呼叫方式: Call 副程式名(參數) 副程式名 參數
函式-Function 函式:有傳回值的副程式 [Private|Public|Static] Function 函式名 _ ([參數]) [As] 型別 程式碼 End Function VB會自動宣告一變數,其名稱為函式名 Private Function Add _ (x As Integer, y As Integer) As Integer Add=x+y End Function
函式-Function(cont’d) Private Function Add _ (x As Integer, y As Integer) As Integer Add=x+y End Function 結果是? Private Sub Form_Click() print Add(1,2) End Sub 把函式當副程式 Add 1,2 Call Add(1,2)
遞迴-Recursion 在函式,呼叫自己 要確定程式會停止 Private Function A() A() End Function Private Function Sum ( x As Integer) As Integer If (x=1) then Sum=1 Else Sum=Sum(x-1)+x End If End Function 初始值的設定很重要!!
遞迴-Recursion(cont’d) Sum(5)=Sum(4)+5 Sum(4)=Sum(3)+4 Sum(3)=Sum(2)+3 Sum(2)=Sum(1)+2 Sum(1)=1 Sum(2)=1+2 Sum(3)=1+2+3 Sum(4)=1+2+3+4 Sum(5)=1+2+3+4+5
費式數列-Fibonacci Series 0, 1, 1, 2, 3, 5, 8, …… 請問第100項為多少? 用迴圈 用遞迴 1 1 2 3 5 8
費式數列-使用迴圈 Private Function Fab(x As Integer) As Integer Dim a,b,i As Integer a=0 b=1 If (x=0 Or x=1) then Fab=x Else For i=2 to x Fab=a+b a=b b=Fab Next i End If End Function
費式數列-使用遞迴 Private Function Fab(x As Integer) As Integer If (x=0 Or x=1) then Fab=x Else Fab=Fab(x-2)+Fab(x-1) End If End Function
階乘 離開副程式與函式 Exit Sub Exit Function 5!=1*2*3*4*5 求某數的階乘 使用迴圈 使用遞迴 試試看
參數傳遞 [Option][ByVal|ByRef][ParamArray] 變數名[()] As 型別 [預設值] ByVal (By Value) 傳值 ByRef (By Reference) 傳址 預設值
傳值v.s.傳址 Private Sub Form_Click() Dim y As Integer y=100 Print “執行test前,y=”;y test y Print “執行test後,y=”;y End Sub Private Sub test([ByRef|ByVal] x As Integer) x=10
傳值v.s.傳址(cont’d) ByVal ByRef 100 10 x x 100 y 100 100 100 y y y x x
預設值 Private Sub Form_Click() test 100 test 10 test End Sub Private Sub test(Optional x As Integer=1) Print x
預設值(cont’d) 如果使用Optional模式,之後的變數都要給定預設值 Private Sub test(Optional x As Integer=10, _ Optional y As Integer=20) Print x+y*2 End Sub Private Sub Form_Click() test 5,10 test 5 test test y:=10 test x:=5 test y:=10,x:=5
不確定個數的參數 使用ParamArray VB會產生一個名為陣列名的陣列,其每個成員的型別為Variant Private Sub test(ParamArray 陣列名()) 程式碼 End Sub
不確定個數的參數(cont’d) Private Sub test (ParamArray items()) Dim i As Integer For i=LBound(items) to UBound(items) Print items(i) Next i End Sub Private Sub Form_Click() test 1,2,3,4,5 test “a”,“b”,“c”,“d”
不確定個數的參數(cont’d) 注意 使用ParamArray時,其陣列成員的型別為Variant 不可和Optional同時使用
訊息對話盒 MsgBox(訊息,[風格],[標題],[……]) 標題 訊息內容 圖示 按鈕
訊息對話盒(cont’d) 按鈕的風格 vbOKOnly 確定 vbOKCancel 1 確定、取消 vbAbortRetryIgnore 確定 vbOKCancel 1 確定、取消 vbAbortRetryIgnore 2 中止、重試、忽略 vbYesNoCancel 3 是、否、取消 vbYesNo 4 是、否 vbRetryCancel 5 重試、取消
訊息對話盒(cont’d) 圖示 對話盒形式 vbCritical 16 vbQuestion 32 vbExclamation 48 vbInformation 64 vbApplicationModal 應用程式等級 vbSystemModal 4096 系統等級 很少用
訊息對話盒(cont’d) 風格 以副程式的方式使用 以函式的方式使用 按鈕風格+圖示+對話盒形式 vbOK+vbInformation+vbApplicationModal 以副程式的方式使用 MsgBox “訊息”…… Call MsgBox(“訊息”……) 以函式的方式使用 MsgBox(“訊息”……) 內定值,可不打
訊息對話盒(cont’d) 由傳回值得知使用者按下那個鍵 vbOK 1 vbCancel 2 vbAbort 3 vbRetry 4 vbIgnore 5 vbYes 6 vbNo 7
輸入對話盒 InputBox(“訊息”,[“標題”],[“預設值”]……) 回傳值是使用者輸入的字串
輸入對話盒(cont’d) 按一下 沒輸入字串 有輸入字串
習題 寫一程式利用InputBox輸入學生的平常成績、期中考成績、期末考成績,假設平常成績佔40%、期中考成績與期末考成績各佔30%,然後算出其學期成績,並以MsgBox顯示出來。