yuan-yu tsai 蔡淵裕 yytsai@asia.edu.tw 辦公室: hb61. 2 chapter 4 副程式與模組

Post on 20-Dec-2015

242 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Yuan-Yu Tsai蔡淵裕

yytsai@asia.edu.tw辦公室:HB61

2

CHAPTER 4副程式與模組

副程式副程式

藉由『副程式』或『函式』的建立,同樣一段程式碼,透過輸入不同『參數』,就能夠重複的被使用在各種專案和程式碼中

成績處理程式 傳入不同科目的分數,即可計算出平均值

.NET Framework 本身內建了相當多豐富的系統函式 ( 或是副程式 ) 提供程式設計師使用

開發人員不需親自撰寫所有的程式碼,透過簡單的指令即可達成需要的功能

3

範例-刪除檔案範例-刪除檔案

透過『 System.IO.File.Delete 』刪除硬碟中某個指定的檔案 括號內之『 C:\abc.txt 』稱之為參數

4

EX : CH04-19\Module1.vb

Sub Main( ) ' 刪除 C:\abc.txt 檔案 System.IO.File.Delete("C:\abc.txt") Console.WriteLine(" 檔案已經刪除 !") Console.ReadKey( ) End Sub

範例-計算次方範例-計算次方

透過『 System.Math.Pow 』計算次方 括號內之『 a 』及『 b 』稱之為參數

5

Sub Main( ) Dim a, b As Single Dim result As Single Console.WriteLine(" 計算 a^b") Console.Write(" 請輸入 a 之數值: ") a = Console.ReadLine Console.Write(" 請輸入 b 之數值: ") b = Console.ReadLine result = System.Math.Pow(a, b) Console.Write(a & "的 " & b & " 次方為 " & result) Console.ReadKey( )End Sub

模組模組

成績處理程式 計算平均值 找最高分及最低分 計算標準差及變異數

模組 將相同類型的副程式或函式放在一起分類使用 意味著程式可以分派給多人共同合作

6

副程式結構 副程式結構 SubroutineSubroutine

7

主程式 副程式Sub Main( )

Code Code Code Code

End Sub

Sub 副程式名稱 ( )

Code Code Code Code

End Sub這樣的一個程式區塊 (從Sub…到 End Sub) ,就被稱為『副程式』,且可在其他的程式碼當中被呼叫

8

EX: CH04-01

Sub MySubA( ) Dim dt As Date '取得現在時間 dt = System.DateTime.Now.ToString '顯示 Console.WriteLine(dt)End Sub

Sub Main( ) '顯示 Console.WriteLine("Hello") '呼叫副程式 [Call] MySubA( ) '顯示 Console.WriteLine("How are you?") '暫停 Console.ReadKey( )End Sub

副程式需要有一個名字,命名規則與變數相同

呼叫 .NET 本身提供的系統函式,來取得時間

顯示目前的時間

利用 Call 指令呼叫副程式

副程式

主程式

9

EX: CH03-07

Sub Main( ) Dim i As Integer For i = 1 To 12 Console.WriteLine(i) Next Console.ReadKey( )End Sub

Sub Main( ) Dim i As Integer For i = 1 To 12 Console.WriteLine(i) Next Pause( )End Sub

Sub Pause( ) Console.WriteLine( ) Console.Write("... 程式暫停中,請按任意鍵繼續… ") Console.ReadKey( )End Sub

函式函式 ((FunctionFunction)) 建立建立

10

建立函式Function Max(ByVal a As Integer, ByVal b As Integer) As

Integer If a > b Then Return a End If If a < b Then Return b End If '如果兩者相等,則傳回 Return 0End Function

函式名稱 函式所須參數由逗號隔開,且每個參數都要有型別

函式回傳之資料型態

Return指令用來結束Function並把值傳回函式名稱

函式與副程式之差異在於函式是可以具有傳回值的,因此需要指定『回傳值的型別』

參數是指當要呼叫這個函式時,需要傳入的運算用資料( 副程式與函式皆可有參數 )

呼叫函式呼叫函式

11

Dim n1, n2 As IntegerDim ret As Integerret = Max(n1, n2)

Dim ret As Integer ret = Max(35, 73)

Dim ret As Integer Max(35, 73)

呼叫時需要傳入兩個參數,傳入的參數可以是變數或是常數的形式

由於 Max 函式會有回傳值,因此建立一個變數來『接收回傳值』

Max 函式回傳之結果會被忽略

ExampleExample

