Transcript 下載/瀏覽
第9章 程序與函數
[換零錢程式]
9-1 模組化程式設計
9-2 建立程序與函數
9-3 傳值或傳址呼叫
9-4 程序與函數的變數範圍
9-5 常用的內建函數
9-1 模組化程式設計
9-1-1 模組的基礎
9-1-2 程序與函數是一個黑盒子
9-1-1 模組的基礎
模組化是把大型功能切割成無數子功能,至於如
何切割成一個個子功能的模組(相當於是Visual
Basic模組),屬於結構化分析的範疇,我們最常
使用的是第7章的由上而下設計方法。
以Visual Basic語言來說,模組化的基本單位是程
序與函數,因為模組可大可小,可能只擁有單一
程序或函數,也可能是整個子功能的函式庫。不
過,每一個程序和函數都可以解決一個小問題,
等到所有小問題都解決了,使用程序與函數堆積
成的軟體系統或應用程式也就開發完成。
9-1-2 程序與函數是一個黑盒子-說
明
程序與函數是一個執行特定功能的程式區塊,執
行程序與函數稱為函數呼叫(Functions Call),
擁有傳回值的程序稱為「函數」(Functions)。
在呼叫時,我們並不需要了解程序與函數內部實
際的程式碼,程序與函數如同是一個「黑盒子」
(Black Box),只要告訴我們如何使用黑盒子的
「使用介面」(Interface)即可,如下圖所示:
9-1-2 程序與函數是一個黑盒子-規
則
當我們使用程式語言撰寫程序與函數時,
有一些規則可供參考,如下所示:
程序與函數的使用介面需要直接、良好定義和
容易了解。
在呼叫程序與函數時,並不需要知道任何有關
內部實作的問題,唯一需要知道的是如何使用
它的使用介面。
在實作程序與函數時,並不用考量或知道到底
是誰需要使用它,只需滿足使用介面定義的輸
入參數和傳回值即可。
9-1-2 程序與函數是一個黑盒子-語
法與語意
程序與函數的「語法」(Syntax)是說明
程序與函數需要傳入何種資料型態的「參
數」(Parameters)和傳回值。
「語意」(Semantic)是指出程序與函數
可以作什麼事?換句話說,在撰寫程序與
函數時,需要了解其語法規則,而在呼叫
程序與函數時需要了解其語意規則,如此
才能正確呼叫程序與函數。
9-2 建立程序與函數
9-2-1 建立程序與函數
ViLLE – 4.1 建立程序與函數
9-2-2 擁有參數的程序與函數
ViLLE – 4.2 擁有參數的程序與函數
9-2-3 強迫跳出程序與函數
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-2-1 建立程序與函數-建立程序
(語法)
在Visual Basic語言建立程序的基本語法,
如下所示:
[Public | Private] Sub 名稱
程式區塊
End Sub
上述Sub指令前的Public或Private是存取修
飾子。
Public是公用程序,即在專案中的所有程式檔
案都可以呼叫。
Private只允許在同一個程式檔案進行呼叫。如
果沒有指定,預設是Public。
9-2-1 建立程序與函數-建立程序
(範例)
例如:顯示提示字串的ShowPrompt()程序,
如下所示:
Sub ShowPrompt()
Dim msg As String
msg = "50元: "
lblOutput.Text = msg
End Sub
上述程式碼是ShowPrompt()程序,並沒有
傳回值。
9-2-1 建立程序與函數-呼叫程序
在程式碼呼叫程序是使用Call指令,只需在
其後加上程序名稱即可,如下所示:
Call ShowPrompt()
上述程序呼叫因為程序沒有參數,可以省
略括號,而且不使用Call關鍵字也可以,如
下所示:
ShowPrompt
9-2-1 建立程序與函數-建立函數
(語法)
在Visual Basic語言建立函數的基本語法,如下所
示:
[Public | Private] Function 函數名稱 [As 資料型
態]
程式區塊
Return 值 | 函數名稱 = 值
End Function
Function函數和Sub程序十分相似,As之後是傳
回值的資料型態。函數傳回值是使用Return關鍵
字來傳回,或將函數名稱指定成需要傳回的值。
9-2-1 建立程序與函數-建立函數
(範例)
例如:將台幣現鈔換成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
9-2-1 建立程序與函數-呼叫函數
函數因為擁有傳回值,通常都是在指定敘
述來呼叫函數,而且是位在指定敘述的右
邊,如下所示:
lblOutput.Text &= ReturnChange()
9-2-1 建立程序與函數-Visual Basic
專案
Visual Basic專案:Ch9-2-1\換零錢程式
在Windows應用程式使用TextBox控制項輸
入兌換金額後,呼叫程序與函數來顯示與
計算可以換成幾個50元硬幣的零錢。其執
行結果如下圖所示:
9-2-1 建立程序與函數-程序與函數
的執行過程
Visual Basic程式是如何執行程序與函數,以本節
的範例為例,如下圖所示:
ViLLE – 4.1 建立程序與函數
請啟動ViLLE,在【四. 程序與函數】目錄下,選
【1. 建立程序與函數】,按【Run】鈕模擬執行
此範例程式,如下圖所示:
9-2-2 擁有參數的程序與函數-說明
程序與函數不只可以單純將重複程式區塊
抽出成獨立區塊,我們還可以在程序與函
數加上參數。
在呼叫時傳入參數值後,相同的程序與函
數就可以得到不同的執行結果。
9-2-2 擁有參數的程序與函數-語法
在Visual Basic語言建立擁有參數的程序與函數,
其語法如下所示:
[Public | Private] [Sub | Function] 名稱(參數1, 參
數2, …)
程式區塊
[Return 值 | 名稱 = 值]
End [Sub | Function]
括號的參數稱為「正式參數」(Formal
Parameters)或「假的參數」(Dummy
Parameters)。正式參數是識別字,其角色如同
變數,需要指定資料型態,而且可以在程式區塊
中使用。
9-2-2 擁有參數的程序與函數-範例1
例如:顯示提示字串的ShowPrompt()程序
擁有1個參數,如下所示:
Sub ShowPrompt(msg As String)
lblOutput.Text = msg
End Sub
上述程序擁有一個參數。
9-2-2 擁有參數的程序與函數-範例2
例如:新增參數的換零錢函數
ReturnChange(),如下所示:
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
9-2-2 擁有參數的程序與函數-呼叫
程序與函數如果擁有參數,在呼叫時可以
指定不同的參數值。因為新版
ShowPrompt()程序擁有參數,所以在呼叫
時需指定參數值,如下所示:
Call ShowPrompt("50元: ")
上述程序呼叫的括號中就是指定的參數值。
擁有參數的函數呼叫,如下所示:
lblOutput.Text &= ReturnChange(Amount, Unit)
9-2-2 擁有參數的程序與函數-實際
參數
在呼叫程序與函數時的參數稱為「實際參
數」(Actual Parameters),這就是參數
值,需要和正式參數定義的資料型態相同。
換句話說,每一個正式參數都需對應同型
態的實際參數。
9-2-2 擁有參數的程序與函數-Visual
Basic專案
Visual Basic專案:Ch9-2-2\換零錢程式
這個Windows應用程式是修改第9-2-1節的【換零
錢程式】,改為使用擁有參數的程序與函數來換
零錢,並且在表單新增TextBox控制項來輸入零錢
的單位。其執行結果如下圖所示:
ViLLE – 4.2 擁有參數的程序與函數
請啟動ViLLE,在【四. 程序與函數】目錄下,選
【2. 擁有參數的程序與函數】,按【Run】鈕模
擬執行此範例程式,如下圖所示:
9-2-3 強迫跳出程序與函數-說明
在執行程序或函數時如果需要中斷程序或
函數的執行,此時可以使用Exit Sub跳出程
序;Exit Function中斷函數的執行,即跳出
函數。
9-2-3 強迫跳出程序與函數-範例
例如:換零錢的ReturnChange()函數,如下所示:
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
9-2-3 強迫跳出程序與函數-Visual Basic
專案
Visual Basic專案:Ch9-2-3\換零錢程式
這個Windows應用程式是修改第9-2-2節的【換零
錢程式】,改為使用RadioButton選項按鈕來選擇
零錢種類,在ReturnChange()函數的迴圈則改用
Exit Function敘述來兌換零錢。其執行結果如下
圖所示:
9-3 傳值或傳址呼叫-說明
程序與函數不只能夠傳遞參數,不同的參
數傳遞方式更影響傳入參數的變數值。
Visual Basic語言提供兩種參數傳遞方式,
如下表所示:
呼叫方式 關鍵字
說明
傳值呼叫 ByVal 將變數的值傳入程序或函數,並不會變更原變數的值
傳址呼叫 ByRef 將變數實際記憶體儲存的位址傳入,所以在程序與函數
如果變更參數的變數值,也會同時更改變數值
9-3 傳值或傳址呼叫-使用
在Visual Basic程序與函數預設使用傳值呼
叫,如果沒有指明,VBE的程式碼編輯器
自動會加上ByVal,如下所示:
Sub SubByVal(ByVal P As Integer)
…..
End Sub
事實上,只有傳址的程序或函數才需要特
別指名ByRef,如下所示:
Sub SubByRef(ByRef P As Integer)
….
End Sub
9-3 傳值或傳址呼叫-Visual Basic專
案
Visual Basic專案:Ch9-3\換零錢程式
這個Windows應用程式是修改第9-2-3節的【換零
錢程式】,只是將ReturnChange()函數改為使用
整數除法和餘數來計算,並且使用傳址呼叫來傳
回剩下的金額。其執行結果如下圖所示:
9-4 程序與函數的變數範圍-說明
在Visual Basic程式檔案可以同時建立多個
程序或函數,不同位置宣告的變數都擁有
不同的有效範圍,也就是只能在指定程式
區塊的程式碼來存取這些變數。
「變數範圍」(Scope)是當程式執行時,
變數可以讓程序或函數內或其他程式區塊
存取的範圍。
9-4 程序與函數的變數範圍-種類
區塊範圍(Block Scope):在If/End If、Select
Case/End Case和Do While/Loop等程式區塊內使
用Dim宣告的變數,變數只能在區塊內使用,在
區塊外的程式碼並無法存取這些變數。
區域範圍(Local Scope):在程序與函數內使用
Dim宣告的變數,變數只能在程序或函數內使用,
程序或函數外程式碼並無法存取此變數,稱為
「區域變數」(Local Variables)。
全域範圍(Global Scope):變數如果是在模組/
類別的Module/ End Module和Class/End Class中,
以Dim或Private宣告在程序和函數外,則該模組/
類別檔案的程序和函數都可以存取此變數,稱為
「全域變數」(Global Variables)。
9-4 程序與函數的變數範圍-Visual
Basic專案
Visual Basic專案:Ch9-4\換零錢程式
這個Windows應用程式是修改和擴充第9-3節的
【換零錢程式】,改為使用CheckBox控制項來勾
選想兌換的硬幣種類,程式可以計算出可兌換成
幾個50元硬幣、幾個20元、幾個10元、5元和1元
硬幣。其執行結果如下圖所示:
9-5 常用的內建函數
9-5-1 日期/時間函數
9-5-2 字串處理函數
9-5-3 資料型態檢查函數
9-5-4 數學函數
9-5-1 日期/時間函數-說明
日期/時間函數可以處理日期/時間格式資料和進行
分析。Visual Basic語言內建常用的日期/時間函
數,其說明如下表所示:
函數名稱
Now
Today
TimeOfDay
Year(Date_format)
Month(Date_format)
Day(Date_format)
Hour(Time_format)
Minute(Time_format)
Second(Time_format)
WeekDay(Date_format)
函數說明
傳回現在的日期和時間
傳回現在的日期
傳回現在的時間
傳回日期格式的年份
傳回日期格式的月份值 1~12
傳回日期格式的日數 1~31
傳回時間格式的小時 0~23
傳回時間格式小時的分 0~59
傳回時間格式分的秒數 0~59
傳回日期格式參數是星期幾,星期日到六的值為 1~7
9-5-1 日期/時間函數-範例
例如:在Label標籤控制項顯示現在的日期、時間
和星期幾,如下所示:
lblOutput.Text = "現在的日期時間: " & Now & _
vbNewLine
lblOutput.Text &= "現在的日期: " & Today & vbNewLine
lblOutput.Text &= "現在的時間: " & TimeOfDay & _
vbNewLine
Dim dtDay As Date ' 宣告日期/時間變數
dtDay = Today
' 傳回現在日期
lblOutput.Text &= "星期幾: " & Weekday(dtDay) & _
vbNewLine
9-5-1 日期/時間函數-DateAdd()函數
(說明)
DateAdd()函數可以加減日期/時間,其語法如下
所示:
DateAdd(單位字串, Number, DateTime)
上述DateAdd()函數是使用單位字串的秒、分或小
時等單位,將第3個參數的日期/時間加減參數
Number的值。單位字串的說明,如下表所示:
單位字串
D
H
n
m
s
差異的單位
日
小時
分鐘
月
秒
9-5-1 日期/時間函數-DateAdd()函數
(範例)
例如:在Label標籤控制項顯示5天後日期,
如下所示:
Dim dtDay, dtDay1 As Date ' 宣告日期時間變數
dtDay = Today
' 傳回現在日期
dtDay1 = DateAdd("D", 5, dtDay) ' 加上5日
lblOutput.Text &= "5天後為: " & dtDay1 & _
vbNewLine
9-5-1 日期/時間函數-DateDiff()函數
(說明)
DateDiff()函數可以計算日期或時間差,其
語法如下所示:
DateDiff(單位字串, DateTime1, DateTime2)
上述DateDiff()函數能夠計算後2個參數的時
間差,第1個參數字串同DateAdd()函數,
可以設定後2個日期/時間差是使用秒、分或
小時等單位。
9-5-1 日期/時間函數-DateDiff()函數
(範例)
例如:在Label標籤控制項顯示計算結果的
日期或時間差,如下所示:
Dim offset As Integer
offset = DateDiff("D", dtDay, dtDay1)
lblOutput.Text &= "dtDay-dtDay1為: " & _
offset & "天"
9-5-2 字串處理函數-說明
「字串」(String)是撰寫程式時常用的資料型態,
不論文字、標籤控制項取得的資料或程式輸出內
容,都是一種字串資料。
Visual Basic語言的字串是String資料型態的變數
或字串字面值,字串是0或多個依序的Char資料
型態的字元,以雙引號括起的文字內容,如下所
示:
Dim Stmt As String = "Visual Basic程式設計"
Dim Stmt1 As String
Stmt1 = "ASP.NET網頁設計"
9-5-2 字串處理函數-函數
函數
Len(Stmt)
UCase(Stmt)
LCase(Stmt)
LTrim(Stmt)
Rtrim(Stmt)
Trim(Stmt)
Space(num)
Asc(Stmt)
說明
傳回整數的字串長度,擁有多少個字元或中文字
將參數字串或字元的英文字母轉換成大寫
將參數字串或字元的英文字母轉換成小寫
刪除字串開頭的空白字元
刪除字串結尾的空白字元
刪除頭尾兩端的空白字元
傳回參數 num 個空白字元的字串
傳回參數 Stmt 字串第 1 個字元的 ASCII 碼,例
如:Asc("A")為 65
Chr(num)
傳回參數 ASCII 碼的字元
Mid(Stmt, start[ , length])
從參數 Stmt 字串的 start 位置(從 1 開始)取出
長 length 的子字串,如果沒有 length 參數,就是
從 start 位置到字串結尾的所有字元
Left(Stmt, length)
從參數 Stmt 字串的開頭起算共 length 長度的字
元,如果為 0 傳回空字串,如果大於字串長度,
傳回整個字串
Right(Stmt, length)
從參數 Stmt 字串的右邊回頭起算共 length 長度
的字元,如果為 0 傳回空字串,如果大於字串長
度,傳回整個字串
StrReverse(Stmt)
將參數的 Stmt 字串反轉,例如:Basic 成為 cisaB
InStr(start, Stmt1, Stmt2)
在參數 Stmt1 字串的 start 位置(從 1 開始)開
始找尋 Stmt2 字串,如果找到傳回找到的位置,
沒有找到傳回 0
Replace(Stmt, Stmt1, Stmt2) 將參數 Stmt 字串中的字串 Stmt1 取代成 Stmt2
9-5-3 資料型態檢查函數
資料型態檢查函數能夠檢查Visual Basic變
數的資料型態,如下表所示:
函數名稱
IsDate(stmt)
函數說明
如果運算式是 Date 型態或能夠轉換成 Date 型態的字串傳
回 True;否則傳回 False
IsNumeric(stmt)
如果整個 stmt 都是數字傳回 True;否則傳回 False
IsArray(var)
如果參數的變數是指向陣列的話傳回 True;否則傳回 False
IsNothing(stmt) 如果運算式的 Object 變數沒有指派物件傳回 True;否則
傳回 False
9-5-4 數學函數-亂數與四捨五入函
數
Visual Basic語言的亂數與四捨五入函數,
其參數stmt為數值或運算式,如下表所示:
函數名稱
Rnd(stmt)
函數說明
亂數函數,依 Single 資料型態的參數產生單精浮點數的亂
數
Randomize(stmt) 使用參數初始化 Rnd()函數的亂數產生器,因為每次會給
予新的種子值,所以每次都產生不同的亂數序列,如果沒
有參數,使用的是系統計時器傳回的值
Int(stmt)
傳回整數的運算結果,它會無條件捨去數字的小數部份,
如果數值為正,傳回整數部分;如為負數傳回比數值小的
負正數
Fix(stmt)
取得數值的整數部分,使用無條件捨去法且不考慮數值為
正或負數
9-5-4 數學函數-Math類別的數學常
數
在System.Math類別擁有2個數學常數,其
說明如下表所示:
常數
E
PI
說明
自然數 e= 2.7182818284590452354
圓周率π= 3.14159265358979323846
9-5-4 數學函數-Math類別的數學方
法
方法
說明
Acos(Double)
反餘弦函數
Asin(Double)
反正弦函數
Atan(Double)
反正切函數
Atan2(Double1,
參數 Double1/Double2 的反正切函數值
Double2)
Cos(Double)
餘弦函數
Exp(Double)
自然數的指數 ex
Log(Double)
自然對數,Log10 是以 10 為底
Log10(Double)
Pow(Double, Double)
傳回第 1 個參數為底,第 2 個參數的次方值
Sign(Type)
傳回參數值的符號,傳回值-1 表示小於 0,0 等於 0,1
大於 0,Type 可以是 Decimal、Double、Single、Integer、
Short 和 Long 等
Sin(Double)
正弦函數
Sqrt(Double)
傳回參數的平方根
Tan(Double)
正切函數