9-1 模組化程式設計 9-2 建立程序與函數 9-3 傳值或傳址呼叫 9-4 程序與函數的變數範圍 9-5 常用的內建函數
9-1 模組化程式設計 目前應用程式或系統軟體的功能愈來愈強大, 從前一個人寫出的試算表程式, 幾個人開發的作業系統將成為神話, 模組化程式設計在應用程式開發上也就愈顯其重要性 9-1-1 模組的基礎 應用程式或系統軟體因為需要大量人員參與分析 設計與開發, 因此將一個大型應用程式的功能分割成一個個獨立的子功能, 就是一件非常重要的工作 模組化模組化是把大型功能切割成無數子功能, 至於如何切割成一個個子功能的 模組 (Modules), 這屬於結構化分析的範疇, 我們最常使用的是第 7 章的由上而下設計方法 (Top-down Design) 對應到程式設計, 模組化程式設計是將大程式切割成一個個小程式 以 Visual Basic 語言來說, 模組化的基本單位是程序與函數 (Functions), 因為模組可大可小, 可能只是單一程序或函數, 也可能是整個子功能的函數庫 不過, 每一個程序和函數都可以解決一個小問題, 等到所有小問題都解決了, 程序與函數組合的軟體就開發完成 程序與函數是一個黑盒子程序與函數是一個執行特定功能的程式區塊, 在呼叫時, 我們不用了解程序與函數內部實際的程式碼, 程序與函數如同是一個 黑盒子 (Black Box), 只要告訴我們如何使用此黑盒子的 使用介面 (Interface) 即可, 如下圖所示 : 9-2
上述圖例可以看出程式碼只知道呼叫程序或函數時, 需要傳入的參數和取得傳回值, 它是程序與函數和外部溝通的使用介面, 一個對外的邊界, 實際程式碼內容是隱藏在使用介面之後, 其實際內容的程式碼撰寫稱為 實作 (Implementation) 程序與函數的最大差異在於程序沒有傳回值 ; 而函數有傳回值 程序與函數的語法和語意說明, 如下所示 : 語法 (Syntax): 說明程序與函數需要傳入何種資料型態的 參數 (Parameters, 或稱引數 ) 和傳回值 ( 或稱回傳值 ) 語意 (Semantic): 指出程序與函數可以作什麼事? 換句話說, 在撰寫程序與函數時, 我們需要了解其語法規則, 呼叫程序與函數時需要了解其語意規則, 才能正確的呼叫程序與函數 9-1-2 再談由上而下設計方法 由上而下設計方法是一種循序漸進了解問題的方法, 它是在面對問題時先考慮將整個解決問題的方法分解成數個大模組, 然後針對每一個大模組, 一一分割成數個小模組, 如此一直細分, 直到細分的小問題建立的模組完成後, 再將它們組合起來, 一層層的向上爬來完成整個應用程式或系統軟體的設計 例如 : 玩拼圖遊戲一定先將整個拼圖粗分為數個區域, 等每一個區域都拼好後, 整張拼圖也就完成了 現在, 筆者準備直接使用房屋繪圖來說明如何分割工作, 如下圖所示 : 上述圖例左邊的房屋圖形可以分割成多個小工作來分別繪製, 換句話說, 我們可以使用由上而下設計方法來完成整個繪圖工作 9-3
分割繪出房屋圖形工作整個房屋的繪圖工作可以粗分成三個子工作, 如下所示 : (1) 繪出屋頂和外框 (2) 繪出窗戶 (3) 繪出門 依據上述工作的分割建立各問題之間的模組架構, 如下圖所示 : 在上述圖例的 主程式 分別呼叫這些模組, 其虛擬碼如下所示 : Call Draw Outline Call Draw Windows Call Draw Door 分割繪出屋頂和外框子工作針對第一個子工作 繪出屋頂和外框 (Draw Outline), 我們可以再次進行分割, 分割成二個下一層的孫工作, 如下所示 : (1) 繪出屋頂 (2) 繪出房屋的外框 依據上述分割建立下一層問題之間的模組架構, 如下圖所示 : 9-4
上述圖例的 繪出屋頂和外框 (Draw Outline) 模組是依序呼叫其下的 2 個模組, 其虛擬碼如下所示 : Call Draw Roof Call Draw House Frame 現在, 我們只需重複上述分析, 繼續一步一步向下進行工作的分割, 例如 : 窗戶有 2 個, 繪出窗戶 可以分為 繪出窗戶 1 和 繪出窗戶 2 ; 繪出門 可以分為 繪出門框 和 繪出門把 最後, 將問題分割成一個個小問題後, 每一個小問題就是一個 Visual Basic 語言的程序或函數, 只需完成這些程序與函數即可解決整個房屋繪圖的問題 9-2 建立程序與函數 程序與函數可以將程式中, 一些常用的共同程式碼獨立成程式區塊, 也就是建立結構化程式設計的模組 在 Visual Basic 語言的程序可以分為兩種, 如下所示 : 事件處理程序 : 事件處理程序是處理指定事件的程序 ( 一定是 Sub, 因為不會有傳回值 ), 在本章前的 Windows 應用程式已經使用 Click 事件處理程序, 關於事件的進一步說明請參閱第 11 章 一般程序或函數 : 將程式區塊使用一個程序或函數名稱來代替, 以便程式可以重複呼叫程序與函數來執行特定功能 Visual Basic 語言的程序分為 Sub 程序和 Function 函數兩種 9-2-1 建立程序與函數 Visual Basic 語言的程序是使用 Sub 和 End Sub 包圍的程式區塊, 在 Sub 關鍵字後是程序名稱, 程序沒有傳回值 Function 函數類似 Sub 程序只是改為 Function 和 End Function 包圍, 其主要差異是函數有傳回值 9-5
程序的建立與呼叫在 Visual Basic 語言建立程序的語法, 如下所示 : [Public Private] Sub 名稱程式區塊 End Sub 上述 Sub 指令前的 Public 或 Private 是存取修飾子 Public 是公用程序, 即在專案中的所有程式檔案都可以呼叫 Private 只允許在同一個程式檔案進行呼叫 如果沒有指定, 預設是 Public 程序名稱的命名和變數名稱相同 例如 : 顯示提示字串的 ShowPrompt() 程序, 如下所示 : Sub ShowPrompt() Dim msg As String msg = "50 元 : " lbloutput.text = msg End Sub 上述 Sub/End Sub 是一個程式區塊, 且沒有傳回值 在程式碼呼叫程序是使用 Call 關鍵字, 然後在其後加上程序名稱, 如下所示 : Call ShowPrompt() 上述程序呼叫因為程序沒有參數, 可以省略括號 不使用 Call 關鍵字也可以, 如下所示 : ShowPrompt 上述程式碼也可以呼叫 ShowPrompt() 程序 函數的建立與呼叫在 Visual Basic 語言建立函數的語法, 如下所示 : [Public Private] Function 函數名稱 [As 資料型態 ] 程式區塊 Return 值 函數名稱 = 值 End Function 9-6
上述 Function 函數和 Sub 程序十分相似,As 之後是傳回值的資料型態 函數傳回值是使用 Return 關鍵字來傳回, 或將函數名稱指定成需要傳回的值 例如 : 將台幣現鈔換成 50 元零錢的 ReturnChange() 函數, 如下所示 : Function ReturnChange() Dim Amount As Integer Amount = CInt(txtAmount.Text) Dim Change As Integer = 0 Do While Amount >= 50 Amount = Amount - 50 Change = Change + 1 Loop Return Change End Function 上述 ReturnChange() 函數傳回可以換成幾個 50 元硬幣, 使用 Return 傳回計算結果 傳回值也可以將函數名稱指定成傳回值, 如下所示 : ReturnChange = Change 上述程式碼也可以指定函數的傳回值 函數因為有傳回值, 通常都是在指定敘述的右邊呼叫函數, 如下所示 : lbloutput.text &= ReturnChange() 上述程式碼將 lbloutput 標籤控制項的 Text 屬性指定成函數的傳回值 範例專案 Ch9-2-1\ 換零錢機 在 Windows 應用程式使用 TextBox 控制項輸入兌換金額後, 呼叫程序與函數顯示與計算可換成幾個 50 元硬幣的零錢, 其執行結果如下圖所示 : 在上方輸入金額後, 按 換零錢 鈕, 可以在下方看到可換成 7 個 50 元硬幣的零錢, 不過, 如果金額沒有完全兌換完, 程式並不會計算和顯示剩下多少錢 9-7
表單設計工具請建立 Windows Form 專案 換零錢機 且開啟表單 Form1( 檔案名稱為 Form1.vb), 然後在表單設計工具新增 Label TextBox 和 Button 控制項, 其建立步驟如下所示 : 選表單 Form1 後, 在 屬性 視窗更改 Text 屬性值為 換零錢機, Size 屬性值為 300, 150 在表單新增 金額 : 的 Label 控制項後, 即可在之後新增名為 txtamount 的 TextBox 控制項, Text 屬性值為 350 在右邊新增名為 換零錢 的 Button 控制項, 如下圖所示 : Label Button TextBox 在下方新增黑底白字的 Label 標籤控制項, 在 屬性 視窗更改的相關屬性值, 如下表所示 : 屬性 值 Name AutoSize BorderStyle BackColor ForeColor lbloutput False FixedSingle ControlText Control Font-Size 10 TextAlign MiddleCenter 9-8
在清除 Label 控制項的 Text 屬性值後, 就完成使用介面的建立, 如下圖所示 : Label 程式碼編輯器 在表單設計工具按二下名為 換零錢 的 Button 按鈕控制項, 可以建立 Button1_Click() 事件處理程序, 和 ShowPrompt() 程序與 ReturnChange() 函數 01: Sub ShowPrompt() 02: Dim msg As String 03: msg = "50 元 : " 04: lbloutput.text = msg 05: End Sub 06: 07: Function ReturnChange() 08: Dim Amount As Integer 09: Amount = CInt(txtAmount.Text) 10: Dim Change As Integer = 0 ' 計算零錢數 11: ' 換零錢的迴圈 12: Do While Amount >= 50 13: Amount = Amount - 50 ' 每次減 50 元 14: Change = Change + 1 15: Loop 16: Return Change 17: End Function 18: 19: Private Sub Button1_Click(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles Button1.Click 20: Call ShowPrompt() ' 呼叫程序 21: lbloutput.text &= ReturnChange() ' 呼叫函數 22: End Sub 9-9
程式碼解說第 1~5 列 :ShowPrompt() 程序可以在 Label 標籤控制項顯示一段提示文字 第 7~17 列 :ReturnChange() 函數可以換零錢, 在第 9 列取得使用者輸入的金額後, 使用第 12~15 列的 Do While/Loop 迴圈計算可兌換的零錢數, 在第 16 列使用 Return 關鍵字傳回兌換個數 第 20~21 列 : 分別呼叫 ShowPrompt() 程序和 ReturnChange() 函數 程序與函數的執行過程 Visual Basic 程式是如何執行程序與函數, 以本節範例專案為例, 程式是在 Button1_Click() 事件處理程序的第 20 列呼叫 ShowPrompt() 程序, 此時程式碼執行順序跳到此程序的第 1 列, 在執行完第 5 列後返回呼叫點, 如下圖所示 : 然後繼續執行程式, 在第 21 列呼叫 ReturnChange() 函數, 程式碼跳到此函數的第 7 列, 在執行完第 17 列返回呼叫點的 Button1_Click() 事件處理程序, 即可完成整個程式的執行 事實上! 程序與函數只是更改程式碼的執行順序, 在呼叫點跳到程序或函數來執行, 在執行完後, 回到程式的呼叫點繼續執行其他的程式碼 9-2-2 擁有參數的程序與函數 程序與函數可以在程序與函數加上參數, 當呼叫時傳入不同的參數值後, 相同的程序與函數也可以得到不同的執行結果 9-10
建立擁有參數的程序與函數在 Visual Basic 語言建立擁有參數的程序與函數, 其語法如下所示 : [Public Private] [Sub Function] 名稱 ( 參數 1, 參數 2, ) 程式區塊 [Return 值 名稱 = 值 ] End [Sub Function] 上述括號的參數稱為 正式參數 (Formal Parameters) 或 假的參數 (Dummy Parameters) 正式參數是識別字, 其角色如同變數, 需要指定資料型態, 而且可以在程式區塊中使用 例如 : 顯示提示字串的 ShowPrompt() 程序擁有 1 個參數, 如下所示 : Sub ShowPrompt(msg As String) lbloutput.text = msg End Sub 上述程序擁有一個參數 擁有參數的函數, 例如 : 換零錢函數 ReturnChange() 擁有 2 個參數, 如下所示 : Function ReturnChange(Amount As Integer, Unit As Integer) Dim Change As Integer = 0 Do While Amount >= Unit Amount = Amount - Unit Change = Change + 1 Loop Return Change End Function 上述 ReturnChange() 函數擁有 2 個參數, 第 1 個是金額, 第 2 個是零錢單位, 因為參數不只一個, 所以使用, 逗號分隔 此函數可以將參數金額兌換成指定單位的零錢 在 ReturnChange() 函數因為擁有參數, 所以不只可以兌換 50 元硬幣, 只需輸入不同單位的參數, 我們一樣可以兌換成其他不同種類的零錢, 例如 :10 元或 5 元硬幣 9-11
呼叫擁有參數的程序與函數程序與函數如果擁有參數, 在呼叫時可以指定不同的參數值 因為 ShowPrompt() 程序擁有參數, 所以呼叫時需要指定參數值, 如下所示 : Call ShowPrompt(" 可兌換數 : ") 上述程序呼叫的括號中有指定參數值 擁有參數的函數呼叫, 如下所示 : lbloutput.text &= ReturnChange(Amount, Unit) 上述程式碼呼叫函數來兌換零錢, 參數是 2 個變數值, 其傳回值是顯示在 Label 標籤控制項 在呼叫程序與函數時的參數稱為 實際參數 (Actual Parameters), 即傳入的參數值, 需要和正式參數定義的資料型態相同, 每一個正式參數都需對應相同型態的實際參數 範例專案 Ch9-2-2\ 換零錢機 這個 Windows 應用程式是修改第 9-2-1 節的 換零錢機, 改為使用擁有參數的程序與函數來兌換零錢, 表單新增 TextBox 控制項輸入零錢的單位, 其執行結果如下圖所示 : 在上方輸入金額和零錢單位後, 按 換零錢 鈕, 可以在下方看到計算結果的零錢數, 以此例是 88 個 5 元硬幣, 前面字串是 ShowPrompt() 程序顯示的提示文字 9-12
表單設計工具請建立 Windows Form 專案 換零錢機, 這是直接複製和貼上第 9-2-1 節範例專案資料夾, 然後新增輸入單位的 Label 和 TextBox 控制項來修改使用介面, 其建立步驟如下所示 : 請在 方案總管 視窗按二下 Form1.vb 開啟表單設計工具 選表單 Form1 後, 在 屬性 視窗更改 Size 屬性值為 300, 200, 並且調整 lbloutput 標籤控制項的尺寸和位置, 即向下方拖拉空出中間部分的編輯區域 在空出的編輯區域新增 零錢單位 : 的 Label 控制項後, 在之後新增名為 txtunit 的 TextBox 控制項, Text 屬性值為 10 如下圖所示: Label TextBox 程式碼編輯器 在表單設計工具按二下名為 換零錢 的 Button 按鈕控制項, 可以修改 Button1_Click() 事件處理程序 ShowPromt() 程序和 ReturnChange() 函數 01: Sub ShowPrompt(ByVal msg As String) 02: lbloutput.text = msg 03: End Sub 04: 05: Function ReturnChange(ByVal Amount As Integer, _ ByVal Unit As Integer) 06: Dim Change As Integer = 0 ' 計算零錢數 07: ' 換零錢的迴圈 08: Do While Amount >= Unit 9-13
09: Amount = Amount - Unit ' 每次減一單位 10: Change = Change + 1 11: Loop 12: Return Change 13: End Function 14: 15: Private Sub Button1_Click(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles Button1.Click 16: Dim Amount, Unit As Integer 17: Amount = CInt(txtAmount.Text) 18: Unit = CInt(txtUnit.Text) 19: Call ShowPrompt(" 可兌換數 :") ' 呼叫程序 20: lbloutput.text &=ReturnChange(Amount, Unit)' 呼叫函數 21: End Sub 程式碼解說第 1~3 列 :ShowPrompt() 程序擁有一個 String 型態的參數 msg, 前方 ByVal 關鍵字指出參數是傳值參數, 這是 Visual Basic 語言預設的參數傳遞方式, 在 VBE 輸入程序或函數的參數時, 如果沒有指明就會自動加上 ByVal, 其進一步說明請參閱第 9-3 節 第 5~13 列 :ReturnChange() 函數擁有 2 個 Integer 資料型態的參數, 在第 8~11 列的迴圈計算可兌換多少零錢, 在第 12 列使用 Return 關鍵字傳回兌換個數 第 15~21 列 :Button1_Click() 事件處理程序是在第 17~18 列取得使用者輸入的金額與單位, 第 19~20 列分別呼叫 ShowPrompt() 程序和 ReturnChange() 函數計算與顯示兌換的零錢數 9-2-3 強迫跳出程序與函數 在執行程序或函數時如果需要中斷程序或函數的執行, 此時可以使用 Exit Sub 跳出程序 ;Exit Function 中斷函數的執行, 即跳出函數 例如 : 換零錢的 ReturnChange() 函數, 如下所示 : 9-14 Function ReturnChange(Amount As Integer, Unit As Integer) Dim Change As Integer = 0 Do While True Amount = Amount - Unit If Amount >= 0 Then Change = Change + 1
Else Return Change Exit Function End If Loop End Function 上述函數使用 Do While/Loop 無窮迴圈來兌換零錢, 當金額小於 0 時, 表示金額已經兌換完, 所以使用 Exit Function 中斷函數的執行 ( 即中斷 Do While/Loop 迴圈 ) 不過,ReturnChange() 函數只能傳回兌換成的零錢數, 如果有小於零錢數的餘額, 函數並不會傳回, 這部分處理需要使用函數的傳址參數, 進一步說明請參閱第 9-3 節 範例專案 Ch9-2-3\ 換零錢機 這個 Windows 應用程式是修改第 9-2-2 節的 換零錢機, 改為使用 RadioButton 選項按鈕選擇零錢種類, 在 ReturnChange() 函數的迴圈改用 Exit Function 來兌換零錢, 其執行結果如下圖所示 : 在上方輸入金額和選擇種類後, 按 換零錢 鈕, 可以在下方看到可換成幾個選擇種類的零錢和還剩下多少錢 表單設計工具請建立 Windows Form 專案 換零錢機, 這是直接複製和貼上第 9-2-2 節範例專案資料夾, 然後新增選擇零錢種類的 GroupBox 和 3 個 RadioButton 控制項來修改使用介面, 其建立步驟如下所示 : 9-15
請在 方案總管 視窗按二下 Form1.vb 開啟表單設計工具, 選表單 Form1 後, 刪除 零錢單位 : 的 Label 控制項和之後名為 txtunit 的 TextBox 控制項 在空出的編輯區域新增 GroupBox 控制項, 其 Text 屬性為 種類 後, 新增 3 個 RadioButton 控制項來選擇零錢種類有 50 10 和 5 元三種, 如下圖所示 : GroupBox 上述 3 個 RadionButton 控制項在 屬性 視窗更改的屬性值, 如下表所示 : 控制項種類 Name 屬性 Text 屬性 Checked 屬性 選項按鈕 rdb50 50 元 True 選項按鈕 rdb10 10 元 False 選項按鈕 rdb5 5 元 False 程式碼編輯器 在表單設計工具按二下名為 換零錢 的 Button 按鈕控制項, 可以刪除 ShowPrompt() 程序, 和修改 Button1_Click() 事件處理程序和 ReturnChange() 函數 01: Function ReturnChange(ByVal Amount As Integer, _ ByVal Unit As Integer) 02: Dim Change As Integer = 0 03: Do While True ' 無窮迴圈 04: Amount = Amount - Unit 05: If Amount >= 0 Then 06: Change = Change + 1 07: Else 08: Return Change 9-16
09: Exit Function ' 跳出函數 10: End If 11: Loop 12: End Function 13: 14: Private Sub Button1_Click(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles Button1.Click 15: Dim Amount As Integer = CInt(txtAmount.Text) 16: Dim Change, Type As Integer 17: ' 選擇零錢種類 18: If rdb50.checked Then 19: Change = ReturnChange(Amount, 50) ' 呼叫函數 20: Type = 50 21: End If 22: If rdb10.checked Then 23: Change = ReturnChange(Amount, 10) ' 呼叫函數 24: Type = 10 25: End If 26: If rdb5.checked Then 27: Change = ReturnChange(Amount, 5) ' 呼叫函數 28: Type = 5 29: End If 30: lbloutput.text=type & " 元 : " & Change & " 個 " & vbnewline 31: ' 計算剩下多少錢 32: lbloutput.text &=" 剩下 : " & (Amount-Type*Change) & " 元 " 33: End Sub 程式碼解說第 1~12 列 :ReturnChange() 函數可以計算兌換成幾個零錢, 第 3~11 列是 Do While/Loop 無窮迴圈, 每執行一次迴圈, 就在第 4 列將金額減去零錢單位, 即換一個零錢, 第 5~10 列的 If Then/Else 條件判斷是否兌換完, 如果是, 在第 9 列使用 Exit Function 跳出函數 第 14~33 列 :Button1_Click() 事件處理程序在第 15 列取得兌換金額, 第 18~29 列的 3 個 If Then 條件判斷兌換哪一種零錢, 以便呼叫 ReturnChange() 函數計算兌換個數, 在第 32 列計算換剩下的金額 9-17
9-3 傳值或傳址呼叫 程序與函數不同的參數傳遞方式可以影響傳入參數的變數值 Visual Basic 語言提供兩種參數傳遞方式, 如下表所示 : 呼叫方式關鍵字說明 傳值呼叫 ByVal 將變數的值傳入程序或函數, 並不會變更原變數的值 傳址呼叫 ByRef 將變數實際記憶體儲存位址傳入, 所以在程序與函數變更參數的變數值, 也會同時更改原變數值 在 Visual Basic 程序與函數預設是使用傳值呼叫, 如果沒有指明,VBE 程式碼編輯器會自動加上 ByVal, 如下所示 : Sub SubByVal(ByVal P As Integer).. End Sub 事實上, 只有傳址程序或函數才需要指名 ByRef, 如下所示 : Sub SubByRef(ByRef P As Integer). End Sub 範例專案 Ch9-3\ 換零錢機 這個 Windows 應用程式是修改第 9-2-3 節的 換零錢機, 只是將 ReturnChange() 函數改為使用整數除法和餘數來計算, 並且使用傳址呼叫傳回剩下的金額, 其執行結果如下圖所示 : 9-18
在上方輸入金額和選擇種類後, 按 換零錢 鈕, 可以在下方顯示共兌換成幾個選擇種類的零錢和剩下多少錢 表單設計工具請建立 Windows Form 專案 換零錢機, 這是直接複製和貼上第 9-2-3 節範例專案資料夾, 其步驟如下所示 : 請在 方案總管 視窗按二下 Form1.vb 開啟表單設計工具, 如下圖所示 : 程式碼編輯器 在表單設計工具按二下名為 換零錢 的 Button 按鈕控制項, 可以修改 Button1_Click() 事件處理程序和 ReturnChange() 函數 01: Function ReturnChange(ByRef Amount As Integer, _ ByVal Unit As Integer) 02: Dim Change As Integer 03: Change = Amount \ Unit ' 整數除法 04: Amount = Amount Mod Unit ' 餘數 05: Return Change 06: End Function 07: 08: Private Sub Button1_Click(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles Button1.Click 09: Dim Amount As Integer = CInt(txtAmount.Text) 10: Dim Change As Integer 11: ' 選擇零錢種類 12: If rdb50.checked Then 13: Change = ReturnChange(Amount, 50) ' 呼叫函數 14: lbloutput.text = "50 元 " 9-19
15: End If 16: If rdb10.checked Then 17: Change = ReturnChange(Amount, 10) ' 呼叫函數 18: lbloutput.text = "10 元 " 19: End If 20: If rdb5.checked Then 21: Change = ReturnChange(Amount, 5) ' 呼叫函數 22: lbloutput.text = "5 元 " 23: End If 24: lbloutput.text &= Change & " 個 " & vbnewline 25: lbloutput.text &= " 剩下 : " & Amount & " 元 " 26: End Sub 程式碼解說第 1~6 列 :ReturnChange() 函數的第 1 個參數是傳址呼叫 ; 第 2 個是傳值呼叫, 在第 3~4 列使用整數除法和餘數運算來兌換零錢 第 8~26 列 :Button1_Click() 事件處理程序在第 9 列取得兌換金額, 第 12~23 列的 3 個 If Then 條件判斷兌換哪一種零錢, 以便呼叫 ReturnChange() 函數計算兌換個數, 參數 Amount 在呼叫後, 就是剩下的金額 9-4 程序與函數的變數範圍 Visual Basic 程式檔案可以同時建立多個程序或函數, 在不同位置宣告的變數都擁有不同的有效範圍, 也就是在程式區塊的哪些程式碼可以存取這些變數 變數範圍 (Scope) 是當程式執行時, 變數可以讓程序與函數內或其他程式區塊存取的範圍 在 Visual Basic 模組或類別中, 變數依宣告位置擁有三種範圍, 如下所示 : 區塊範圍 (Block Scope): 在 If/End If Select Case/End Case 和 Do While/Loop 等程式區塊內使用 Dim 宣告的變數, 變數只能在區塊之內使用, 區塊之外的程式碼並無法存取這些變數 區域範圍 (Local Scope): 在程序與函數內使用 Dim 宣告的變數, 變數只能在程序或函數內使用, 程序或函數外程式碼並無法存取此變數, 稱為 區域變數 (Local Variables) 9-20
全域範圍 (Global Scope): 變數如果是在模組 / 類別的 Module/ End Module 和 Class/End Class 中, 以 Dim 或 Private 宣告在程序和函數外, 該模組 / 類別檔案的程序和函數都可以存取此變數, 稱為 全域變數 (Global Variables) 筆者已經將上述變數範圍整理成圖形表示, 如下圖所示 : 不只如此, 全域變數如果使用 Public 宣告, 整個 Visual Basic 專案的所有模組 / 類別檔案都可以存取此變數, 屬於模組等級的全域變數 範例專案 Ch9-4\ 換零錢機 這個 Windows 應用程式是修改和擴充第 9-3 節的 換零錢機, 改用 CheckBox 控制項勾選想兌換的硬幣種類, 程式可以計算可兌換成幾個 50 元硬幣 幾個 20 元 幾個 10 元 5 元和 1 元硬幣, 其執行結果如下圖所示 : 在上方輸入兌換金額, 勾選需要兌換的硬幣種類後, 按 換零錢 鈕, 可以在下方看到各種硬幣的兌換數量 9-21