VB.NET語法基礎
在進行ASP.NET程序設計之前,首先要選擇一種ASP.NET編程語言。ASP.NET的默認語言是Visual Basic.NET,當然也可以使用C#。本書主要介紹Visual Basic.NET,並且書中所有的例子都用Visual Basic.NET來編寫。
本章介紹一些Visual Basic.NET的初步知識,關於VB.NET的高級編程知識請讀者參閱其他相關圖書。
Visual Basic.NET是繼Visual Basic 6.0之后新發布的Visual Basic的全新版本。如果您是一個Visual Basic.NET的高手的話,可以跳過這一部分,從第3章開始學習。
學完本章后,讀者將能夠:
(1) 了解為什么選擇VB.NET作為ASP.NET程序設計的首選語言;
(2) 了解變量、常量和表達式的知識;
(3) 會使用條件、循環語句;
(4) 了解如何使用過程和函數。
2.1 編程語言的選擇
由於ASP.NET只是一個程序設計環境,要在這個環境中進行程序設計,必須選擇一種語言。在早期的ASP中,默認使用的語言是VBScript腳本語言。由於.NET Framework已經支持VB等非腳本的高級語言,所以完全沒有必要再去使用VBScript,但是原來用VBScript寫的程序在ASP.NET中仍然可以執行,因為.NET環境仍然支持VBScript的語法。
2.1.1 .NET支持的語言
.NET為用戶提供了三種程序設計語言:Visual Basic.NET、C#和Jscript。本節分別介紹這三種語言。
Visual Basic.NET是VB最新的版本,從功能和性能上講可以說有了很大的飛躍。首先,早期的VB版本不完全支持面向對象的程序設計,由於它不支持對象的繼承和重載,所以產生了很多問題。另外,早期的VB版本無法創建多線程的應用程序,這樣就不能夠充分利用機器的資源,也不能很好地提高應用程序的執行效率。但是現在,由於VB.NET使用了CLR,這些問題都很好地得到了解決。
對於C#,可以認為它是在C、C++的基礎上創立的一種新的語言。它繼承了C++的優異功能,去除了在.NET環境中沒有用處的類型定義、模板等功能,使得C#與C++相比,更加易於使用,同時效率也大大提高。
與VB.NET一樣,JScript.NET也是從JScript發展而來的。JScript.NET是完全用C#重新編寫的,它支持類型和繼承性,並且是完全編譯執行的。為了保證原有的JScript程序仍然能夠正確地執行,它仍然支持現有的JScript代碼。
2.1.2 為什么選擇VB.NET
本書選擇VB.NET作為程序設計語言的原因是:首先,VB.NET是ASP.NET的默認編程語言;其次,VB.NET對於初學者來說十分簡單易學,並且使用它可以完成C#和JScript.NET所能夠完成的所有功能。
2.2 變量、常量和表達式
2.2.1 數據類型
VB.NET中有12種不同的數據類型,可以分成三類:數值類型、文本類型和混合類型。
數值類型是VB.NET數據類型的主要類型,共7種。數值類型的數據類型見表2-1。
表2-1 數值類型的數據類型
數據類型 |
表示方式 |
取 值 范 圍 |
說 明 |
整型 |
Integer |
–2147483648~2147483647 |
用於表示簡單整數 |
字節型 |
Byte |
0~255 |
用於簡單算術運算。由於這個類型的變量可以在一個字節中存儲,所以運算速度最快 |
短整型 |
Short |
–32768~32767 |
是整型的一種形式,相對表示范圍較小 |
長整型 |
Long |
–9223372036854775808~ 9223372036854775807 |
是整型的一種形式,相對表示范圍較大 |
單精 |
Single |
–3.402823E38~–1.401298E-45(對於負數)和1.401298E-45~3.402823E38(對於正數) |
用於存放單精度浮點數 |
雙精 |
Double |
–1.79869313486232E308~ –4.94065645841247E-324(對於負數) 和4.94065645841247E-324~ 1.79869313486232E308(對於正數) |
用於存放雙精度浮點數 |
小數 |
Decimal |
當小數位為0的時候,為 –79228162514264337593543950335~ 當小數位為28的時候,為 –7.9228162514264337593543950335~ |
常用於存儲貨幣值 |
用於存放文本的數據類型有兩個。文本類型的數據類型見表2-2。
表2-2 文本類型的數據類型
數 據 類 型 |
表 示 方 式 |
說 明 |
字符串型 |
String |
用於存放任何形式的字符串,包括一個字符或者多行字符 |
字符型 |
Char |
用於存放一個字符,它以0~65535之間數字的形式存儲 |
其中需要說明的是:
(1) 對於String類型,可以存放任何形式的字符串,它可以是純粹的文本,也可以是文本和數字的組合或者是數字、日期等。例如"This is a book. "和"12345"都是字符串。對於字符串類型的數據,可以進行相關的字符串操作,例如連接、截斷等。
(2) 對於Char類型,可以存儲的只是一個字符,注意,這個字符的存儲編碼必需是一個數字。在計算機系統中,可以顯示很多符號(不僅僅是英文字母),為了能夠正確地顯示,國際上有通用的標准(例如Unicode編碼),為每個字符設定了一個標准的數值來表示這個字符。
其余的數據類型還有:Date數據類型、布爾數據類型和Object數據類型,其說明見表2-3。
表2-3 其他數據類型
數 據 類 型 |
表 示 方 式 |
說 明 |
日期型 |
Date |
必須用mm/dd/yyyy的格式表示,也可以存儲時間(可以存儲00:00:00~23:59:59之間的任何時間) |
布爾型 |
Boolean |
取值為True和False |
對象型 |
Object |
|
其中需要說明的是:在VB.NET中,對於Boolean類型的數據,當需要把布爾類型的值轉換為數值類型的時候,會把True當成1來處理,把False當作0來處理。當需要把數值類型的值轉換為布爾類型的時候,會把0轉換為False,而把其他的非0數值轉換為True。
2.2.2 變量
變量用來存儲程序中需要處理的數據,用戶可以把變量看作是在內存中存儲數據的盒子。在其他程序設計語言中,幾乎都要求程序設計人員在使用變量之前定義變量的數據類型,因為不同數據類型的變量所需要的內存空間是不一樣的:比如,字節型變量需要8位的空間,短整型變量需要16位空間等,這就表示盒子的容量是不一樣的,所以為一種數據類型定義的變量就不能存放另一種數據類型的值。
在Visual Basic.NET中,創建變量的方式有兩種:一種方法是使用Dim關鍵字,這是顯式定義的方法。還可以使用隱式定義的方法,也就是在用戶需要使用一個變量的時候直接寫出這個變量並為它賦值。
顯式定義方法如下所示:
Dim x
通過這樣一條語句,就創建了一個名為x的變量。也可以用下面的方法一次定義多個變量:
Dim a,x
這條語句創建了兩個變量:a和x。
在這里,有以下幾點需要說明:
(1) 如何為變量取名字。Visual Basic.NET和其他語言一樣,其變量名稱必須以字母開頭,只能包含字母、數字和下划線,並且不是Visual Basic.NET關鍵字。在為變量取名時,建議不要使用像a或者x這樣的讓人無法理解的變量名,而應該采用小寫前綴加上有特定描述意義的名字的方式來為變量命名,這種命名方法被稱為Hungarian法。變量名的前三個字母用於說明數據類型,第四個字母大寫以表示變量的實際含義。例如下面的定義:
Dim strFileName
Dim intTotal
都可以說是定義了很好的變量名:用str和FileName兩個部分組合來表示strFileName是用來存儲字符串類型的文件名的,用int和Total兩個部分組合來表示intTotal是用來存儲整數類型的總和的。當然,對於程序員來說,這種命名約定並不是強制性的,仍然可以使用a和x這樣的變量名,也可以用intTotal變量來存儲一個字符串。但是很明顯,如果用戶都采用這種為變量命名的方式並在程序設計過程中遵循這樣的好習慣,可以讓程序易讀,並減少出錯的機會。
在VB.NET中,常用的約定前綴見表2-4。
表2-4 常用的變量命名約定
數 據 類 型 |
前 綴 |
例 子 |
Boolean |
bln |
blnYes |
Byte |
byt |
bytByte |
Char |
chr |
chrChar |
Date |
dat |
datDate |
Double |
dbl |
dblDouble |
Decimal |
dec |
decDecimal |
Integer |
int |
intTotal |
Long |
lng |
lngLong |
Single |
sng |
sngSingle |
Short |
sho |
shoShort |
String |
str |
strText |
Object |
obj |
objFileObject |
(2) 當使用Dim 語句的時候,可以在后面加上一個as關鍵字來指定一個變量的數據類型。例如:
Dim intTatal as Integer
這條語句表示創建一個名為intTatal的整數類型的變量,使用這種方法可以指明一個變量必須要保存什么類型的數據。雖然VB.NET並不強迫用戶在定義變量的時候一定要指明其數據類型,但是建議用戶在編寫程序時使用這種方法來指明變量的數據類型,以減少程序出錯的可能。
(3) 雖然可以使用隱式方法來創建變量,但是由於前面提到的原因,仍然建議使用顯式的方法來定義變量。
(4) 在VB.NET中,是不區分大小寫的,這就意味着,變量strFileName和變量strfilename將表示同一個變量。
2.2.3 運算符
在VB.NET中常用的運算符與其他的語言並沒有什么不同。常用的運算符有:賦值運算符、算術運算符、字符串連接運算符、比較運算符和邏輯運算符。
1. 賦值運算符
賦值運算符是最常用的運算符,它就是我們熟悉的等號(=)。需要注意的是,雖然它表面上是一個等號,但它並不是一個數學意義上的等號,它的意思是把等號后邊的值賦值給等號前面的變量。
例如,如果定義了一個整數型變量intNumber,就可以使用下面的語句:
Dim intNumber as Integer
intNumber=1
intNumber=intNumber*3
其中,第一行表示創建了一個名字為intNumber的整數型變量,第二行表示把這個變量的值賦值為2,第三行表示把intNumber中的值(也就是2)乘以3所得到的值(也就是6)賦值給intNumber。當第三條語句執行完成之后,intNumber中的值就是6。而在數學上,當intNumber的值是非零的時候,intNumber無論如何也不可能等於intNumber*3。
2. 算術運算符
VB.NET中的算術運算符有:+(加)、–(減)、*(乘)、/(除)、"(整數除)、Mod(取模)和^(冪),其中需要解釋的是/(除)和"(整數除)的區別。/(除)表示的是通常意義的除法,例如,(5.4/3)的結果是1.8,而"(整數除)表示把除數和被除數四舍五入以后再計算除法得到的整數結果,所以在計算(5.4"3)時,把5.4四舍五入為5,再進行運算,得到的整數結果是1,這種運算在特定的應用中會十分有用。例如,你有89條消息需要發布,又不希望所有的89條信息都在一頁中顯示,而希望分頁顯示,而每頁中只顯示20條信息。那么(89"20)所得到的4就表示有4頁是填滿了20條信息的,而剩下的一頁中有19條信息,並沒有填滿。
例2.1(02-01.aspx)VB.NET中算術運算符的用法。
1: <%
2: Dim dblData1,intData2,intData3
3: dblData1=5.4
4: intData2=3
5: intData3=7
6: Response.Write (dblData1+intData2 & "<br>") '5.4+3:結果是8.4
7: Response.Write (dblData1-intData2 & "<br>") '5.4-3:結果是2.4
8: Response.Write (dblData1*intData2 & "<br>") '5.4*3:結果是16.2
9: Response.Write (dblData1/intData2 & "<br>") '5.4/3:結果是1.8
10: Response.Write (dblData1"intData2 & "<br>") '5.4"3:結果是1
11: Response.Write (intData3 Mod intData2 & "<br>") '7 Mod 3:結果是1
12: Response.Write (intData3 ^ intData2 & "<br>") '7 ^ 3:結果是343
13: %>
需要說明的是:上面程序中第6行到第11行語句中的“&”運算符表示字符串的連接,另外,Response.Write表示輸出后面括號中的字符串。
可以運行上面的程序來學習如何使用算術運算符。
3. 字符串連接運算符
在例2.1中可以使用第6行的dblData1+intData2得到一個Double類型的數和一個Integer類型的數進行相加的結果。對於兩個字符串類型的變量,也可以使用“+”運算符。但是這時“+”運算符的含義不是加法,而是字符串的連接。例如:
Dim strTemp1,strTemp2 as String
strTemp1="Hello"
strTemp2="World. "
response.wirte(strTemp1 + " " + strTemp2)
當定義了兩個字符串型變量strTemp1和strTemp2並給它們分別賦值之后,就可以使用第4行的“+”運算符把它們連接起來,並在中間夾了一個空格,形成"Hello World."字符串。
由於在算術運算符中“+”的含義與字符串運算的時候“+”的含義大不相同,所以為了減少誤會的發生,在VB.NET中還可以使用“&”運算符作為字符串連接運算符。也就是說,當把第4行的語句換成
response.wirte(strTemp1 & " " & strTemp2)
后,仍然會得到正確的結果。建議使用“&”運算符進行字符串連接。
4. 比較運算符
VB.NET中的比較運算符有:=(等於)、<>(不等於)、<(小於)、<=(小於等於)、>(大於)、>=(大於等於)。這些運算符對於數值、字符、日期表達式的比較都是有效的,結果是布爾類型的True或False。
例2.2(02-02.aspx)VB.NET中的比較運算符的用法。
1: <%
2: Dim dblData1,intData2,intData3
3: dblData1=5.4
4: intData2=3
5: intData3=7
6: Response.Write ((dblData1>intData2) & "<br>") '5.4>3:結果是True
7: Response.Write ((dblData1<intData2) & "<br>") '5.4<3:結果是False
8: Response.Write ((dblData1=intData2) & "<br>") '5.4=3:結果是False
9: Response.Write ((dblData1>=intData2) & "<br>") '5.4>=3:結果是True
10: Response.Write ((dblData1<=intData2) & "<br>") '5.4<=3:結果是False
11: %>
可以運行上面的程序來學習如何使用比較運算符。
另外需要說明的是,字符串之間也是可以進行比較的,比較的方法是根據字母表的順序。例如,“but”比“book”大,而“A”小於“a”。
5. 邏輯運算符
VB.NET中常用的邏輯運算符有:Not(非)、And(與)、Or(或)、Xor(異或)。計算的結果仍然是布爾類型的True或False。
例2.3(02-03.aspx)VB.NET中邏輯運算符的用法。
1: <%
2: Dim bolData1,bolData2 as Boolean
3: bolData1=True
4: bolData2=False
5: Response.Write ((bolData1 And bolData2) & "<br>") 'True And False是False
6: Response.Write ((Not bolData1) & "<br>") 'Not True是False
7: Response.Write ((bolData1 Or bolData2) & "<br>") 'True Or False是True
8: Response.Write ((bolData1 Xor bolData2) & "<br>") 'True Xor False是True
9: %>
可以運行上面的程序來學習如何使用邏輯運算符。
2.2.4 常量
常量是指在程序中直接給出的數值、字符或字符串。在程序中經常會使用這樣的賦值語句:
intValue=3
strFileName="student.aspx"
在這里,3和"student.aspx"是常量。
在Visual Basic.NET中,有幾個很特別的常量用戶應該注意:
(1) Nothing:在VB.NET中,把一個表示對象的變量賦值為Nothing時,就表示這個對象不再使用,VB.NET會釋放這個對象所占用的內存空間。使用的方法是:
objMyObject=Nothing
(2) Null:當一個變量的值是Null時,它表示這個變量的值不是有效數據。如果把變量形容成一個盒子,在沒有給一個變量賦任何值的時候,VB.NET 會給它一個初始值(例如,如果用戶定義了一個整型的變量,那么在沒有使用它之前,它的值是0);而Null則表示這個盒子中的值是一個無效值。
(3) True:表示真。
(4) False:表示假。True和False通常用於條件語句。
另外一種常量是用Const關鍵字定義的。在定義變量的時候使用Const而不是Dim,並為這個變量賦一個值,就可以定義一個特殊的常量。這個常量以變量的形式出現在程序中,只是它的值在程序的執行過程中是不能改變的。由於它是一個不能改變的變量,所以有人也稱它為常變量,也有人稱之為符號常量。可以采用下面的方式定義一個表示路徑名的符號常量:
Const strPathName="c:"windows"
這樣,在后面的程序中,就可以使用strPathName來代表所有的“c:"windows”路徑名,不用每次都指明。而且,如果程序發生變化,路徑名要變成“c:"windows"cindy”,只要改動上面的這個定義語句就可以了。如果不采用常量,就需要修改程序中所有涉及到這個路徑名的地方。
為了提高程序的效率,建議用戶不要定義不需要使用的常量,因為所有的常量都要占用內存空間來進行保存。一旦定義了一個常量,系統就要在它的整個生存期內負責維護這個常量。對於大型的程序,往往會定義一個常量文件,把所有項目中會使用的常量都定義在這個文件中,在需要使用的時候把這個文件包含進來。這種方法雖然對於減少代碼的復雜度很好,但是有一個問題,就是一個程序並不會使用包含文件中的所有常量。這樣,很多常量是沒有用的,但是這些常量卻仍然要占用服務器的內存空間。由於在網絡的環境中,客戶的需求不好估計,往往很大,所以在定義常量時,要考慮清楚,才能保證程序的效率。
2.2.5 數組
除了使用單個變量,在VB.NET中還可以使用數組,以方便地存儲一系列相關的數據。數組分為一維數組和多維數組。一維數組如下定義:
Dim arrData(2) as String
這個Dim語句定義了一個長度為3的一維數組arrData。它的下標的范圍從0~2,即可以訪問arrData(0)、arrData(1)、arrData(2),而數組中所有的數據都是String類型。
多維數組就是維數大於1的數組。最常見的是二維數組和三維數組。二維數組的定義方式如下:
Dim arrData(2,3) as String
這個Dim語句定義了一個3×4的數組,共有12個單元。與一維數組一樣,它的下標范圍是第一維從0~2,第二維從0~3。以此類推,可以定義三維數組或維數更多的數組。在VB.NET中數組的維數最多可以定義到60,但很少有人會用到維數超過三維的數組。
在VB.NET中還可以定義動態數組,即長度不確定的數組。例如,可以在程序開始的時候定義一個動態數組:
Dim arrData()
在這里,沒有指明數組arrData的長度,也不知道它的維數,因此這個數組在程序中是不能直接使用的。因為所有的數組都需要有連續的內存空間來存放,如果沒有定義數組的維數和每一維的長度,就意味着無法為數組分配內存空間。所以VB.NET要求在使用動態數組之前用ReDim語句為這個數組指明維數和每一維的長度。方法如下:
ReDim arrData(2)
這個時候,才可以使用arrData數組。注意,如果一個數組在定義的時候不是動態數組,就不能使用ReDim語句對數組重新定義。另外,對於已經使用ReDim重定義過的動態數組,可以使用ReDim重新再定義這個數組的長度,但是不能使用ReDim來重新定義數組的維數。也就是說,如果已經定義了一個動態數組arrData(),可以在后面的程序中把它重新定義為一個一維的數組(如ReDim arrData(2)),而不允許再把它定義為一個二維的數組(如ReDim arrData(2,3)),但是可以把它再次重定義為一個長度為5的一維數組(ReDim arrData(4))。
2.2.6 表達式
表達式是一個或多個運算的組合。VB.NET的表達式與其他語言的表達式沒有顯著的區別。每個符合VB.NET規則的表達式的計算都是一個確定的值。對於常量、變量的運算和對於函數的調用都可以構成最簡單的表達式。
2.3 分支
到目前為止,我們已經學習了VB.NET的表達式的使用。現在,我們把它們用到更加復雜的結構中去。
在程序設計中,條件語句能夠根據表達式的值來決定代碼的執行流程。在VB.NET中,條件分支語句有兩種:If/Then/Else語句和Select/Case語句。
1. If/Then/Else語句
If/Then/Else語句是最常用的條件語句。它的基本形式是:
If condition Then statements1 [Else statements2 ]
它表示:如果condition為True,那么就執行statements1;否則執行statements2。
例2.4(02-04.aspx)根據時間顯示問候信息。
1: <%
2: If Hour(Now)<12 Then Response.Write ("Good morning! Cindy!")
3: If Hour(Now)=12 Then Response.Write ("Good noon! Cindy!")
4: If (Hour(Now)>12 And Hour(Now)<18) Then Response.Write ("Good afternoon! Cindy!")
5: If Hour(Now)>=18 Then Response.Write ("Good evening! Cindy!")
6: %>
在上面的例子中,函數Hour()是對給出的日期時間求它的小時數,Now函數用於返回當前的日期和時間。程序根據當時的時間判定是上午、中午還是下午,分別給出問候信息。我們看到,這個寫法很簡單,但是這個程序為了顯示一條問候信息,要對Hour(Now)取值4次並且執行4次比較才能完成,從效率上考慮並不好。
If/Then/Else語句還可以寫成比較復雜的形式:
If condition_1 Then
statements_1
[ElseIf condition_m Then
statements_m
[ElseIf condition_n Then…]]
[Else
statements_2]
End If
這個語句可以檢測多個條件。第一種寫法要求語句在寫的時候要在一行中寫完,例如例2.4 的第2行的If語句。這條語句也可以采用第二種方法來寫,方法如下:
If Hour(Now)<12 Then
Response.Write ("Good Morning!Cindy!")
End If
建議用戶采用后一種寫法,因為這種方法更結構化,可讀性好。當用戶在調試大型軟件的代碼時,會發現,雖然看起來多寫了幾行語句,但好處卻是很大的。
例2.5(02-05.aspx)根據時間顯示問候信息。請注意這個例子的寫法與上個例子中的寫法在執行效率上的區別。
1: <%
2: If Hour(Now)<12 Then
3: Response.Write ("Good morning! Cindy!")
4: ElseIf Hour(Now)=12 Then
5: Response.Write ("Good noon! Cindy!")
6: ElseIf Hour(Now)>=18 Then
7: Response.Write ("Good evening! Cindy!")
8: Else
9: Response.Write ("Good afternoon! Cindy!")
10: End If
11: %>
上面的例子在執行的過程中,對於當前不同的時間,為了顯示問候信息,執行的Hour(Now)的取值和比較的次數是不一樣的:最少只要1次,最多需要3次。從效率上看,比例2.4要好。
2. Select/Case結構
當程序中的條件比較復雜,而且是根據同一個表達式的不同值執行不同操作的時候,用If/Then/Else語句來寫就顯得十分煩瑣。這時可以考慮采用Select/Case結構來完成條件語句。
Select/Case結構為:
Select Case testexpression
Case condition_1
statements_1
[ …
Case Else
statements_n]
End Select
它表示:如果testexpression的值是Condition_1,就執行statements_1,以此類推,如果都不符合,就執行Statements_n。
例2.6(02-06.aspx)用Select/Case語句來實現問候信息的顯示。
1: <%
2: Select Case Hour(Now)
3: Case 0,1,2,3,4,5,6,7,8,9,10,11
4: Response.Write ("Good morning! Cindy!")
5: Case 12
6: Response.Write ("Good noon! Cindy!")
7: Case 13,14,15,16,17
8: Response.Write ("Good afternoon! Cindy!")
9: Case Else
10: Response.Write ("Good evening! Cindy!")
11: End Select
12: %>
很明顯,用這種方法來顯示問候信息要比用If/Then/Else語句清楚得多。因此,在選擇條件語句的時候要考慮好采用什么方式,並認真設置好條件。
2.4 循環
VB.NET中的循環有三種形式:For/Next、While/End While、Do/Loop和For/Each。
1. For/Next循環
用For/Next循環可以精確地控制循環體的執行次數。For/Next循環的語法如下:
For counter = startvalue To endvalue [Step stepvalue]
[statements]
[Exit For]
[statements]
Next
其中,用Step關鍵字可以定義循環計數器的增長方式,stepvalue的值(可正可負)來適應各種不同的需求。Exit For語句允許在某種條件下直接退出循環體。
例2.7(02-07.aspx)用For/Next語句來實現顯示二維數組的內容。
1: <%
2: Dim arrData(1,2)
3: Dim intI,intJ as Integer
4: arrData(0,0)=12
5: arrData(0,1) =13
6: arrData(0,2) =14
7: arrData(1,0) =15
8: arrData(1,1) =16
9: arrData(1,2) =17
10: For intI=0 To 1
11: For intJ=0 To 2
12: Response.Write (arrData(intI,intJ) & " ")
13: Next
14: Response.Write ("<br>") '一行顯示完以后換行顯示下一行
15: Next
16: %>
可以看出,用For/Next循環來顯示數組這樣的可以確定循環次數的數據結構是十分方便的。
2. While/End While 循環
如果不清楚要執行的循環的次數,那么可以用While/ End While循環。它有一個檢測條件,當條件滿足時,執行循環體的內容。如果條件不滿足,就退出循環。While/ End While語法如下:
While condition
[statements]
End While
由於在進入循環體之前會遇到檢測條件,所以如果這個時候condition的值為False,那么While/ End While循環的循環體有可能一次也不能執行。
例2.8(02-08.aspx)顯示3次問候信息。
1: <%
2: Dim intI as Integer
3: IntI=0
4: While intI<3
5: Response.Write ("Hello! Cindy!" & "<br>")
6: IntI=intI+1
7: End While
8: %>
在這個例子的第3行中為第2行中定義的intI變量設置了初值0。這里,如果不設置初值也是可以的,系統會自動為intI進行初始化(VB.NET默認為未顯式初始化的整數初始化為0)。但是,建議養成為變量設置初值的好習慣,這樣可以防止很多意想不到的錯誤。
3. Do/Loop
同樣,在不知道循環次數的情況下,也可以使用Do/Loop 循環。Do/Loop循環的作用與While/ End While十分相似。它的語法是:
Do {While | Until} condition
[statements]
[Exit Do]
[statements]
Loop
其中,Do后面的While和Until是可選的。使用While時,后面的條件滿足則執行循環體;使用Until時,后面的條件滿足就退出循環體。Do/Loop循環還有另外一種寫法:
Do
[statements]
[Exit Do]
[statements]
Loop {While | Until} condition
這種寫法的結果是:循環體在執行的時候至少會執行一次。
例2.9(02-09.aspx)顯示3次問候信息。
1: <%
2: Dim intI
3: IntI=0
4: Do Until intI>2
5: Response.Write ("Hello! Cindy!" & "<br>")
6: IntI=intI+1
7: Loop
8: %>
可以看出,Do/Loop的執行和While/End While的執行沒有太大的區別。用戶也可以把上面例子中第4行中的Until改為While並相應地改變后面的條件來實現相同的功能。
4. For/Each
在某些特殊情況下,可以使用For/Each來實現對一個數組或集合(集合將在后面的章節中講解)中元素的遍歷。
For/Each語句的寫法如下:
For Each item In Array or Collection
[statements]
Next
例2.10(02-10.aspx)用For/Each顯示一個數組中的所有數據。
1: <%
2: Dim arrData(3)
3: Dim stritem as string
4: arrData(0)="Beijing"
5: arrData(1)="Shanghai"
6: arrData(2)="Guangzhou"
7: For Each stritem In arrData
8: Response.Write (stritem & "<br>")
9: Next
10: %>
可以看出,For/Each循環與For/Next循環的區別是:在For/Next循環中需要指明循環的次數,而在For/Each循環中不需要這樣就可以遍歷到一個數組或集合的所有內容。另外需要說明的是,這種循環通常在集合中使用。
2.5 過程和函數
在程序設計過程中,隨着代碼量的不斷增加,會出現很多地方使用同樣代碼的情況。為了能夠減少同樣代碼的編寫,ASP.NET允許使用一些小的程序將重復的代碼只寫一次,其他需要使用這段代碼的地方調用這個小程序就可以了。
在ASP.NET中,實現這種小程序的方式有兩種:過程和函數。
2.5.1 模塊化的優點
模塊化是在程序設計發展到一定程度的時候誕生的程序設計方法。在早期的程序設計過程中,由於機器的硬件配置低,所以程序的運行速度和效率十分重要,因此早期的程序設計人員會大量使用各種技巧保證程序的快速運行,而這些技巧導致的最直接后果就是程序的結構混亂,很難閱讀。
隨着機器硬件的不斷更新,這些編程技巧所提高的程序運行速度已經微不足道,這時提高程序的可讀性就變得十分重要,於是就出現了模塊化程序設計方法。
模塊化程序設計方法的特點是:在編寫程序之前,把程序的功能分解成若干個小的任務,並把這些小任務看成是一個一個的模塊。當各個模塊編寫完成之后,就可以把這些模塊編譯成為一個大型的程序。由於每個模塊都有自己獨立的功能,所以可以把這些模塊分配給很多程序員來完成;而每個模塊的功能都是詳細定義的,所以可以建立完善的文檔,使得程序的可讀性大大提高。
2.5.2 過程和函數
VB.NET支持子過程和函數,它們都可以根據需要設置參數。它們之間惟一的區別是函數可以有返回值而子過程沒有。
子過程的定義方式為:
Sub subname ([argument1[,…, argumentn]])
[statements]
End Sub
對於子過程的調用方式是直接調用過程名subname。如果有參數,就在后面按照次序將參數在括號中寫好。
例2.11(02-11.aspx)用一個子過程顯示對一個用戶的問候信息:
1: <script language="vb" runat="server">
2: Sub SayHello(strUserName as String)
3: Response.Write ("Hello!" & strUserName & "<br>")
4: End Sub
5: </script>
6: <%
7: SayHello("Cindy")
8: %>
在上面的例子中,有下面幾點需要說明:
(1) 在第1行~第5行使用<Script>標記加入程序代碼。
(2) 在第2行~第4行定義了一個SayHello子過程。這個過程帶有一個參數strUserName,並在第3行輸出。
(3) 在第7行調用了這個子過程。在調用的時候,傳入參數的值是“Cindy”。
函數的定義方式為:
Function functionname ([argument1[,…, argumentn]])
[statements]
[Return value]
[statements]
End Function
對於函數的調用方式是調用函數名functionname()。如果有參數,就按照次序寫在括號中。
例2.12(02-12.aspx)用一個函數計算兩個整數的和。
1: <script language="vb" runat="server">
2: Function Add(intData1 as Integer,intData2 as Integer) as Integer
3: intData1=intData1+intData2
4: Return intData1
5: End Function
6: </script>
7: <%
8: Dim intTemp1,intTemp2 as Integer
9: intTemp1=2
10: intTemp2=3
11: Response.Write(Add(intTemp1,intTemp2))
12: Response.Write("<br>")
13: Response.Write(intTemp1)
14: %>
在上面的程序中,有下面幾點需要說明:
(1) 在第2行~第5行定義了一個函數Add。這個函數帶有兩個參數:intData1和intData2,並把一個整數作為返回值。
(2) 在第3行把參數intData1與intData2的和放到intData1中,並在第4行把intData1作為結果返回。
(3) 在第11行調用了這個函數,並把結果顯示出來。
在上面的子過程和函數的講解過程中,可以看出都可以采用帶參數的方式來增加子過程和函數的靈活性。需要說明的是,參數的傳遞有兩種方式:通過值傳遞參數和通過引用傳遞參數。
在調用子過程和函數的時候,如果沒有明確地指出,所有的參數都是通過值進行傳遞的。所謂通過值進行傳遞,就是把參數的值復制到參數中。例如例2.12中第11行的Add(intTemp1,intTemp2),就是通過值進行傳遞的好例子。在真正執行第2行~第5行定義的Add函數時,是把intTemp1的值2復制給了intData1,把intTemp2的值3復制給了intData2。在第3行把intData1和intData2的和賦值給intData1的時候,intData1的值變成了5,但是這個時候,intTemp1的值仍然是2,不是5(通過第13行的執行可以看出來),這就是通過值傳遞參數。這時,intData1和intTemp1是兩個不同的變量,在內存中占用不同的存儲空間。
在函數和子過程中,使用關鍵字ByVal來顯式表示通過值傳遞參數。也就是說,如果要用顯式的方式進行定義,第2行的函數定義可以寫成:
Function Add(ByVal intData1 as Integer, ByVal intData2 as Integer) as Integer
默認的情況是采用通過值傳遞參數。
那么什么是通過引用傳遞參數呢?請先看下面的例子。
例2.13(02-13.aspx)用一個函數計算兩個整數的和。
1: <script language="vb" runat="server">
2: Function Add(ByRef intData1 as Integer,ByRef intData2 as Integer) as Integer
3: intData1=intData1+intData2
4: Return intData1
5: End Function
6: </script>
7: <%
8: Dim intTemp1,intTemp2 as Integer
9: intTemp1=2
10: intTemp2=3
11: Response.Write(Add(intTemp1,intTemp2))
12: Response.Write("<br>")
13: Response.Write(intTemp1)
14: %>
例2.13與例2.12的區別就在於第2行的Add函數的定義。在這里使用了ByRef關鍵字表示這時的參數是通過引用進行傳遞的。執行這個程序就會發現,在程序執行完之后,不但intData1的值變成了5,同時intTemp1的值也變成了5。
通過引用傳遞參數的方法是把參數的地址傳遞進去。在第11行進行傳遞的時候,不是把intTemp1的值復制給intData1,把intTemp2的值復制給intData2,而是把intTemp1的地址給了intData1的地址,把intTemp2的地址給了intData2的地址。在傳遞成功之后,intData1就是intTemp1,intData2就是intTemp2。所以在第3行intData1的值發生變化時,intTemp1的值也同時發生了變化。
2.5.3 變量的作用域
在進行變量聲明時,變量聲明的位置決定了這個變量的作用范圍。在一個過程或函數外聲明的變量是全局變量,對本程序內部所有的過程和函數都起作用;而在一個過程或函數內部聲明的變量是局部變量,只對本過程或函數起作用。
下面通過一個例子說明全局變量和局部變量的區別。
例2.14(02-14.aspx)全局變量和局部變量的使用。
1: <script language="vb" runat="server">
2: Dim strGlobal as String="global"
3: Sub SayHello
4: Dim strTemp as String="hello!"
5: Response.Write (strTemp & "<br>")
6: Response.Write (strGlobal & "<br>")
7: if strGlobal<>"" then
8: Dim strTemp1 as String="hello cindy!"
9: Response.Write (strTemp1 & "<br>")
10: end if
11: 'Response.Write (strTemp1 & "<br>")
12: End Sub
13: </script>
14: <%
15: SayHello
16: %>
上面的例子中,有下面幾點需要說明:
(1) 第2行聲明的變量strGlobal定義在所有的函數或者過程之外,所以是一個全局變量。由於在定義這個變量的時候就為這個變量賦值為“global”,所以,在后面的程序中,第一次使用這個變量時這個變量的值就是“global”。
(2) 第3行~第12行定義了一個子過程SayHello。在這個過程中,首先在第4行定義了一個變量strTemp,由於這個變量是定義在子過程中的,所以這個變量是一個局部變量。在第5行顯示這個變量的值的時候,會顯示一個“hello!”字符串。
(3) 第6行要顯示strGlobal的值,由於這是一個全局變量,所以會顯示第1行賦值的“global”。
(4) 第7行~第10行定義了一個If/Endif代碼塊,在這個代碼塊中,定義了一個塊級局部變量strTemp1(第8行)。由於這個變量是定義在代碼塊中的,所以只在這個代碼塊中起作用。所以在第9行要顯示它的值的時候,會顯示“hello cindy!”。而如果取消第11行的注釋,系統將會通告strTemp1變量沒有定義。
通過上面的例子可以看出,在編寫程序的時候,要時刻注意變量的作用域的問題。因為在不同模塊中修改全局變量會導致模塊之間相互影響,違反了進行模塊化程序設計的初衷。所以要設計好的程序,就應該盡量減少全局變量的使用。