第4章VB語法精選

Download Report

Transcript 第4章VB語法精選

第四章 VB語法精選
本書使用VB2010語法來開發ASP.NET程式,因此在本
章中,我們將迅速回顧VB2010的語法,並透過範例來
示範。但我們不會介紹VB2010中與物件導向有關的語
法。而是著重在變數、運算式、流程控制及陣列的說明。
若您已經有其他程式語言的背景,則可迅速瀏覽本章內
容,若您已熟悉VB2010語法,可直接略過本章的介紹。
1
第四章 VB語法精選
• ASP.NET可以使用C#或VB.NET語法開發程式,本書採用的
是VB.NET語法,並且由於本書採用單一檔案模式開發
ASP.NET網頁,故不必學會VB.NET的「繼承」語法就能夠
進行ASP.NET的程式開發。在本章中,我們將迅速瀏覽
VB.NET的基本語法(並不牽涉物件導向)。
2
大綱
• 4.1 『VB2010』簡介
• 4.2 VB2010的基礎
–
–
–
–
–
4.2.1
4.2.2
4.2.3
4.2.4
4.2.5
變數
常數
設定運算子
運算式與運算子
型別轉換
• 4.3 決策與迴圈(流程控制)
–
–
–
–
–
–
4.3.1
4.3.2
4.3.3
4.3.4
4.3.5
4.3.6
If…Then…決策
If…Then…Else…決策
Select...Case...End Select決策
For…Next迴圈
While...End While條件式迴圈
Do...Loop條件式迴圈
3
大綱
• 4.4 陣列
– 4.4.1
– 4.4.2
宣告陣列-Dim敘述
For Each ...Next 陣列迴圈
• 4.5 程序
–
–
–
–
–
4.5.1
4.5.2
4.5.3
4.5.4
4.5.5
Sub程序
Function程序
變數有效範圍
遞迴程序
Visual Basic的內建函式
• 4.6 本章回顧
4
4.1 『VB2010』簡介
• Basic是一個具有歷史的程式語言
– 從早期的不夠結構化,演變為QBasic結構化程式語言後,持續演變為可開
發視窗程式的Visual Basic,Visual Basic可以使用系統提供的視覺化物件,
並採用事件驅動方式設計程式,但不能夠繼承類別自創類別及物件,於是
最後一個版本Visual Basic 6終於被淘汰。隨之而來的新版本稱之為Visual
Basic.NET。
• 除此之外,在網頁技術流行之初,Visual Basic也曾被簡化為VBScript,
可以使用於客戶端瀏覽器設計程式,也能夠作為伺服器端傳統ASP的
Script語言
– VBScript與VB的特性類似,可使用系統提供的物件,並採用事件驅動方式
設計程式,但不能夠繼承類別。
– 因此,不論是VBScript或VB6都只能算是物件基礎程式語言而不是物件導
向程式語言。
5
4.1 『VB2010』簡介
•
Visual Basic.NET是一個完整的物件導向程式語言,同時也提供了好用的
IDE,使之易於開發視窗程式。Visual Basic.NET是.NET Framework的一
環,因此,可使用.NET Framework類別庫的類別來建立物件。
– Visual Basic.NET的版本共出現1.0、2.0、3.0、3.5、4.0版等,其中本書使用
的為Visual Basic.NET 4.0版,又稱為Visual Basic 2010版。
– ASP.NET不再採用VBScript語法開發程式,而是改採C#或VB.NET語法,這
樣的好處在於,可使用.NET Framework類別庫的類別來建立物件,並且還能
夠繼承與自創類別。
• 除了上述特點之外,新版的VB新增了『區域型別推斷』、『物件初始設
定』與『匿名型別』等功能,並且為了統一資料的存取介面,另外提供了
LINQ(Language Integrated Query)查詢語言。
• 而本書不會介紹過多的VB2010語法,有興趣的讀者應該另外閱讀VB2010
的專書。
6
4.1 『VB2010』簡介
• 在本章中,我們將以最簡略的方式介紹VB2010
– 您可以當做學習VBScript般,不用理會繼承機制,因本書採用的是單一檔案型
式開發ASP.NET網頁,故不會出現Partial Class及Inherits等關鍵字。
– 至於和物件導向有關的VB語法將於下一章進行介紹。
7
4.2 VB2010的基礎
• 在第3章,我們曾在按鈕事件程序中,撰寫單一行的設定敘述
(Assignment Statement)
– 該敘述是將字串相連並設定給『=』左方的變數。而其『=』右方的字
串連結則為一個運算式『Expression』。
• 設定敘述(Assignment Statement) :
Label2.Text = "耶!" + TextBox1.Text + "也會寫ASP.NET網頁程式了。"
8
4.2 VB2010的基礎
• VB程式是由許多的程序所組成,而程序內則由許多的敘述(Statement;
又稱陳述式)組合而成,並且敘述分為許多種,例如我們後來將第三章的
按鈕事件程序修改如下時,它包含了兩種敘述,分別是If… Then…Else敘
述及設定敘述。
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
If TextBox1.Text = "" Then
Label2.Text = "請在文字方塊中輸入文字後,再按下按鈕。"
Else
Label2.Text = "耶!" + TextBox1.Text + "也會寫ASP.NET網頁程式了。"
End If
End Sub
• 各種不同的敘述代表的意義皆有所不同,在本章中,我們將陸續加以介紹。
而在本章範例中,我們將會把所有的程式都撰寫於按鈕事件程序中,而其
結果則使用Label控制項來表示。
– 至於介面的位置若較單純者,會採用相對定位,若較複雜者,則採用絕對定
位。
9
4.2 VB2010的基礎
• 在撰寫VB程式時,要注意下列幾點:
– (1) 註解:想要在VB中使用註解,則必須使用『‘』符號。(
• 在『‘』符號之後整行的文字都會被視為VB程式的註解,編譯器將
不加以處理。
• 而註解是用來提示維護者,該部分程式的功能為何。
• 不過請注意,單引號若出現在字串內,則不會被當成是註解符
號。)
'此行全部為註解
x=y+3 '此符號後方全為註解
10
4.2 VB2010的基礎
– (2) 設定敘述的結束符號與跨行編輯程式:
• 設定敘述是最常用的敘述,VB以一行為一個單位,亦即兩行程式視為兩
個敘述。但當敘述過長而須分為兩行時,可以利用跨行符號『 _』來連結,
範例如下:
Label2.Text = "耶!" + TextBox1.Text + _
"也會寫ASP.NET網頁程式了。"
– 【說明】
• 上列敘述由於跨越兩行,故在後方使用跨行符號『 _』來連結,若不加上
跨行符號『 _』,則會視為兩個敘述,而這兩個敘述都不合法,故無法通
過編譯。同時,跨行符號不可出現在" "內,因為雙引號是用來包裝字串,
若跨行符號『 _』出現" "內,則會被視為字串的兩個字元。
– (3) 字串常數使用雙引號包裝:
• 如同上面範例中的"也會寫ASP.NET網頁程式了。",就是代表『也會寫
ASP.NET網頁程式了。』字串。
11
4.2.1
變數
• 變數是用來儲存程式執行時各項資料的一個記憶體位置名稱,因此,任何
程式語言都必須使用變數來為各項資料命名。在VB中,使用Dim敘述來宣
告變數(例如:Dim var1)。變數經宣告之後,便可以在程式的某個範圍
中做為運算或判別之用。在VB的變數宣告中,宣告變數時,可指定變數
的資料型別,也可以不指定,除此之外,也可以在宣告變數時,同時指定
其初始值。而若宣告變數時不指定變數型別,也不設定初值的話,則視為
宣告Object型別的變數。
• 宣告單一變數
– 宣告單一變數語法如下:
Dim
Dim
Dim
Dim
變數1 As 資料型別
變數2
'視為宣告Object型別的變數2
變數3 As 資料型別 = 初始值
變數4 = 初始值
'由初始值決定變數4的資料型別
12
4.2.1
變數
– 【說明】
• (1) 當宣告變數時,若不指定變數型別但設定初值時,VB2010編譯器會進
行區域型別推斷(Type Inference),由初始值的資料型別判斷該變數的資
料型別。
• (2) 當宣告變數時,若不指定變數的資料型別及初值時,會認定變數為
Object型別的變數,Object是.NET Framework所有類別的祖先,故該變
數將來可以設定為任何一種資料型別,但我們並不建議將變數宣告為
Object型別。因為雖然不需宣告資料型別會加快程式的撰寫,但也會使得
程式的執行變慢,同時,將變數明確宣告為某個資料型別,也可以讓編譯
器的型別檢查找出可能的相關錯誤。
• (3) 宣告變數時若未設定預設值,則如下規定:
13
4.2.1
變數
– 【範例】
Dim
Dim
Dim
Dim
var1 As Integer
'var1為Integer型別的變數
var2
'var2為Object型別的變數
var3 As String = "Hello" 'var3為String型別的變數
var4 = "您好"
'var4為 String型別的變數
• VB提供了多種的資料型別(如表4-1),以便存放不同種類
的資料,下表是VB可使用的資料型別。
– 由於VB.NET屬於.NET Framework的一環,為了達到跨語言的效果,
故它以CLR的相關類別來對應資料型別
– 並且為了達到跨平台的效果,因此實際使用的記憶體長度有些會由實
作平台來決定
14
15
4.2.1
變數
16
4.2.1
變數
– 【註】以上類別庫皆為System,例如Integer使用的類別為System.Int32類別。
17
4.2.1
變數
• 事實上,通常我們不會使用所有的資料型別,常用的資料型
別如下:
• 同時宣告兩個以上變數
– 我們也可以同時宣告兩個以上的變數,並且還可以指定不同的資料型
別:
18
4.2.1
變數
Dim var1, var2, var3 As Integer
Dim var4 As Double, var5 As String="Hello"
Dim var6 As Integer = 3 , var7 As Double
• 【說明】
– (1)var1,var2,var3,var6都是Integer整數型別,var6的初始值為3,其餘
為0。
– (2)var4,var7都是Double浮點數型別,初始值為0。
– (3)var5為String字串型別,初始值為「Hello」。
– (4)您無法將第一行改寫為Dim var1, var2, var3 As Integer = 6,因為
使用單一型別宣告多個變數時,不允許設定初始值。
– (5)但您可以將最後一行改寫為Dim var6 As Integer = 3, var7 As
Double = 3.5,因為它並非使用單一型別宣告多個變數。
19
4.2.1
變數
• 變數的命名規則
–
–
–
–
–
–
變數的名稱可以由我們自行決定,但須符合下列命名規則:
1. 必須以字母字元或底線 (_) 開頭。
2. 只能包含字母字元、十進位數字和底線。
3. 若以底線開頭,必須含有至少一個字母順序字元或十進位數字。
4. 長度不可超過 1023 個字元。
5. 變數名稱不可以是Visual Basic的保留字。因保留字對VB具有特殊
意義,例如For代表迴圈。通常IDE會提示您使用了關鍵字或保留字。
– 6. 對編譯器而言,變數名稱的大小寫視為相同。但在CLR中仍會區分
大小寫。
20
4.2.1
變數
• 雖然變數名稱有上述規定,但依照實際情況,我們仍提出下
列建議:
– (1)盡可能不以底線 (_) 開頭,因為有時以底線 (_) 開頭的名稱會被系
統採用。
– (2)區分大小寫。
– (3)變數名稱盡可能簡短,但仍具有意義,如此可提升程式碼的可讀性。
– (4)名稱中的每一個單字以大寫字母做為開頭,例如 RectWidth 與
RectLength,可用來作為矩形的寬與長之變數名稱。其他關於程序命
名等相關建議請見msdn的「Visual Basic 命名慣例」段落。
21
4.2.2
常數
• 『常數』在日常生活中無所不見,例如:圓周率π、自然指數
e、光速…等等,代表的意思是在宇宙間永遠不會變動的數值。
但是對於程式而言,『常數』則是「一個在程式執行過程中
不會被改變的某個數值、字元或字串」。
– 換句話說,常數在執行過程中,同樣會佔用某些記憶體,但是該記憶
體內容卻不會改變。
– 也就是說,『常數』在程式執行前會先給定一個值,而在執行過程中該
常數值不會改變。Visual Basic的常數分為常值 (Literal Constant)與符
號常數 (Symbolic Constant) 兩類。
22
4.2.2
常數
• 常值(Literal)
– 常值是由一連串的字元組合而成,這些字元是Unicode字元,但有些
則具有數字或特殊意義。在VB中,字串格式的常值前後必須使用『"』
括起來,例如" Hello "、"12,000"。而具有數值意義的常值,則不必用
『"』括起來,例如3、5.3。
【註】:
若在字串中必須出現『"』符號,則需要在『"』字元前再加上一個『"』。
所以若要表達『4"5』,則必須寫為"4""5",而若字串只有單一個字元
『"』,則必須寫為""""。
23
4.2.2
常數
• 符號常數(Symbolic Constant)
– 在程式設計時,有時會遇到某些常數或文字不斷重複出現在各片段程
式碼的情況,例如:利率(會計軟體)、圓周率(數學繪圖軟體)、
光速(物理計算軟體)等。此時我們可以透過Const敘述,宣告一個
『符號常數』,以名稱來取代該常數值,如此一來,所有在程式中必
須使用該常數值處,都可以使用這個『符號常數』來代替。
– 同時,當該常數內容變動時(例如:利率更動),則只需要在宣告處
修改符號常數的內涵,而不需要更改使用該常數的所有程式碼。
– 宣告符號常數的語法如下:
Const 常數名稱 As 資料型別 = 常值
24
4.2.2
常數
– 使用符號常數的範例如下:
Const pi As Double = 3.14
Dim Area,Length As Double
Dim Radius As Double = 10
'宣告pi為符號常數
Area = Radius * Radius *pi
Length = 2* Radius *pi
'計算圓面積
'計算圓周長
25
4.2.3
設定運算子
• 設定敘述(Assignment Statement;或稱為指派敘述)是設定變
數值的重要運算子,並且分為兩類:
– 1.設定運算子『=』
• 設定運算子『=』可以將『=』右方的運算式之結果設定給左方的
變數,範例如下:
Dim Area, Radius As Double
Dim var1 As Integer=1
var1=var1+5
'將var1+5的結果設定給var1,故執行完畢var1為6
Radius=10.5
'10.5設定給Radius變數
Area = Radius * Radius *3.14 '計算圓面積,並將結果設定給Area變數
26
4.2.3
設定運算子
– 2.複合設定運算子『+=、-=、、、、』
• 複合運算子同時具有設定與計算功能,會將右方的運算式之結果
與左方變數進行特定運算後,設定給左方變數,範例如下:
Dim var1 As Integer=1
Dim var2 As Integer=4
var1+=5
'將var1+5的結果設定給var1,故執行完畢var1為6
var1-=var2
'將var1-var2的結果設定給var1,故執行完畢var1為2
27
4.2.3
設定運算子
– VB的複合設定運算子共有下列幾種:(有些運算符號請見下一節的說
明)
28
4.2.4
運算式與運算子
• 除了單純的設定之外,要讓程式產生變化,通常需要透過運
算式進行運算。
– 運算式(Expression)是由運算子與運算元組合而成
• 例如『x+y』,則x、y為運算元,而+為運算子。,
– 並且運算式可以由更小的運算式組合而成
• 例如『z*(x+y)』,其中*號的運算元為z與(x+y),而(x+y)本身也是
一個運算式。
• VB提供了眾多的運算子以進行不同的運算,並且這些運算子
可以分類為算術、比較、串連、邏輯和位元運算子等等。
– 算術運算子
• 算術運算子的運算對象(運算元)是數值資料型別的變數或常數。
Visual Basic提供的算術運算子如下。
29
4.2.4
運算式與運算子
– 【說明】
• 當+、-作為表達正數與負數時,為一元運算子(只有一個運算元),
其餘都是二元運算子。
30
4.2.4
運算式與運算子
– 串連運算子
• VB提供了字串連結的串連運算子,『+』與『&』都可以作為字串相連使
用,範例如下:
Dim str1 As String = "Hello", str2 As String = "Kitty"
Dim str3,str4 As String
str3=str1+" "+ str2
str4= str1 & " " & str2
' str3內容為 Hello Kitty
' str4內容為 Hello Kitty
• 【註】"12"+"34"為字串連結而非數值計算,故結果為"1234”
• 【註】『&=』與『+=』也可以作為串連字串的複合設定運算子。
– 比較運算子
• 比較運算子是用來比較兩個運算式,通常作為條件判斷之用,它會在比較
之後回傳一個Boolean值,該值代表左右運算式的關係,並且又可以分為
比較數值、比較字串及比較物件等三類運算子。
31
4.2.4
運算式與運算子
32
4.2.4
運算式與運算子
33
4.2.4
運算式與運算子
– 邏輯和位元運算子
• 有些時候光是依靠比較無法判斷較複雜的狀況,此時可利用邏輯運算子將
運算式的布林結果進行運算,其值仍舊是一個布林值。
– 例如,若想測試高度是否介於120~150之間,則可以寫為
(height<=120 And height>=150)。
• VB提供的基本邏輯運算子有Not、And、Or、Xor等。其真值表如下:
34
4.2.4
運算式與運算子
– 除了上述的基本邏輯運算子之外,為了加快程式的速度,因此VB也提
供了AndAlso與OrElse兩個運算子,功能與And及Or完全相同,只不
過它有時可以依照左運算式的結果,就能夠決定最後的結果,不必測
試右運算式。此技巧稱之為最少運算(Short Circuit)。範例如下:
35
4.2.4
運算式與運算子
36
4.2.4
運算式與運算子
• 上述的邏輯運算,其左右運算式必須是布林運算式,亦即運算元
具備布林值特性。若運算元不具備布林值特性且為整數型別時使
用Not、And、Or、Xor,則會變成是位元運算。至於AndAlso與
OrElse則不能當作是位元運算。
– 進行位元運算時,會將運算元化為二進制,然後每一個位元進行位元
運算,最後才組合為結果。其單一位元的真值表如下:
37
4.2.4
運算式與運算子
• 範例如下:
Dim x As Integer = 11
Dim y As Integer= 14
Dim result1,result2 As Integer
result1=x And y
'result1結果為10,因1011 And 1110為1010
result2=x Or y
'result2結果為15,因1011 Or 1110為1111
•
運算子優先權
– 就像小時候所學的鐵律『先乘除後加減』一樣,每個運算子都有其運
算優先順序(稱為運算子優先權),當一個運算式中出現不只一個運
算子時,就必須由運算子優先權決定哪一個運算先做。若您不確定運
算順序的話最好使用『( )』將部分運算式先括起來,以便保證絕對會
先被執行。VB的運算子優先權規定如下:
38
4.2.4
運算式與運算子
– 【註】
• 優先順序相同的運算子,按照在運算式的位置由左至右來評估,越靠左者
越先執行。
39
4.2.4
運算式與運算子
• 運算子的關聯性
– 除了優先權之外,另外一個會影響運算式最後結果的因素就是運算子
的關聯,就如同數學上的1+2+3會先計算1+2再計算(1+2)+3,而次方
計算則並非如此,如下圖:
圖4-1 上式中數學的關聯在VB中並不成立
– 明顯地,『+』號的關聯性為由左向右,但次方的關聯性應該是由右
向左,但VB規定,當運算式中出現優先順序相同的運算子時 (例如除
法),編譯器會依運算出現順序由左至右評估,此稱之為左關聯。
• 因此,上述範例將與數學的計算結果不同,在VB中,(2 ^ 3 ^ 2)結
果為64,如果想要如數學之定義,則應該撰寫為(2 ^( 3 ^ 2)),結
果才會是512。
40
4.2.5
型別轉換
• 程式在編譯時,有時候會進行型別的轉換,例如Area =
Radius * Radius *pi,假設Radius為Integer型別,Area與pi皆
為Double型別,則Radius會被自動轉換為Double型別來運算
– 這種自動轉換型別的動作會由編譯器自動進行,稱之為隱含式轉換
– 而編譯器會以最寬裕的型別作為轉換後的型別,例如Double必定可存
放整數,故轉換為Double型別。
• 除了自動轉換型別之外,我們也可以在程式中使用『明確轉
換』以確保資料的正確性
– 例如Label控制項的Text屬性為String字串型別,當我們想要將數值資
料設定給字串變數時,就可以使用CStr()函式來進行轉換。
– VB提供作為型別轉換的函式如下表所列:
41
4.2.5
型別轉換
42
4.2.5
型別轉換
– 範例:
Dim str1 as String
Dim x as Integer =200
str1 = CStr(x)
' str1結果為"200"
【奇怪的VB四捨五入】:
在VB中,當小數資料型別轉換為整數時,採用了一種奇怪的四捨五入方式進行
轉換。在微軟網頁中,將之稱為「四捨六入五成雙」。
也就是當小數不是兩個相鄰正整數的中點,使用的規則就是一般的四捨五入。
當小數恰好是兩個相鄰正整數的中點(例如:5.5、8.5),則會將小數轉換成最接
近的正偶整數(必定為雙數)。例如5.5取整數會得到6,8.5取整數會得到8。
43
4.2.5
型別轉換
• 整合範例
– 我們將之前介紹的小範例,以一個完整範例來呈現如下:
• 範例4-1:
– 網站目錄 ASPNET\ch04\ch04_01\(檔案ch04_01.aspx)
– Step1:
• 網頁介面設計如下(所有控制項皆採相對定位)並設定屬性(其
餘屬性參照屬性窗格)。
44
4.2.5
型別轉換
45
4.2.5
型別轉換
– Step2:撰寫事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Const pi As Double = 3.14
'宣告pi為符號常數
Dim Area, Length As Double
Dim Radius As Double = 10
Dim OutputStr As String
Area = Radius * Radius * pi
Length = 2 * Radius * pi
'計算圓面積
'計算圓周長
OutputStr = "圓面積=" + CStr(Area) + "<br />"
OutputStr = OutputStr + "圓周長=" + CStr(Length)
Label1.Text = OutputStr
End Sub
46
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
Dim Area, Radius As Double
Dim var1 As Integer = 1
Dim OutputStr As String
var1 = var1 + 5
'將var1+5的結果設定給var1,故執行完畢var1為6
Radius = 10.5
'10.5設定給Radius變數
Area = Radius * Radius * 3.14 '計算圓面積,並將結果設定給Area變數
OutputStr = "var1=" + CStr(var1) + "<br />"
OutputStr = OutputStr + "圓面積=" + CStr(Area)
Label1.Text = OutputStr
End Sub
– 範例說明:
• (1)我們只列出兩個按鈕的事件程序Button1_Click()與Button2_Click(),其
餘七個按鈕的事件程序請自行參閱檔案內容。
• (2)大部分的程式在之前已經說明過,此處尚需說明的如下:
• (3)Label1.Text為字串型別,OutputStr也被宣告為String字串型別,故可
以直接設定。
47
4.2.5
型別轉換
• (4)在第16~17行,使用『+』進行字串連結,而其他非字串型別的資料,
則使用CStr()函式將之轉換為字串型別。
• (5)在OutputStr中,連結了一個"<br />"字串,這是為了要在網頁中產生換
行效果,因為<br />是XHTML的換行標籤。在第3章中我們得知,Label控
制項執行後會形成<span>…內容…</span>回傳給瀏覽器,而由於我們在
其中加入了一些<br />字串,故執行後會形成<span> …內容…<br /> …內
容…<br /> …</span>,故瀏覽器會產生換行效果。
• (6)Button1_Click()與Button2_Click()兩個事件程序中,都宣告了Area變數,
但這是兩個不同的變數,相互不會影響,因為Area屬於區域變數,故作用
範圍僅在所處的程序內,並且當程序執行完畢後就會消失。
• (7)同理,OutputStr也是區域變數,當程序執行完畢後就會消失,因此無
法保存字串內容到下一次執行事件程序時,故若修改第16、31行,使其
串接OutputStr(例如OutputStr=OutputStr+ "圓面積="),也不用擔心
OutputStr是否殘留上一次執行的最後結果。
48
4.2.5
型別轉換
• (8)下圖僅測試Button1與Button2,其餘請讀者自行測試,並將結
果比對之前的小範例。
– Step3:執行程式。
• 【程式執行結果】:
49
50
4.3 決策與迴圈(流程控制)
• 任何一種程式語言都必須具有流程控制能力,否則將無法提
供各類變化的執行結果。
• 流程控制是由決策與跳躍組成,而決策與跳躍也可以合成迴
圈。
– 現今除了組合語言外,大多數程式語言並不允許使用者自行定義跳躍,
而把跳躍移到決策與迴圈之內,在VB也是如此。
• 在4.3.1~4.3.3節中,我們將介紹各種決策語法
• 而在4.3.4~4.3.6節中則是介紹各種迴圈語法
– 讀者應該完全了解決策與迴圈,才能夠寫出有用的程式。
51
4.3.1
If…Then…決策
• If…Then…決策是一種條件敘述(Conditional Statements),
當某個條件運算式成立時,就去做某件事(或某些事),當
條件運算式不成立時,就不會做這些事,下面是一個生活實
例。
– If 下雨 Then 打傘
• 【註】條件運算式也稱為判斷式或布林運算式
(BooleanExpression),也就是運算結果能產生布林值的運算式。
– 在VB中,寫上述的實例程式也是同樣的道理,只不過將『下雨』使用
條件運算式來表達。把『打傘』用敘述來表達。
– 例如:If A>1 Then B=100,就是當A>1時,將B的變數值指定為100。
52
4.3.1
If…Then…決策
• 如果要做的事不只一件的時候,我們又該如何撰寫呢?以下是一個生活實
例。
– If 感冒了Then
多喝水
多休息
End If
• 同樣地,上述範例也符合VB的語法,在從Then到End If之內的所有事情
就是當If之後的條件運算式成立時所要做的事情,以下是If…Then…決策
的兩個完整語法。
• If…Then…語法一:
If…Then…語法二:
If 判斷式 Then 要執行的單一敘述
If 判斷式 Then
...
要執行的敘述
...
End If
53
4.3.1
If…Then…決策
• 以下我們透過實際的範例來說明If…Then…決策。
• 範例4-2:
– 網站目錄 ASPNET\ch04\ch04_02\(檔案ch04_02.aspx)
– Step1:網頁介面設計如下(所有控制項皆採相對定位)並設定屬性
(其餘屬性參照屬性窗格)。
54
4.3.1
If…Then…決策
55
4.3.1
If…Then…決策
– Step2:撰寫Button1_Click()事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Dim A, A2 As Double
Label1.Text = ""
A = CDbl(TextBox1.Text)
If A > 5 Then
A2 = A ^ 2
Label1.Text &= "您所輸入的數值平方為" & CStr(A2) & "<br />"
End If
Label1.Text &= "謝謝使用"
End Sub
56
4.3.1
If…Then…決策
– 範例說明:
• (1)按下【計算】鈕後,第10、11、16行的程
式一定會被執行,其中的第11行,是用來設
定A的變數值為輸入欄位的內容,並使用
CDbl進行型別轉換。
• (2)第13~14行的程式則會視A的變數值是否大
於5才決定是否執行。因此,當您所輸入的值
大於5時,將會先計算A2的變數值為輸入值
的平方(第13行),然後串連到Label1標籤
內容顯示計算之後的結果(第14行)。最後
再執行第16行,繼續串連「謝謝使用」字串。
如果當所輸入的值小於等於5,則第13~14行
都不會被執行,但第16行仍會被執行,直接
串連「謝謝使用」字串。上圖是
Button1_Click事件程序的流程圖。
57
4.3.1
If…Then…決策
• (3) 本範例仍有缺失,將於下一個範例中修正。
– Step3:執行程式。
• 【程式執行結果】:
58
4.3.2
If…Then…Else…決策
• 使用If...Then…決策無法在當條件運算式不成立時,指定所執
行的動作。而If…Then…Else就可以在判斷式不成立的狀況
下,執行某些指定的程式碼,其語法如下。
– If…Then…Else…語法:
If…Then…Else…流程圖:
If 判斷式 Then
判斷式成立時要執行的敘述區塊
Else
判斷式不成立時所執行的敘述區塊
End If
59
4.3.2
If…Then…Else…決策
– 在範例4-2中,如果您未在文字方塊中輸入數值就直接按下【計算】鈕,
則會出現錯誤。這是因為CDbl(TextBox1.Text)進行轉型時發生了錯誤。
由於我們尚未介紹例外處理及驗證控制項,故在此我們以多一層的
If…Then…Else來進行檢查,事實上,這個範例也是巢狀決策的範例。
• 範例4-3:
– 網站目錄 ASPNET\ch04\ch04_03\(檔案ch04_03.aspx)
– Step1:網頁介面與範例4-2完全相同。
60
4.3.2
If…Then…Else…決策
– Step2:撰寫Button1_Click()事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Dim A, A2 As Double
Label1.Text = ""
If IsNumeric(TextBox1.Text) Then
'判斷是否輸入數值資料
A = CDbl(TextBox1.Text)
If A > 5 Then
A2 = A ^ 2
Label1.Text &= "您所輸入的數值平方為" & CStr(A2) & "<br />"
End If
Else
Label1.Text &= "請輸入數值資料" & "<br />"
End If
Label1.Text &= "謝謝使用"
End Sub
61
4.3.2
If…Then…Else…決策
– 範例說明:
• (1)在第11~19行是一個If…Then…Else敘
述,其判斷式為
IsNumeric(TextBox1.Text),IsNumeric是
一個特殊的函式,可以用來判斷字串是否
為數值,若是則回傳True,否則回傳
False。
• (2) 由於我們將範例4-2的部分程式移到第
12~16行,因此,只有當輸入欄位的文字
是數值時才會被執行(並且不會執行第18
行)
• (3) 當輸入欄位的文字不是數值時會直接
跳過第12~16行,而執行第18行。
• (4) 第20行是一定會被執行的,因為它並
非If…Then…Else敘述的一部分,流程圖
如下所示。
62
4.3.2
If…Then…Else…決策
– Step3:執行程式。
【註】:由此範例中,您可以發現,我們可以將多個If…Then…Else敘述組成巢
狀式結構,如此一來,就可以將各種狀況再細分成許多小狀況完成所需要的對
應。 。
63
4.3.3
Select...Case...End
Select決策
• 當狀況不僅為True與False兩種時,除了使用多個或巢狀式
If…Then…Else…決策敘述之外,我們還可以使用Select…Case…多向決
策敘述。Select…Case…可以使得程式碼看起來更加來得清楚。使用
Select…Case…來做決策,其語法如下所示。
– Select…Case…End Select語法:
Select…Case流程圖:
Select Case 運算式
Case 條件測試值1
……敘述區塊1……
Case 條件測試值2
……敘述區塊2……
:
:
Case 條件測試值n
……敘述區塊n……
[Case Else
……敘述區塊……]
End Select
64
4.3.3
Select...Case...End
Select決策
•
【語法說明】:
– (1) Select的每一個Case跟隨著一個條件測試值,當中的敘述區塊代
表當『運算式=條件測試值』時,所要執行的敘述區塊。而Case Else
之後不跟隨條件值,其中的敘述區塊則是代表當『運算式不等於任何
一個條件測試值』時所要執行的敘述區塊。因此,Case Else可有可
無,若沒有Case Else,則當運算式不等於任何一個條件測試值的時
候,整個Select Case敘述就不會執行任何的程式碼。
– (2) 運算式:可以為字串或數值運算式。
– (3) 條件測試值:條件測試值的資料型別必須與運算式的資料型別相
同。並且可使用『To』與『Is』關鍵字進行更彈性的比對。
– 【範例】
• Case "Y"
:測試值是否為大寫『Y』。
– 【範例】
• Case "xyz","XYZ" :測試值是否為『xyz』或『XYZ』字串。
65
4.3.3
Select...Case...End
Select決策
– 【範例】
• Case Is < 100
:測試值是否小於100。【此處的Is與物件比較
的Is不同】
– 【範例】
• Case –10,0,10
:測試值是否為-10或0或10。
– 【範例】
• Case -1,1 To 100
:測試值是否為-1或1或2或…或100。
• 範例4-4:
– 網站目錄 ASPNET\ch04\ch04_04\(檔案ch04_04.aspx)
– Step1:網頁介面設計如下(所有控制項皆採絕對定位),請先設定
名稱,然後設定屬性(其餘屬性參照屬性窗格)。
66
4.3.3
Select...Case...End
Select決策
67
4.3.3
Select...Case...End
Select決策
– Step2:撰寫BtnGrade_Click()事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
Protected Sub BtnGrade_Click(sender As Object, e As System.EventArgs)
Dim score As Integer
LblResult.Text = ""
If IsNumeric(TxtBoxInput.Text) And InStr(TxtBoxInput.Text, ".") = 0 Then
score = CInt(TxtBoxInput.Text)
68
4.3.3
Select...Case...End
Select決策
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Select Case score
Case Is < 60
LblResult.Text = "分數等級為丁等"
Case 60 To 69
LblResult.Text = "分數等級為丙等"
Case 70 To 79
LblResult.Text = "分數等級為乙等"
Case 80 To 89
LblResult.Text = "分數等級為甲等"
Case 90 To 99
LblResult.Text = "分數等級為優等"
Case 100
LblResult.Text = "完滿分數"
Case Else
LblResult.Text = "您輸入了不合法的分數"
End Select
Else
LblResult.Text = "您輸入了不合法的分數"
End If
End Sub
69
4.3.3
Select...Case...End
Select決策
• 範例說明:
–
–
–
–
–
–
–
–
(1)第13~28行:Select Case…End Select決策敘述的範圍。
(2)第14~15行:當符合第14行時(score<60),執行第15行之敘述。
(3)第16~17行:當符合第16行時(60≦score≦69),執行第17行之敘述。
(4)第18~19行:當符合第18行時(70≦score≦79),執行第19行之敘述。
(5)第20~21行:當符合第20行時(80≦score≦89),執行第21行之敘述。
(6)第22~23行:當符合第22行時(90≦score≦99),執行第23行之敘述。
(7)第24~25行:當符合第24行時(score=100),執行第25行之敘述。
(8)第26~27行:當不符合上述任何一個條件時(即score>100時),執行第27
行之敘述。
– (9)第12行透過CInt()將文字方塊內的字串轉換為整數設定給score。而為了防
止使用者輸入非整數的數值,因此在第11行先行判斷。
70
4.3.3
Select...Case...End
Select決策
– (10)第11行的判斷式必須在兩個條件都成立下,結果才會為True。
IsNumeric()是用來判斷字串是否為數值,在前面範例中已經說明。而
InStr()則是用來找出子字串的位置,其語法如下:
Integer InStr(String str1,String str2)
' 尋找str2在str1中的位置,若找不到則回傳0
– (11)若TxtBoxInput.Text非數值資料,則IsNumeric()回傳False,整個
條件運算式也將是False。若TxtBoxInput.Text是數值資料,但包含小
數點(例如6.5),則雖然IsNumeric()回傳True,但InStr()將回傳非0
值。故整個條件運算式仍是False。所以第11行可以用來判斷字串格
式是否為整數。事實上,若配合後面章節介紹的驗證控制項,就不必
進行這些檢查了。
71
4.3.3
Select...Case...End
Select決策
– Step3:執行程式。
【註】除了上述的幾種決策敘述外,Try...Catch...Finally敘述也屬於決策敘述,
但它是專門用於例外處理,故在本章中先不介紹。
72
4.3.4
For…Next迴圈
• 迴圈是程式語言另一項重要的設計,它可以重複不停的做某些動作直到某
個條件成立時,動作才會停止。在VB中提供了多種的迴圈,我們首先介
紹For…Next迴圈。
For 次數 = 1 To 10
總和=總和+次數
Next
– 在上面的小範例中,迴圈一共會被執行10次,因此『總和=總和+次數』
也總共會被執行10次。
– 最開始「次數」值為1,每次重複執行迴圈時,迴圈的計數變數「次
數」值都會加1
– 所以如果變數「總和」一開始指定為0的話,當迴圈執行完畢,「總
和」值就會是1~10的總和55。
73
4.3.4
For…Next迴圈
• For…Next迴圈執行的詳細步驟如下:
– Step1:判斷迴圈計數變數是否大於終值,若是則跳出迴圈,若不是
則進入迴圈中,執行迴圈敘述。
– Step2:執行迴圈敘述。
– Step3:迴圈敘述執行完畢。
– Step4:迴圈計數變數加1。
• (使用Step N時,將迴圈計數變數值加N)
– Step5:回到Step1。
74
4.3.4
For…Next迴圈
• 如果我們不想把迴圈計數變數每次加1,而是每次增加或減少其他種的變
化量(例如+2),則只要在For該列程式最後加上一個Step N即可,其中
N值就是代表迴圈計數變數的加法變化量(減法時使用負值即可)。
– 例如,我們將上面的小範例改寫為每次+2的迴圈就變成了下面的樣子。
• 同樣地,如果在一開始將變數總和設為0,則迴圈執行完畢後,總和變數
值為1+3+5+7+9=25。
For 次數 = 1 To 10 Step 2
總和=總和+次數
Next
75
4.3.4
For…Next迴圈
• For…Next迴圈語法:
For 計數變數 [ As 資料型別] = 變數初值 To變數終值 [Step 計數變數增量]
………迴圈內的敘述區塊………
Next [計數變數]
• 【說明】
– (1) [計數變數]可省略。
– (2)若計數變數已宣告過,則[ As 資料型別]
可以省略,若在迴圈開始時宣告,則計數
變數離開迴圈後就無法使用。
– (3)另外還有一種可以使用於陣列的類似迴
圈,稱為『For Each…Next』迴圈,我們
將於下一節再做介紹。
– (4)對應流程圖如下:
76
4.3.4
For…Next迴圈
– Exit For
• 除了讓For..Next迴圈依照上述的步驟執行完畢之外,我們還可以強制讓迴
圈在計數變數尚超過終值之前就跳出迴圈,強制跳出迴圈的指令為Exit
For。
– Continue For
• 除了Exit For之外,另一個可以略過迴圈內敘述的指令為Continue For,
它會立即跳回迴圈的開頭,並執行增量,然後依照是否達到終值,決定是
否繼續執行迴圈內敘述。
• 換句話說,Continue For可以跳過本次迴圈內尚未執行的剩餘敘述。
• 範例4-5:
– 網站目錄 ASPNET\ch04\ch04_05\(檔案ch04_05.aspx)
– Step1:網頁介面設計如下(所有控制項皆採絕對定位),請先設定名稱,然
後設定屬性(其餘屬性參照屬性窗格)。
77
4.3.4
For…Next迴圈
78
4.3.4
For…Next迴圈
– Step2:撰寫BtnOddSum1_Click()事件程序碼如下:
• 程式部分內容:
79
4.3.4
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
For…Next迴圈
Protected Sub BtnOddSum1_Click(sender As Object, e As System.EventArgs)
Dim sum As Integer
LblResult.Text = ""
If IsNumeric(TxtBoxInput.Text) And InStr(TxtBoxInput.Text, ".") = 0 Then
sum = 0
For I As Integer = 1 To CInt(TxtBoxInput.Text) Step 1
If I Mod 2 = 1 Then
sum = sum + I
LblResult.Text = LblResult.Text & I & " "
End If
Next I
LblResult.Text = LblResult.Text & "總和為 " & sum
Else
LblResult.Text = "請輸入正整數"
End If
End Sub
80
4.3.4
For…Next迴圈
– 範例說明:
• (1)第13~18行:For…Next迴圈內的敘述區塊(第14~17行)會重
覆執行CInt(TxtBoxInput.Text)次。迴圈變數I的初值為1,每次重覆
迴圈時I值皆遞增1。
• (2)第15~16行位於If…Then敘述區塊內,只有當I值為奇數時才會
被執行,因此次數少了一半。
• (3)本範例第13行的「Step 1」可省略,因為內定為遞增1。第18行
可改寫為「Next」。
• (4)若擔心出現負整數,則第11行還要以And加上
InStr(TxtBoxInput.Text, "-") = 0的條件。
81
4.3.4
For…Next迴圈
– Step3:撰寫BtnOddSum2_Click()事件程序碼如下:(以Step方式改寫)
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Protected Sub BtnOddSum2_Click(sender As Object, e As System.EventArgs)
Dim sum As Integer
LblResult.Text = ""
If IsNumeric(TxtBoxInput.Text) And InStr(TxtBoxInput.Text, ".") = 0 Then
sum = 0
For I As Integer = 1 To CInt(TxtBoxInput.Text) Step 2
sum = sum + I
LblResult.Text = LblResult.Text & I & " "
Next I
LblResult.Text = LblResult.Text & "總和為 " & sum
Else
LblResult.Text = "請輸入正整數"
End If
End Sub
82
4.3.4
For…Next迴圈
– 範例說明:
• BtnOddSum2_Click()的功能和BtnOddSum1_Click()相同。只不過
我們將增量改為2(第31行的Step 2),故迴圈內不需要判斷I是否
為奇數。
83
4.3.4
For…Next迴圈
– Step4:撰寫BtnOddSum3_Click()事件程序碼如下:(以Continue For方式改
寫)
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Protected Sub BtnOddSum3_Click(sender As Object, e As System.EventArgs)
Dim sum As Integer
LblResult.Text = ""
If IsNumeric(TxtBoxInput.Text) And InStr(TxtBoxInput.Text, ".") = 0 Then
sum = 0
For I As Integer = 1 To CInt(TxtBoxInput.Text) Step 1
If I Mod 2 <> 1 Then Continue For
sum = sum + I
LblResult.Text = LblResult.Text & I & " "
Next I
LblResult.Text = LblResult.Text & "總和為 " & sum
Else
LblResult.Text = "請輸入正整數"
End If
End Sub
84
4.3.4
For…Next迴圈
– 範例說明:
• BtnOddSum3_Click()的功能也和BtnOddSum1_Click()相同。只不
過我們利用Continue For略過第49~50行的執行,故只有當I為奇數
時,第49~50行才會被執行。
– Step5:執行程式。
85
86
4.3.4
For…Next迴圈
• 巢狀式迴圈
– 迴圈內的敘述區塊可以包含各類敘述,當然也可以包含另一個迴圈敘
述,所謂『巢狀式迴圈』就是迴圈裡面包含其他的內層迴圈。『巢狀式
迴圈』通常可以用來處理二維以上的表格(例如:九九乘法表)或是
具規則性的推導公式(例如:排列組合、樂透組合等等)。
• 範例4-6:
– 網站目錄 ASPNET\ch04\ch04_06\(檔案ch04_06.aspx)
– Step1:網頁介面設計如下(所有控制項皆採相對定位),請先設定
名稱,然後設定屬性(其餘屬性參照屬性窗格)。
87
4.3.4
For…Next迴圈
88
4.3.4
For…Next迴圈
– Step2:撰寫BtnRun99_Click()事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
18
19
Protected Sub BtnRun99_Click(sender As Object, e As System.EventArgs)
Dim I, J As Integer
Dim outputStr As String = ""
LblResult.Text = "九九乘法表" & "<br />"
For I = 1 To 9
For J = 1 To 9
outputStr &= "&nbsp;&nbsp;" & I & "*" & J & "=" & (I * J)
If (I * J) < 10 Then outputStr &= "&nbsp;&nbsp;" '補足空白欄位
Next J
outputStr &= "<br />"
Next I
LblResult.Text &= outputStr
End Sub
89
4.3.4
For…Next迴圈
• 範例說明:
– (1)第11~17行:外層迴圈,將重複執行9次。(第16行將被執行9次)
– (2)第12~15行:內層迴圈,單獨來看內層迴圈也會重複執行9次。但
由於位於外層迴圈之內,因此一共會被執行9*9=81次。(第13~14行
將被執行81次)
– (3)我們在迴圈外就宣告了I,J變數,故在迴圈時不必指定其資料型別。
– (4)值得注意的是,在第13行我們使用『&』來串接字串,但其中有些
資料為Integer型別,不過編譯器仍會將之以字串來串連。
– (5)我們使用"&nbsp;&nbsp;"來表示兩個空白字元,&nbsp;是HTML的
空白字元,否則瀏覽器會忽視以【space】鍵所造成的兩個以上空白
字元。
90
4.3.4
For…Next迴圈
– (6)第14行是要將某些不足兩位數的結果對齊,故多加上空白字元。事
實上,我們並不建議使用空白字元對齊欄位,通常網頁設計是使用表
格來對齊欄位資料(並將表格框線寬度設為0)。
– Step3:執行程式。
91
4.3.5 While...End While條件式
迴圈
• 在For…Next迴圈中,我們必須設定迴圈計數變數的初值與結束值,若不
使用Exit For指令,則在迴圈一開始被執行的時候就可以決定迴圈內部敘
述區塊的執行次數。
– 因此For…Next迴圈一般用在與數字相關的運算。但是並非所有的狀況都適合
用For…Next迴圈來撰寫。
• 例如我們希望程式一直重複做某件事,直到某個條件成立為止,而非重複
執行固定的次數。這個時候,我們就應該採用條件式迴圈。
• VB的條件式迴圈分為兩大類:While...End While與Do...Loop
– 其中Do…Loop又分為許多種類。
– 在本小節中,我們先介紹While...End While條件式迴圈。
92
4.3.5 While...End While條件式
迴圈
• While…End While迴圈語法:
While 條件運算式
⋯敘述區塊⋯
[Exit While]
[Continue While]
End While
• 【功能】:
– (1)執行迴圈前先檢查條件運算式是否為True,若為True則進入迴圈(執行
迴圈內的敘述區塊),否則離開迴圈。
– (2)迴圈內敘述區塊執行完畢,將重新測試條件運算式,若仍為True則再執
行迴圈內敘述區塊,若為False則跳離迴圈。如此週而復始,直到『條件運
算式』為False時,才跳離迴圈。其流程圖如右。
– (3)Exit While是用來立即跳出迴圈。
– (4)Continue While是用來立即跳至迴圈開頭處。
93
4.3.5 While...End While條件式
迴圈
• 【範例4-7】:
– 使用While...End While條件式迴圈撰寫一個根
據輾轉相除法求兩數最大公因數的程式。輾轉
相除法範例如右:
• 範例4-7:
– 網站目錄 ASPNET\ch04\ch04_07\(檔案
ch04_07.aspx)
– Step1:網頁介面設計如下(所有控制項皆採絕
對定位),請先設定名稱,然後設定屬性(其
餘還包含多個標籤控制項,其屬性參照屬性窗
格)。
94
– Step2:撰寫BtnCompute_Click()事件程序碼如下:
• 程式部分內容:
95
4.3.5 While...End While條件式
迴圈
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Protected Sub BtnCompute_Click(sender As Object, e As System.EventArgs)
Dim A, B, Temp As Integer
'若需判斷輸入是否為正整數,請自行參考前面範例
A = CInt(TxtBoxA.Text)
B = CInt(TxtBoxB.Text)
If A < B Then
Temp = A : A = B : B = Temp '對調A與B的值
End If
While A <> 0
A = A Mod B
If A <> 0 Then
Temp = A : A = B : B = Temp '對調A與B的值
End If
End While
LblResult.Text = CStr(B)
End Sub
96
4.3.5 While...End While條件式
迴圈
• 範例說明:
– (1) 第15行:使用了『Temp = A : A = B : B = Temp』的片段程式,目的是為
了將A與B的值對調(將較大值放在A),否則將更難撰寫輾轉相除法的程式
(第21行也是如此)。而由於VB是以一行為一個運算式敘述單位,若要將多
個運算式敘述單位放在一行來撰寫,則中間必須以『:』加以區隔。
– (2) 第18~23行:此處出現了一個While…End While迴圈,迴圈執行的次數完
全依照A的變數值變化決定,除非A的變數值為0,否則迴圈將一直重複執行。
– (3)本範例所使用的輾轉相除法求最大公因數,非常適合用While…End While
迴圈來撰寫,如果強迫要使用For…Next迴圈撰寫的話,將會發現困難了許多,
讀者可以自行試試看。
– (4)本範例不再檢查輸入是否正確,我們假設使用者輸入的資料都是預想中的
正確資料,而對於其他錯誤情形,我們會在後面章節中,採用驗證控制項來
設定,或者採用例外狀況處理。若您還是想要檢查輸入的正確性,請自行參
閱前面的範例。
97
4.3.5 While...End While條件式
迴圈
– Step3:執行程式。
• 【程式執行結果】:
98
4.3.6
Do...Loop條件式迴圈
• 一般程式語言除了提供前測性質While迴圈之外,還會提供Do While後測
性質的迴圈。VB當然也提供了後測性質的迴圈,但由於發展的歷史因素,
VB提供的條件式迴圈多達6種,去除上一小節介紹的While迴圈,其餘種
類的迴圈,VB稱之為Do…Loop迴圈,並可以區分為下列五種:
– 1. 前測式迴圈一:Do While…Loop
• (功能與While… End While迴圈完全相同)
– 2. 前測式迴圈二:Do Until…Loop
– 3. 後測式迴圈一:Do…Loop While
• (功能類似於C++/Java的do-while迴圈)
– 4. 後測式迴圈二:Do…Loop Until
– 5.無窮迴圈:Do…Loop
• 以下是各種迴圈的語法及流程圖:
99
4.3.6
Do...Loop條件式迴圈
• Do While…Loop前測式迴圈
– Do While…Loop迴圈語法:
Do While…Loop迴圈流程圖:
Do While 條件運算式
…敘述區塊…
[Exit Do]
[Continue Do]
Loop
• 【功能】:
– 功能與While… End While迴圈完全相同,只有關鍵字的格式不同。
100
4.3.6
•
Do...Loop條件式迴圈
Do Until…Loop前測式迴圈
– Do Until…Loop迴圈語法:
Do Until…Loop迴圈流程圖:
Do Until 條件運算式
…敘述區塊…
[Exit Do]
[Continue Do]
Loop
•
【功能】:(條件恰與Do While…Loop迴圈相反)
– (1)執行迴圈前先檢查條件運算式是否為False,若為False則進入迴圈(執行迴圈內的敘
述區塊),否則離開迴圈。
– (2)迴圈內敘述區塊執行完畢,將重新測試條件運算式,若仍為False則再執行迴圈內敘
述區塊,若為True則跳離迴圈。如此週而復始,直到『條件運算式』為True時,才跳離
迴圈。其流程圖如上。
– (3)Exit Do是用來立即跳出迴圈。
– (4)Continue Do是用來立即跳至迴圈開頭處。
101
4.3.6
•
Do...Loop條件式迴圈
Do…Loop While後測式迴圈
– Do…Loop While迴圈語法:
Do…Loop While迴圈流程圖:
Do
…敘述區塊…
[Exit Do]
[Continue Do]
Loop While條件運算式
•
【功能】:(迴圈區塊至少執行一次)
– 1. 先執行敘述區塊一次,然後才判斷『條件運算式』是否為True,若為True,則再重
覆進入迴圈內執行敘述區塊;否則將離開迴圈,前往Loop While之後的下一個敘述繼續
執行。
– 2. 迴圈內敘述區塊執行完畢,將重新測試『條件運算式』是否為True,若仍為True,
則再執行迴圈內敘述區塊,若為False則跳離迴圈。如此週而復始,直到『條件運算式』
為False,才跳離迴圈。
– 3. 迴圈內的敘述區塊至少會被執行一次以上。
102
4.3.6
•
Do...Loop條件式迴圈
Do…Loop Until後測式迴圈
– Do…Loop Until迴圈語法:
Do…Loop Until迴圈流程圖:
• (條件恰與Do…Loop While迴圈相反)
Do
…敘述區塊…
[Exit Do]
[Continue Do]
Loop Until條件式
•
【功能】:
– 1. 先執行敘述區塊一次,然後才判斷『條件運算式』是否為False,若為False,則再重
覆進入迴圈內執行敘述區塊;否則將離開迴圈,前往Loop Until之後的下一個敘述繼續
執行。
– 2. 迴圈內敘述區塊執行完畢,將重新測試『條件運算式』是否為False,若仍為False,
則再執行迴圈內敘述區塊,若為True則跳離迴圈。如此週而復始,直到『條件運算式』
為True,才跳離迴圈。
103
4.3.6
Do...Loop條件式迴圈
• Do…Loop 無窮迴圈語法
– Do…Loop 無窮迴圈語法:
Do…Loop無窮迴圈流程圖:
Do
…敘述區塊…
[Exit Do]
[Continue Do]
Loop
– 【功能】:由於迴圈的前後都沒有提供『條件運算式』做為判斷依據,因此
迴圈一旦執行,就不會停止(除非使用Exit Do敘述強制跳離迴圈)。
• 雖然VB提供了那麼多的條件式迴圈,但一般只需要使用While… End
While作為前測式迴圈以及Do…Loop While作為後測式迴圈即可。
– 而無窮迴圈也可以直接設定條件運算式為布林常數True就可以達到。
104
4.3.6
Do...Loop條件式迴圈
• 【範例4-8】:使用條件式迴圈改寫範例4-5的奇數和程式。
• 範例4-8:
– 網站目錄 ASPNET\ch04\ch04_08\(檔案ch04_08.aspx)
– Step1:網頁介面設計如下(所有控制項皆採絕對定位),請先設定名稱,然
後在設定屬性(其餘屬性參照屬性窗格)。
105
4.3.6
Do...Loop條件式迴圈
– Step2:撰寫BtnOddSum1_Click()~BtnOddSum5_Click()等五個事件程序碼,
以下節錄其中最常使用的(前測)Do While…Loop、(後測)Do…Loop While、
(無窮)Do…Loop等迴圈如下:(其餘請自行參閱檔案)
106
4.3.6
Do...Loop條件式迴圈
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Protected Sub BtnOddSum1_Click(sender As Object, e As System.EventArgs)
Dim I, sum As Integer
LblResult.Text = ""
'若需判斷輸入是否正確的正整數,請參考前面範例
sum = 0
I=0
Do While (I <= CInt(TxtBoxInput.Text))
If I Mod 2 = 1 Then
sum = sum + I
LblResult.Text = LblResult.Text & I & " "
End If
I=I+1
Loop
LblResult.Text = LblResult.Text & "總和為 " & sum
End Sub
107
4.3.6
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Do...Loop條件式迴圈
Protected Sub BtnOddSum2_Click(sender As Object, e As System.EventArgs)
Dim I, sum As Integer
LblResult.Text = ""
'若需判斷輸入是否正確的正整數,請參考前面範例
sum = 0
I=0
Do
If I Mod 2 = 1 Then
sum = sum + I
LblResult.Text = LblResult.Text & I & " "
End If
I=I+1
Loop While (I <= CInt(TxtBoxInput.Text))
LblResult.Text = LblResult.Text & "總和為 " & sum
End Sub
108
4.3.6
:
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Do...Loop條件式迴圈
Protected Sub BtnOddSum5_Click(sender As Object, e As System.EventArgs)
Dim I, sum As Integer
LblResult.Text = ""
sum = 0
I=0
Do
If I Mod 2 = 1 Then
sum = sum + I
LblResult.Text = LblResult.Text & I & " "
End If
I=I+1
If I > CInt(TxtBoxInput.Text) Then Exit Do '跳出迴圈
Loop
LblResult.Text = LblResult.Text & "總和為 " & sum
End Sub
109
4.3.6
Do...Loop條件式迴圈
– 範例說明:
• (1)第14~20行:Do While…Loop前測式迴圈,只要I≦N(N為輸入
值)就會一直執行。
• (2)第31~37行:Do…Loop While後測式迴圈,迴圈至少執行一次,
並且只要I≦N(N為輸入值)就會一直執行。
• (3)第81~88行:Do…Loop 無窮迴圈,除非第87行成立而執行Exit
Do,否則迴圈會一直執行。
– Step3:執行程式。
• 【程式執行結果】:
110
111
4.4 陣列
• 陣列』是一群資料(通常是資料型別相同的資料)以一個名稱來代表的方
式。舉例來說,假設我們想要記錄每月的營業額,您當然可以使用
January、February、、、December等12個數值變數來儲存,但如果您
使用『陣列』來加以儲存的話,則可以只使用同一個「陣列名稱」即可,
例如:Month (12)。
– 當我們宣告Month(12)陣列時,Month就是「陣列名稱」,並且在記憶體中將
會保留13個連續位置分別存放Month(0)~Month(12)等13個陣列元素。
•
陣列中每個元件(稱之為陣列元素)相當於一個變數,我們只要透過『索引』,
就可以直接取得陣列的指定元素
– 例如:我們使用Month(1)~Month(12)來存放12個月份的營業額,當我們希望
取出8月份的營業額時,只要使用Month(8)當做變數名稱就可以輕鬆取出該元
素值。
– 因此,使用陣列可以免除大量變數命名的問題,使得程式具有較高的可讀性,
並且可搭配迴圈有效率地處理陣列元素的變化。
112
4.4 陣列
– 上述的Month(12)稱之為一維陣列,陣列若具有兩個索引稱為『二維陣列』、
具有三個索引稱為『三維陣列』,依此類推。
• 二維陣列的應用非常廣泛(僅次於一維陣列),您可以將二維陣列以數學
的矩陣來加以看待,也就是二維陣列是由列(Row)與行(Column)組
合而成,並且每一個元素恰恰落在某一特定的列及行。
113
4.4 陣列
• 我們可以用二維陣列來表示複雜的資料,例如使用橫列來表示各分公司的
營運狀況,直行表示各季的營業額,假設我們放棄第0列與第0行不使用,
則可以如下安排整間公司的總體營運狀況。
– 這樣的陣列為Trade (3,4),共有20個元素,但我們只使用了其中的12個元素。
114
4.4.1
宣告陣列-Dim敘述
• 宣告陣列也是使用Dim敘述,當陣列宣告完畢,我們就可以存取陣列中的
元素資料了,以下是陣列宣告語法:
語法:Dim 陣列名稱 (最大索引1 [,最大索引2 [.....]]) [As資料型別]
功能:宣告一維(二維、三維、、)陣列,以及元素的資料型別。
• 【語法說明】:
– 1. 陣列名稱:
• 陣列名稱的命名規定與變數命名規定相同,您應該盡量採用有意義的英文
字或組合字來代表該陣列的用途。
– 2. 最大索引:
• 最大索引決定了該陣列為1維陣列、2維陣列、、、。也決定了每一維度的
元素數目(也就是最大索引+1個元素)。舉例如下:(以下假設我們放棄
了元素0不使用)
115
4.4.1
宣告陣列-Dim敘述
– 【範例】:假設我們有12個月的營業額要記錄,您可以使用Month也可以使用Trade
(交易)做為陣列名稱,如下宣告一維陣列:
• Dim Trade (12) As Integer
↑
月份
– 經由上述宣告後,我們可以用Trade(7)來存放7月份的營業額。
– 【範例】:假設我們有兩年的每月營業額要記錄,則可以如下宣告二維陣列:
• Dim Trade (2 , 12) As Integer
↑ ↑
年 月份
– 經由上述宣告後,我們可以用Trade(2,7)來存放第2年7月份的營業額。
– 【範例】:假設我們有兩家公司兩年的每月營業額要記錄,則可以如下宣告三維陣列:
• Dim Trade (2 , 2 , 12) As Integer
↑ ↑
↑
公司 年 月份
– 經由上述宣告後,我們可以用Trade(1,2,7)存放第1家公司第2年7月份的營業額。
116
4.4.1
宣告陣列-Dim敘述
– 3. As 資料型別
• 『資料型別』對於陣列而言,其重要性遠比變數的資料型別來得重要許多,因為當
您宣告了陣列的資料型別之後,陣列中的每一個元素都將使用該資料型別
• 因此,若您省略了宣告資料型別,則陣列各元素的資料型別都將是Object,此時可
以存放各種不同的資料型別。
– 以下是各種常用的陣列基本資料型別宣告:
• (1) 【範例】Dim Trade1(12) As Integer '每個陣列元素的資料型別為Integer
• (2) 【範例】Dim Trade2(12) As Double '每個陣列元素的資料型別為Double
• (3) 【範例】Dim Item(12) As String
'每個陣列元素的資料型別為String
• (4) 【範例】Dim arr(12)
• 【說明】:arr陣列的每個陣列元素資料型別為Object,而它可以存放各種資料型別,
如下列兩個敘述是合法的,而雖然它提供了陣列元素不同資料型別的彈性,但一般
我們並不建議如此使用陣列。
arr(1) = 100
arr(2)="abc"
'arr(1)的資料型別是Integer
'arr(2)的資料型別是String
117
4.4.1
•
宣告陣列-Dim敘述
使用下界0宣告陣列
– 以往VB6可以宣告不同陣列的下界,但VB.NET只允許將陣列的下界宣告為0,因此您可
以依照下列語法宣告一維陣列:
Dim 陣列名稱(0 To 最大索引) [As資料型別]
– 【範例】
• Dim Trade1(0 To 12) As Integer
'效果等同於Dim Trade1(12) As Integer
118
4.4.1
•
宣告陣列-Dim敘述
宣告陣列初始值
– 宣告陣列時,可以同時設定陣列元素的初始值,一維陣列的陣列初始值宣告語法如下:
Dim 陣列名稱() [As資料型別] = { 陣列元素0之值, 陣列元素1之值, …,最後陣列元素之值}
– 【說明】
• 不需要設定陣列最大索引,因為編譯器可以由初始值的個數決定陣列元素個數。
– 【範例】
• Dim arr1() As Integer ={15,10,25} 'arr1(0)為15、arr1(1)為10、arr1(2)為25
– 【範例】
• Dim arr2() As String ={"abc","hello"} 'arr2(0)為"abc"、arr2(1)為"hello"
– 【範例】
• Dim arr3() ={"abc",123} 'arr3(0)為"abc"、arr3(1)為123,如果使用在上述的Month
或Trade時,可將第(0)個元素用來存放代表陣列意義的字串,但我們非常不建議使
用此語法。
119
4.4.1
宣告陣列-Dim敘述
• 二維陣列的陣列初始值宣告語法:
Dim 陣列名稱(,) [As資料型別] = { {第一維初始值設定},{第二維初始值設定}}
– 【範例】
• Dim arr4(,) As Integer ={{15,10,25},{4,6,8}}
– 陣列宣告時,若未設定陣列元素的初始值,則陣列元素的初始值會依照一般
變數初始值的規定,例如數值資料為0。
120
4.4.1
宣告陣列-Dim敘述
• 陣列長度
– 有些時候我們為了使用迴圈一一讀取陣列元素值,會希望知道陣列的長度
(元素個數),此時可以使用『陣列名稱.Length』取得陣列長度。您也可以
將Length視為陣列的一個屬性。範例如下:
– 【範例】
• Dim arr1(10)As String
• Dim arr2(1,2) As String
• L1=arr1.Length
'L1是11,因為(10+1)=11
• L2=arr2.Length
'L2是6,因為(1+1)*(2+1)=6
• 不規則陣列
– 有時候對於多維陣列而言,我們可能希望每一維的長度不同,例如以月份作
為第一維,而每一月的日期作為第二維,則第一維長度為12,但第二維長度
則不一定,此時,必須宣告一維陣列,但陣列元素也宣告為陣列才能達到不
規則陣列的目的。由於牽涉較深,有興趣的讀者請自行參閱VB.NET專書。本
書極少使用此種陣列。
121
4.4.1
宣告陣列-Dim敘述
• 【範例4-9】:
– 使用階層公式存放陣列元素,並尋找陣列元素中,第一個超過(含)100,000
的索引。
• 範例4-9:
– 網站目錄 ASPNET\ch04\ch04_09\(檔案ch04_09.aspx)
– Step1:網頁介面設計如下(所有控制項皆採相對定位),請先設定名稱,然
後設定屬性(其餘屬性參照屬性窗格)。
122
4.4.1
宣告陣列-Dim敘述
– Step2:撰寫BtnRunFac_Click()事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
Protected Sub BtnRunFac_Click(sender As Object, e As System.EventArgs)
Dim fac(12) As Long '宣告陣列,陣列元素資料型別為Long
Dim I As Integer
Dim outputStr As String = "fac(0)=0!=1<br />fac(1)=1!=1<br />"
LblResult.Text = ""
123
13
14
15
16
17
18
19
20
21
22
23
24
25
fac(0) = 1
'設定fac(0)值為1
For I = 1 To fac.Length - 1
'最大索引應該是fac.Length-1
fac(I) = fac(I - 1) * I
outputStr &= " fac(" & I & ")=" & I & "!=" & fac(I) & "<br />"
Next I
For I = 1 To fac.Length - 1
If (fac(I) >= 100000) Then Exit For
Next I
outputStr &= "fac(" & I & ")=" & I & "!已經大於等於100000"
LblResult.Text &= outputStr
End Sub
– 範例說明:
• (1)第8行:宣告一維陣列fac(12),陣列元素資料型別為Long,並
未設定初始值,故全為0。
• (2)第13行:設定fac(0)的元素值為1。
• (3)第15~18行:利用迴圈設定fac(1)~fac(12)的元素值。其中
fac.Length的值為13,因為共有13個元素,故迴圈計數最大值設為
fac.Length-1。
124
4.4.1
宣告陣列-Dim敘述
• (4)第20~22行:利用迴圈尋找
元素值大於等於100000的元素,
當成立時,跳出迴圈,故I將是
該元素的索引。
– Step3:執行程式。
125
4.4.2
圈
For Each ...Next 陣列迴
• 陣列與迴圈息息相關,例如我們可以透過一個迴圈將陣列的
每一個元素值讀出或存入新值(如範例4-9),此時常需要藉
助陣列的Length屬性來完成。若不小心存取超過陣列索引最
大值的元素時,則會發生錯誤。
– 要避免發生這樣的錯誤,我們可以透過VB提供的另一種迴圈敘述For
Each…Next來取出陣列元素。
• For Each…Next迴圈,稱之為『陣列迴圈』,它會依照陣列元素的個數,
決定迴圈內的敘述區塊要重覆執行幾次,其語法如下:
語法:For Each 變數 [As 資料型別] In 陣列名稱
[敘述區段]
[Exit For]
[Continue For]
Next [變數]
功能:依照陣列元素的個數,決定重複執行敘述區段的次數。
126
4.4.2
圈
For Each ...Next 陣列迴
• 【語法說明】:
– 1. 變數:變數的資料型別應與陣列元素相容(至少能夠自動轉型)。
– 2. 陣列的元素個數決定了迴圈內的敘述區塊重覆執行的次數。
– 3. 每次重覆迴圈時,變數值會等於某一個陣列元素值,並且會由陣列(0)開始,
依序指定給該變數。
– 4. 迴圈執行完畢會繼續執行緊接在Next之後的敘述。
• 【範例4-10】:
– 將費氏數列的值存放於陣列中,使用For Each…Next迴圈將其取出並顯示。
• 範例4-10:
– 網站目錄 ASPNET\ch04\ch04_10\(檔案ch04_10.aspx)
– Step1:網頁介面設計如下(所有控制項皆採相對定位),請先設定名稱,然
後在設定屬性(其餘屬性參照屬性窗格)。
127
4.4.2
圈
For Each ...Next 陣列迴
128
4.4.2
圈
For Each ...Next 陣列迴
– Step2:撰寫BtnRunFac_Click()事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
18
Protected Sub BtnRunFib_Click(sender As Object, e As System.EventArgs)
Dim Fib() As Integer = {0, 1, 1, 2, 3, 5, 8, 13, 21}
Dim outputStr As String = "費氏數列<br />"
LblResult.Text = ""
For Each f As Integer In Fib
outputStr &= f & " "
Next f
LblResult.Text &= outputStr
End Sub
129
4.4.2
圈
For Each ...Next 陣列迴
– 範例說明:
• 第13~15行:每次執行迴圈時將一一取出Fib陣列的元素並指定給
變數f。
– Step3:執行程式。
【註】與陣列有關的敘述還有很多,例如ReDim等,但已超出本書範圍,有
興趣的讀者,請自行參閱VB專書。
130
4.5 程序
• 在結構化程式設計中,我們通常會將具有某種特定功能(解決某一子問題)
或常常重覆出現的敘述區塊獨立出來,成為一個程式單元,此時我們會將
之賦予一個名稱,以便於其他程式呼叫及使用
– 此程式單元一般稱之為『副程式』(Subprogram),而在VB中則稱之為程序
(Procedure)。
• 程序的特點如下:
– 1. 程序是模組化的一大特色,將一個大的應用程式切割為數個副程式,就可
以由許多的程式設計師分工撰寫副程式,如此一來,可以加快程式的開發速
度,不過在切割功能以及撰寫之前,必須討論出一定的規格,以免發生不協
調的狀況。
– 2. 程序擁有屬於自己的名稱,除透過多載機制,否則不可存在兩個相同名稱
的程序。
– 3. 程序內宣告的變數為區域變數,換句話說,在不同程序內可以使用相同的
變數名稱,因為該變數只會在所屬的程序中生效。
– 4. 程序最好具有特定功能,並且程序的程式碼應該越簡單越好,如此才能夠
提高程式的可讀性並有利於除錯與日後的維護。
131
4.5 程序
• 在VB中,程序可以分為Sub程序、Function程序(有回傳
值)、Property程序、Operator程序等四類。
– 但本章僅會使用其中的Sub程序、Function程序(有回傳值)
– 至於Property程序是用來定義類別的屬性,我們會在下一章說明何謂
VB類別的屬性;而Operator程序則是用來自行定義運算子的運算細節,
本書並不會使用這種語法,讀者自行參閱VB專書。
• Sub…End Sub程序及Function…End Function程序最主要的
差別在於
– Sub…End Sub程序不會回傳任何資料給呼叫它的程式
– 而Function…End Function程序則會回傳資料。
132
4.5.1
Sub程序
• Sub程序的語法如下:
[修飾字] Sub 程序名稱 [(參數清單串列)]
[程式區塊]
[Exit Sub]
End Sub
• 【語法說明】:
– 1. Sub程序可以由「Sub」、或「修飾字 Sub」做為開頭,結尾則是End Sub。
– 2. 修飾字可以用來宣告存取層級或多載、覆寫、共用及遮蔽等相關資訊。由
於大部分牽涉到物件導向機制,此處暫時不提。
– 3. 程序名稱:程序命名方式與變數名稱相同。除了使用修飾字之外,不可出
現兩個相同名稱的程序。
133
4.5.1
Sub程序
– 4. 參數清單串列(parameter list):參數(parameter)是用來接收由呼叫敘述傳
送過來的某些資料,每個參數之間必須使用逗號『,』加以分開,每一個參數
的語法如下(與宣告一般變數類似):
[Optional] [ByVal | ByRef] [ParamArray] 參數名稱 As 資料型別
• (1)Optional是代表使用選擇性參數,此時可以事先指定參數的預設值。
• (2)ByVal代表使用傳值呼叫,也是VB的預設程序呼叫方式(可省略ByVal,
例如VWD2010的事件程序即省略ByVal,但VWD2008則未省略ByVal,
但兩者效果相同)。ByRef代表使用傳參考呼叫。本書僅使用ByVal傳值
呼叫,也就是當呼叫程序時,僅將其值傳給被呼叫程序,此後呼叫方的引
數與被呼叫方的參數就互不影響。
• (3)ParamArray是用在不確定數目的參數時使用,它以一維陣列進行接收,
並且必須放在參數清單串列的最後,同時也必須與ByVal共用。
• (4) 參數名稱:參數是用來接收由呼叫敘述傳送過來的某些資料,每個參
數之間必須使用逗號『,』加以分開。
134
4.5.1
Sub程序
– 5. 呼叫程序時,可以使用Call 敘述來呼叫,也可以直接呼叫,換句話
說,Sub程序是一個「被呼叫的程序」(Called procedure)。呼叫
Sub程序的語法如下:
Call 程序名稱 [(引數清單串列)]
或
程序名稱 [(引數清單串列)]
• (1)引數清單串列(argument list)包含許多引數,引數(argument)代
表您在呼叫程序時傳給被呼叫程序參數的值。
• (2)每一個引數會對應至清單中相同位置的參數。
• (3)每個引數都是一個運算式,可包含變數、符號常數或常值。但
必須能夠將它轉換成參數型別。明顯地,引數也可以是單一個變
數,但此變數不需要與參數同名。
135
4.5.1
Sub程序
– 6.正常狀況下,程序會一直執行,直到遇見End Sub為止才返回原本
呼叫該程序的下一個敘述。但在程序中,也可以使用Exit Sub,強迫
立即返回原本呼叫該程序的下一個敘述。
– 7.Sub程序的宣告不應出現在某個程序內。
• 【範例4-11】
– 修改範例4-7,將計算最大公因數撰寫為一個Sub程序。
• 範例4-11:
– 網站目錄 ASPNET\ch04\ch04_11\(檔案ch04_11.aspx)
– Step1:網頁介面設計同範例4-7。
– Step2:撰寫BtnCompute_Click()事件程序與GCD()程序碼如下:
136
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Protected Sub BtnCompute_Click(sender As Object, e As System.EventArgs)
Dim X, Y As Integer
'若需判斷輸入是否為正整數,請自行參考前面範例
X = CInt(TxtBoxA.Text)
Y = CInt(TxtBoxB.Text)
GCD(X, Y)
'呼叫GCD程序
LblResult.Text &= " 為" & X & "與" & Y & "的最大公因數"
End Sub
Sub GCD(ByVal A As Integer, ByVal B As Integer)
Dim Temp As Integer
If A=0 Or B=0 Then Exit Sub
If A < B Then
Temp = A : A = B : B = Temp '對調A與B的值
End If
While A <> 0
A = A Mod B
If A <> 0 Then
Temp = A : A = B : B = Temp '對調A與B的值
End If
End While
LblResult.Text = CStr(B)
End Sub
137
4.5.1
–
Sub程序
範例說明:
• (1)第16~30行:此處定義了一個Sub GCD程序,請注意,它並非定義於
BtnCompute_Click()事件程序內。
• (2)第12行:呼叫GCD程序並傳入兩個引數X,Y。
• (3) 當按下按鈕後,BtnCompute_Click()開始執行,而執行到第12行時,
則呼叫GCD程序,並傳入兩個引數(假設為792與102),接下來會執
行第16~30行,執行第16行時,A會接收第一個引數值(假設為792),
B會接受第二個引數值(假設為102)。由於第18行的If不成立,所以不
會執行Exit Sub,故GCD會完整執行到第29行才結束,結束後則回到第
13行繼續執行,所以您會看到執行結果中,標籤文字後方又多了一些文
字
– 同時您也可以注意到,雖然GCD程序內的A,B曾被改變過,但呼叫
方的X,Y值並未被改變過,因為呼叫GCD時,採用的是傳值呼叫
ByVal。
• (4)在GCD程序內不需要宣告A,B,因為參數可以當作是區域變數來使用。
138
4.5.1
Sub程序
– Step3:執行程式。
139
4.5.2
Function程序
• Function程序與Sub程序最大的差別在於Function程序可以回傳『一個』
程序執行結果,而Sub則無法回傳任何值。Function程序的語法如下:
[修飾字] Function 程序名稱 [(參數清單串列)] [As 回傳值資料型別]
[程式區塊]
[Exit Function]
Return 運算式
End Function
• 【語法說明】:
– 1. 程序名稱前面的[修飾字]功能與Sub程序相同。程序名稱的規定也與Sub程
序相同。
– 2. 一般我們也將Function程序稱之為『函式』。
– 3. 最後面最好明確使用As宣告回傳值的資料型別。
– 4. 回傳結果時,使用的是Return,其後可接一個運算式,但回傳的結果將會
是運算式的運算結果。
140
4.5.2
Function程序
– 5.Return不但能夠回傳值,並且也會立即返回原本呼叫該程序的下一
個敘述,因此常常會將Return敘述放在最後。
– 6.程序內應該至少包含一個Return敘述,雖然未包含Return敘述仍可
通過編譯,但將無法收到回傳值。同時,程序內也允許出現多個
Return敘述,但請注意Return敘述一旦執行,程序就會返回。
– 7.正常狀況下,程序會一直執行,直到遇見End Function為止才返回
原本呼叫該程序的下一個敘述。但在程序中,也可以使用Exit
Function,強迫立即返回,但一般我們都使用Return來達到此功能,
避免未回傳任何值就返回。
– 8.呼叫Function程序的方式如下:
變數名稱=程序名稱([引數清單串列])
• 【註】變數名稱是用來接收回傳值,該變數的資料型別必須與宣
告的回傳值資料型別相容。
141
4.5.2
Function程序
• 【範例4-12】
– 修改範例4-11,將計算最大公因數改寫為一個Function程序,並將求
得的最大公因數回傳給呼叫方。
• 範例4-12:
– 網站目錄 ASPNET\ch04\ch04_12\(檔案ch04_12.aspx)
– Step1:網頁介面設計同範例4-11。
– Step2:撰寫BtnCompute_Click()事件程序與GCD()程序碼如下:
7
8
Protected Sub BtnCompute_Click(sender As Object, e As System.EventArgs)
Dim X, Y, Result As Integer
142
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'若需判斷輸入是否為正整數,請自行參考前面範例
X = CInt(TxtBoxA.Text)
Y = CInt(TxtBoxB.Text)
Result = GCD(X, Y)
'呼叫GCD Function程序
LblResult.Text = CStr(Result)
LblResult.Text &= " 為" & X & "與" & Y & "的最大公因數"
End Sub
Function GCD(ByVal A As Integer, ByVal B As Integer) As Integer
Dim Temp As Integer
If A = 0 Or B = 0 Then Return 0
If A < B Then
Temp = A : A = B : B = Temp '對調A與B的值
End If
While A <> 0
A = A Mod B
If A <> 0 Then
Temp = A : A = B : B = Temp '對調A與B的值
End If
End While
Return B
'回傳計算結果並返回
End Function
143
4.5.2
Function程序
– 範例說明:
• (1)第17~32行:此處定義了一個Function GCD程序,請注意,它
也非定義於BtnCompute_Click()事件程序內。
• (2)第12行:呼叫GCD程序並傳入兩個引數X,Y,而回傳值由
Result接收。
• (3)當按下按鈕後,BtnCompute_Click()開始執行,而執行到第12
行時,則呼叫GCD程序,並傳入兩個引數,接下來會執行第
17~32行。若第19行的If不成立,就不會執行Result 0,此時GCD
會完整執行到第31行遇到Return敘述時才回傳B的值並返回,返回
後,Result接收到B的值然後執行第13~15行。
144
4.5.2
Function程序
– Step3:執行程式。
145
4.5.3
變數有效範圍
• 在上一個範例中,Temp被宣告在GCD程序中,而這就代表它是GCD程序
的一個區域變數 (Local Variable),層級是程序,故只有宣告變數的程序
才能使用(BtnCompute_Click程序就無法使用)。事實上,VB的變數可
以依照有效範圍(Scope或稱視野)分為四種層級,如下表:
146
4.5.3
變數有效範圍
– 其中區塊範圍是如選擇、迴圈與例外等區塊。
– 至於模組範圍,對於ASP.NET網頁而言,由於每一個網頁是一個類別,故宣
告於該網頁所有程序之外的變數,都屬於模組範圍(也就是在類別內宣告),
故該網頁的所有程序都可以使用。
– 至於命名空間,則留待5.2節介紹。
• 【範例4-13】
– 類別範圍的變數。
• 範例4-13:
– 網站目錄 ASPNET\ch04\ch04_13\(檔案ch04_13.aspx)
– Step1:網頁介面設計【略,請自行參閱檔案】:當中包含一個Button按鈕控
制項,名稱為Button1及一個Label標籤控制項,名稱為Label1。
– Step2:撰寫<script>內的程式碼如下:
147
4.5.3
變數有效範圍
• 程式部分內容:
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script runat="server">
Dim num As Integer
'Dim可改寫為Public,Private,Protected
Sub Addk(ByVal k As Integer)
num = num + k
End Sub
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Addk(3)
Addk(3)
num = num + 1
Label1.Text = "num=" & CStr(num)
End Sub
</script>
148
4.5.3
變數有效範圍
– 範例說明:
• (1)第9~11行:此處定義了一個Addk()程序。
• (2)第13~18行:此處定義了一個Button1_Click()事件程序。
• (3)第7行:此處宣告了一個變數num,未設定初始值,故為0。
• (4)當執行Button1_Click()事件程序時,會呼叫Addk(3)兩次,而Addk()內
則將num累加3。因此呼叫兩次後num為6,而控制權交還給
Button1_Click()之後,繼續在第16行將num加1,故第17行的num為7。您
可以注意到Addk()與Button1_Click()都能夠存取num變數,這是因為num
變數是一個在類別內定義的變數,所以類別內的程序都可以使用它。而類
別在哪裡呢?答案是整個.aspx檔案,因為它是一個繼承自Page的網頁類
別。
• (5)在執行結果中,不論您按下幾次【執行】鈕,num的值都是7,這代表
num變數值無法保存至下一次伺服器接受到請求時。這是因為,num其實
是網頁類別的欄位,對於每一個網頁物件而言,當網頁物件產生時,它就
被設定為0。而當伺服器接受到請求時網頁物件才會產生。當執行完畢而
送回時,網頁物件就消滅了。
149
4.5.3
變數有效範圍
– Step3:執行程式。
150
4.5.3
變數有效範圍
• 請注意,當程式執行離開其變數的範圍時,變數也將消失,
因此下次再執行時,變數值將無法保存上一次最後的值。
– 如果一定要保存的話,則應該使用Static來宣告靜態變數,但僅限於區
塊與程序使用。
• 【範例4-14】靜態變數。
• 範例4-14:
– 網站目錄 ASPNET\ch04\ch04_14\(檔案ch04_14.aspx)
– Step1:網頁介面設計【略,請自行參閱檔案】:當中包含一個Button按鈕控
制項,名稱為Button1及一個Label標籤控制項,名稱為Label1。
151
4.5.3
變數有效範圍
– Step2:撰寫Button1_Click()事件程序與Addk()程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
17
18
19
Function Addk(ByVal k As Integer) As Integer
Static Dim old As Integer
'請將Static去除,再執行一次
old = old + k
Return old
End Function
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Dim v As Integer
v = Addk(3)
v = Addk(3)
v = Addk(3)
Label1.Text = "v=" & CStr(v)
End Sub
152
4.5.3
變數有效範圍
– 範例說明:
• (1)第7~11行:此處定義了一個Function Addk(k)程序,其中第8行宣告了
一個靜態變數old。因此它能夠在Addk()執行完畢後,保留最後的值。
• (2)第14~17行:呼叫Addk(3)三次,第一次呼叫完畢,old的值為3,第二
次呼叫呼叫完畢,old的值為6,第三次呼叫呼叫完畢,old的值為9。故最
後v的值為9。您可以於執行結果中印證。
• (3)請將第8行的Static去除後存檔,再執行一次,您會發現,最後v的值為
3。這是因為old無法保留上次呼叫最後的值,而變成每一次呼叫都重新歸
0。
• (4)請恢復第8行的Static,然後存檔再重新執行,並且多按幾次【執行】
鈕,您會發現結果仍為9,而不會變成18、27…。這是因為當每一次伺服
器執行ASP.NET時,都是執行新產生的網頁物件(稱之為Page執行個
體),而不同的網頁物件間,並不會共用old變數。因為old變數仍屬於
Addk()程序的區域變數。
153
4.5.3
變數有效範圍
– Step3:執行程式。
154
4.5.4
•
遞迴程序
當一個程序呼叫自己時,稱之為程序的『遞迴呼叫』(recursive call),明確定
義如下:
– 遞迴呼叫:
一個程序經由直接或間接呼叫程序本身,稱之為程序的『遞迴呼叫』。例如:
• MySub1()呼叫MySub1()為直接遞迴呼叫
• MySub1()呼叫MySub2()且MySub2()呼叫MySub1()為間接遞迴呼叫。
•
VB允許程序的遞迴呼叫,通常遞迴程序可以輕鬆解決一些資訊領域常見的問題
(例如:樹狀圖的相關演算法),而且相當簡潔使人易懂,但在執行效率則略遜
一疇。
•
通常一個遞迴程序需符合下列兩個限制條件:
– (1)遞迴程序必須有邊界條件,當程序符合邊界條件時,就應該返回(可使用return或
Exit Sub強制返回)程序呼叫處。
– (2) 遞迴程序在邏輯上,必須使得程序漸漸往邊界條件移動,否則該程序將無法停止呼
叫,而無窮地執行下去,由於每次的程序呼叫都會使用一些記憶體堆疊,最終將造成記
憶體不足的問題。
155
4.5.4
遞迴程序
• 【範例4-15】使用遞迴,求出n!的值。
• 範例4-15:
– 網站目錄 ASPNET\ch04\ch04_15\(檔案ch04_15.aspx)
– Step1:網頁介面設計如下(所有控制項皆採相對定位)並設定屬性
(其餘屬性參照屬性窗格)。
156
4.5.4
遞迴程序
– Step2:撰寫Button1_Click()事件程序與fac()程序碼如下:
• 程式部分內容:
157
4.5.4
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
遞迴程序
Function fac(ByRef n As Long) As Long
If (n <= 1) Then
Return 1
Else
Return n * fac(n - 1)
End If
End Function
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Dim num As Long
Label2.Text = ""
'若需判斷輸入是否為正整數,請自行參考前面範例
num = CLng(TextBox1.Text)
Label2.Text = TextBox1.Text & "!=" & CStr(fac(num)) & "<br />"
End Sub
158
4.5.4
遞迴程序
– 範例說明:
• (1)第21行呼叫fac(num),並將結果加入到Label2標籤中。
• (2)第7~13行:fac(num)程序,將回傳一個長整數。而其中第11行,
它又呼叫了本身,但由於每次呼叫都會遞減1,故會往邊界條件
(≦1)移動。
– Step3:執行程式。
159
4.5.5
Visual Basic的內建函式
• 大部分的高階語言為了縮短應用程式開發時程,會將一些常
見的數值與字串運算功能,事先撰寫成「內建函式」,並放
在程式庫內。
– 程式設計師如果覺得某個內建函式恰好適用的話,只需要在使用時直
接呼叫函式名稱並賦予一些合法的引數初值,函式就會幫您執行可完
成該功能的細節動作,然後回傳一個使用者需要的回傳值。
• VB也提供了許多的內建函式,但有些在實作上會在編譯時以內嵌方式取
代而不會進行實際的程序呼叫,有些則歸類到特定類別之中。
– 被歸類到特定類別中時,稱之為方法(Methods),而有時這些常用方法以共用
方法宣告(Shared Method),因此不必產生物件也可以直接使用
– 而內嵌與共用方法在使用上與一般傳統VB6/VBScript使用內建函式的方式比
較類似。
160
4.5.5
Visual Basic的內建函式
• 型別轉換函式。
– 例如CInt()、CStr()等,詳見表4-1,此類函式編譯時以內嵌方式取代。
• 其他常用函式
– 其他函式在.NET Framework的規劃下,以類別為單位,換句話說,
這些函式將隸屬於某一個類別而稱之為類別的方法。
– 我們會在第5章中介紹這些好用的類別與方法。當中包含了數學類別
與方法、字串類別與方法、日期時間類別與方法、測試資料的類別與
方法、亂數類別與方法等。
161
4.6 本章回顧
• 在本章中,我們介紹了VB的基本語法,包含資料型別、運算
式、流程控制、程序、陣列、型別轉換函式等等
– 在下一章,我們將介紹VB有關於物件與類別的技術
– 本章所介紹的InStr()函式與IsNumeric()函式仍會出現在下一章中,因
為它是某個類別的方法。
– 至於本章所使用的型別轉換函式,如CStr()、CInt()等則會在編譯時以
內嵌方式處理,故不在下一章重新介紹。
162
本章習題
163