建立一個函式,讓使用者輸入圓的的半徑,該函式就傳回圓的面積

12

13

解答

Sub Main( ) Dim r As Single Dim area as Single Console.Write(" 請輸入半徑: ") r = Console.ReadLine area=Area_Cal(r) Console.WriteLine(" 半徑 " & r & " 之圓面積為: " & area) Pause( )End Sub

Function Area_Cal(ByVal r As Integer) as Single Dim tmp as Single tmp=r*r*3.14159 Return tmpEnd Function

Sub Pause( ) Console.WriteLine( ) Console.Write("... 程式暫停中,請按任意鍵繼續… ") Console.ReadKey( )End Sub

副程式

函式

ExerciseExercise

參考 CH02-12 的範例,建立一個 BMI 函式,當傳入身高,體重,則傳回該人的 BMI 值

如果函式的回傳值型別設為 Single ,但主程式接收參數的變數型別為 Integer ,則會發生什麼狀況 ?

如果函式中參數的型別為 String ,但主程式傳遞給該函式的相對應變數為 Integer 型別,則會發生什麼狀況 ?

如果函式中參數的型別為 Integer ,但主程式傳遞給該函式的相對應變數為 String 型別,則會發生什麼狀況 ?

14

ExampleExample 請撰寫一個函式,名稱為 GetNumber ,

接收的參數為 msg(String 型別 ) ,並且回傳 Integer 型別的回傳值,必須具備顯示 Msg 並且要求使用者輸入數字的功能

n1=GetNumber(" 請輸入數字 1:")

n2=GetNumber(" 請輸入數字 2:")

15

解答 Function GetNumber(ByVal Msg As String) As Integer Console.Write(Msg) Return Console.ReadLineEnd Function

傳值呼叫傳值呼叫 (ByVal )(ByVal )

16

Sub Main( ) Dim a, b As Integer a = 10 b = 20 Swap(a, b) Console.WriteLine("變數 a:" & a) Console.WriteLine("變數 b:" & b)End Sub

Function Swap(ByVal n1 As Integer, ByVal n2 As Integer) As Integer Dim c As Integer c = n1 n1 = n2 n2 = cEnd Function當主程式呼叫副程式的時候,把自己變數內的值給副程

式用,但原本主程式中的變數則不受副程式的影響

執行結果變數 a:10變數 b:20

傳址呼叫傳址呼叫 (ByRef )(ByRef )

17

Sub Main( ) Dim a, b As Integer a = 10 b = 20 Swap(a, b) Console.WriteLine("變數 a:" & a) Console.WriteLine("變數 b:" & b)End Sub

Function Swap(ByRef n1 As Integer, ByRef n2 As Integer) As Integer Dim c As Integer c = n1 n1 = n2 n2 = cEnd Function當主程式呼叫副程式的時候,把自己的變數本身一起傳

過去給副程式使用

執行結果變數 a:20變數 b:10

18

範例Sub Main( ) Dim a( ) As Integer = {4, 15, 23, 1, 57, 21, 722, 3, 6, 89, 24, 5, 62} Sort(a) For i As Integer = 0 To UBound(a) Console.Write(a(i) & ",") Next Console.ReadKey( )End Sub

Sub Sort(ByRef arr( ) As Integer) For x As Integer = 0 To UBound(arr) For y As Integer = x + 1 To UBound(arr) If arr(x) > arr(y) Then Swap(arr(x), arr(y)) Next NextEnd Sub

Sub Swap(ByRef n1 As Integer, ByRef n2 As Integer) Dim c As Integer c = n1 n1 = n2 n2 = cEnd Sub

19

4 15 23 1 57 21 722

3 6 89 24 5 62

1 15 23 4 57 21 722

3 6 89 24 5 62

1 3 23 15 57 21 722

4 6 89 24 5 62

1 3 4 23 57 21 722

15 6 89 24 5 62

1 3 4 5 57 23 722

21 15 89 24 6 62

1 3 4 5 6 57 722

23 21 89 24 15 62

1 3 4 5 6 15 722

57 23 89 24 21 62

1 3 4 5 6 15 21 722

57 89 24 23 62

1 3 4 5 6 15 21 23 722

89 57 24 62

1 3 4 5 6 15 21 23 24 722

89 57 62

1 3 4 5 6 15 21 23 24 57 722

89 62

1 3 4 5 6 15 21 23 24 57 62 722

89

1 3 4 5 6 15 21 23 24 57 62 89 722

OptionalOptional 關鍵字關鍵字 以此關鍵字修飾的參數被定義後,主程式在呼

叫該函數時,可以省略此參數

20

Function add(ByVal a As Integer, Optional ByVal b As Integer = 0)EX : CH04-09

Sub Main( ) Dim a As Integer a = add(5) MsgBox(a) a = add(5, 10) MsgBox(a)End Sub'將 a,b兩個參數相加並傳回 ,如果沒有傳入 b參數 ,則預設為Function add(ByVal a As Integer, Optional ByVal b As Integer = 0) Return a + bEnd Function

因為「 Optional」修飾字的關係,就算在呼叫 add 函式沒有填入參數 b 值也不會有錯誤訊息

需指定預設值

ExerciseExercise

請建立一個函式,可以傳入兩個或三個整數型態的參數,並針對傳入的參數做相乘的動作,當參數只傳入兩個時,則將兩個參數相乘,並將結果回傳,若傳入三個參數,則將這三個參數相乘,並把結果回傳

21

變數的存留期與存取範圍變數的存留期與存取範圍 變數的『存留期』,是指變數在記憶體當中佔

有的時間,從什麼時候開始到什麼時候結束 變數的『存取範圍』,則是指程式碼中可以存

取特定變數的範圍 全域變數指的是在程式的任何範圍都可存取到

的變數

22

全域變數 區域變數宣告方式 宣告在區域的外層 宣告在某個區域裡面 ( 例如

Function)

生命週期 程式執行時持續佔有記憶體空間

只有該函式執行時佔有記憶體空間

存取範圍 整個程式範圍 被宣告的區域內定義時機 需要被所有函式存取 僅在一定的範圍內存取

Do…Loop、 For Each…Next、 If…End If、Select…End Select、 SyncLock…End SyncLock、 Try…End Try、While…End While、 Sub…End Sub、 Function…End Function

23

EX : CH04-09

0001: Dim UserName As String0002: Sub Main( ) 0003: UserName = GetUserName( )0004: ShowWelcome( )0005: Pause( )0006: End Sub0007:0008: Function GetUserName( )0009: Dim n As String0010: Console.Write("請輸入您的名稱 :") 0011: n = Console.ReadLine( )0012: Return n0013: End Function0014:0015: Sub ShowWelcome( )0016: Console.WriteLine(UserName & "您好,歡迎您來到本系統 ")0017: End Sub0018: Sub Pause( )0019: Console.WriteLine( )0020: Console.Write("===>程式暫停中,請按任意鍵繼續 ...")0021: Console.ReadKey( )0022: End Sub

請注意這個變數宣告在主程式 Sub Main( ) 的外面,稱之為全域變數

這邊用到了第 2 行所定義的全域變數

這個變數宣告在 GetUserName( )函式中,稱之為區域變數

靜態變數靜態變數 以 Static 關鍵字所宣告的變數 靜態變數其數值會被保留,不會隨著所在的副

程式的結束而消失

24

EX : CH04-12

Sub Main( ) For i As Integer = 1 To 12 Test( ) Next End Sub

Sub Test( ) Static n As Integer = 0 n = n + 1 Console.WriteLine("n:" & n)End Sub

Sub Main( ) For i As Integer = 1 To 12 Test( ) NextEnd Sub

Sub Test( ) Dim n As Integer = 0 n = n + 1 Console.WriteLine("n:" & n)End Sub

靜態變數靜態變數 靜態變數的生命週期與『全域變數』是一樣的

在函式的最外層宣告全域變數之效果與靜態變數相同 全域變數之缺點

每個副程式或任何區域都可以存取該變數 其他的副程式不小心用到這個全域變數,或是誤設該變

數的值,導致難以察覺的錯誤,破壞函式間的獨立性 全域變數中已用過的變數名稱,同樣的名稱不能再出現

靜態變數之優點 跟全域變數一樣的生命週期 存取範圍被刻意侷限在某個副程式或是區域當中

可以避免被程式設計師誤用,有些常用的變數名稱,也可以重複的使用在不同的副程式或函式當中 25

.NET.NET 函式庫的呼叫與使用函式庫的呼叫與使用

.NET Framework 中有內建豐富的函式庫,並且依照不同的功能區分

26

命名空間名稱 功能System.Data 提供所有與資料庫 (Access, SQL

Server, Oracle) 相關的函式與功能。System.Drawing 提供與繪圖有關的函式與功能。System.IO 提供與檔案、資料夾存取有關的功能。System.Net 提供與網路相關的函式與功能。System.Net.Mail 提供與電子郵件相關的函式與功能。System.Web 提供與網際網路資源存取相關的功能。System.Xml 提供與 XML 相關的功能。

.NET My Class Library.NET My Class Library

透過簡單的『My 』關鍵字,讓程式設計師可以輕鬆的引用 .NET Framework 的功能

只需要在程式碼撰寫時,鍵入『My. 』系統就會跳出可供使用的功能

27

ExerciseExercise 請試著透過 My Class ,找到下載網際網路上檔

案的方法 請試著透過 My Class ,找到刪除一個本機電腦

檔案 ( 例如自己的 C:\) 的方法

請試著透過 My Class ,找到讓電腦『叮』一聲的方法

請試著透過 My Class ,偵測使用者是否按下鍵盤上的 Number Lock ,並顯示出來

28

模組 模組 ModuleModule

一群副程式的集合 將主程式碼切割成副程式,並將功能相似的副程式歸類為一個模組

使得開發人員方便管理,後續的維護也會更加便利,特別是在多人同時開發一個專案的時候,好處會更加明顯

29

建立模組之方式建立模組之方式選單中的「專案」→「加入模選單中的「專案」→「加入模組」組」

30

建立模組之方式建立模組之方式在「方案總管」中,按下滑鼠右鍵→「加入」→在「方案總管」中,按下滑鼠右鍵→「加入」→「模組」「模組」

31

模組的使用模組的使用

只需要打入模組名稱『 newmodule. 』,就會帶出該模組中可用的函式 (剛才我們建了一個Pause) 出來給我們選擇

32

EX : CH04-14\NewModule.vbModule NewModule Sub Pause( ) Console.WriteLine( ) Console.Write("===>程式暫停中,請按任意鍵繼續 ...")

Console.ReadKey( ) End SubEnd Module

名為 NewModule 的模組,內含一個 Pause 的副程式

33

EX : CH04-14

Sub Main( ) Dim score( ) As Single = {41, 57, 83, 93, 47, 99, 87.5, 56, 36.8, 95, 36.7} Dim ret As Integer ' 呼叫 Computation 模組裡的 sum ,傳遞參數 scores1讓 sum 計算。 Computation.Sum(score) ' 呼叫 Computation 模組裡的 average 。 ret = Computation.Average Console.Write(" 平均成績: " & ret) ' 暫停 NewModule.Pause( )End Sub

Module NewModule ' 暫停 Sub Pause( ) Console.WriteLine( ) Console.Write("===> 程式暫停中,請按任意鍵繼續 ...") Console.ReadKey( ) End Sub

End Module

34

EX : CH04-14

Module Computation Dim SumScore As Single Dim Students As Integer

Sub Sum(ByVal scores As Array) SumScore = 0 Students = 0 For Each score As Integer In scores '累加總成績 SumScore += score '累加學生數量 Students += 1 Next End Sub Function Average( ) As Single Dim AvgScore As Single AvgScore = SumScore / Students Return AvgScore End FunctionEnd Module

函式自動註解功能函式自動註解功能

35

註解功能0022: ''' <summary>0023: ''' 把成績平均0024: ''' </summary>0025: ''' <returns></returns>0026: ''' <remarks></remarks>0027: Function Average( ) As Single0028: Dim AvgScore As Single0029:0030: AvgScore = SumScore / Students0031: Return AvgScore0032: End Function

在函式或副程式上頭,連續打三個『 ' 』,就會自動出現這串文字,請在<summary>和</summary> 中,手動入輸入註解

模組中函式的可用範圍模組中函式的可用範圍

『保護措施』的機制:避免呼叫到不該呼叫的函式而發生意料之外的錯誤,可讓模組的架構更佳的完善

當函式未用 Private 關鍵字修飾時,預設可跨到模組之外 當變數未用 Public 關鍵字修飾時,預設存取範圍為模組之

內 36

Module A Sub B( ) Call C( ) End Sub Sub C( ) (…略… ) End Sub Sub D( ) Call C( ) End SubEnd Module

Module A Sub B( ) Call C( ) End Sub Private Sub C( ) (…略… ) End Sub Sub D( ) Call C( ) End SubEnd Module

ExerciseExercise

某班同學考試成績如右 若要把分數分成三個級距

100-80 為優秀 79-60 為通過 0-59 為不通過

請利用副程式撰寫程式,列出優秀、通過以及不通過的學生

37

學號 分數1 100

2 70

3 59

4 63

5 77

6 13

7 50

8 60

9 97

10 88

38

top related