摘 要:通過具體的程序?qū)嵗饰隽薞B初學(xué)者在編程過程中出現(xiàn)的若干典型錯(cuò)誤,以期幫助他們了解這些程序錯(cuò)誤產(chǎn)生的原因,從而加深他們對(duì)相關(guān)VB編程知識(shí)的理解。文中的錯(cuò)誤程序示例也可供VB教師作為教學(xué)素材使用,為他們改進(jìn)課程教學(xué)提供一定的參考依據(jù)。
關(guān)鍵詞:Visual Basic;典型錯(cuò)誤;實(shí)例剖析
中圖分類號(hào):TP312
《Visual Basic程序設(shè)計(jì)》(下文簡(jiǎn)稱VB)是許多高校為非計(jì)算機(jī)專業(yè)學(xué)生開設(shè)的第一門程序設(shè)計(jì)語(yǔ)言課程。由于VB課程本身理論性和實(shí)踐性都比較強(qiáng),加之學(xué)生初次接觸程序設(shè)計(jì)語(yǔ)言,缺乏相應(yīng)的知識(shí)背景,在編程時(shí)難免會(huì)產(chǎn)生各種各樣的錯(cuò)誤。面對(duì)出錯(cuò)的程序,學(xué)生找不出錯(cuò)誤原因,不知如何處理,這極易使學(xué)生對(duì)VB編程產(chǎn)生畏難情緒,從而不利于課程的進(jìn)一步學(xué)習(xí)?;诖耍疚尼槍?duì)筆者在VB教學(xué)實(shí)踐中收集到的學(xué)生編程時(shí)出現(xiàn)的若干典型錯(cuò)誤以具體實(shí)例的方式進(jìn)行了剖析,以期幫助他們了解這些程序錯(cuò)誤產(chǎn)生的原因,從而加深他們對(duì)相關(guān)VB編程知識(shí)的理解。
1 VB編程典型錯(cuò)誤
1.1 誤用“+”運(yùn)算符
“+”運(yùn)算符在VB中既可以用來(lái)計(jì)算和,也可以用來(lái)連接字符串。“+”作為字符串連接符來(lái)使用,只有一種情況,就是“+”旁邊的兩個(gè)操作數(shù)的數(shù)據(jù)類型都是字符串型時(shí),“+”旁邊的操作數(shù)只要有一個(gè)的數(shù)據(jù)類型是數(shù)值型,“+”就用來(lái)求和。學(xué)生初學(xué)VB時(shí),容易受數(shù)學(xué)思維的影響,因而經(jīng)常出現(xiàn)誤用“+”運(yùn)算符的情況。
例如,要求編寫程序“從鍵盤分別輸入一個(gè)學(xué)生三門課的成績(jī),求他的總成績(jī)”。有學(xué)生是這么做的,先在窗體上繪制三個(gè)文本框,分別用來(lái)輸入三門課的成績(jī),再繪制一個(gè)命令按鈕,然后編寫如下程序:
Private Sub Command1_Click()
Dim mark As Single
mark = Text1.Text + Text2.Text + Text3.Text
Print \"該學(xué)生的總成績(jī)?yōu)椋篭"; mark
End Sub
對(duì)于上面的程序,運(yùn)行時(shí)要么出現(xiàn)“溢出”錯(cuò)誤,要么得不到正確的結(jié)果,主要原因就是“+”運(yùn)算符的使用有錯(cuò)誤。學(xué)生誤認(rèn)為“+”在這里是求和,實(shí)際上“+”在這里是做字符串的連接,因?yàn)槲谋究虻腡ext屬性的數(shù)據(jù)類型是字符串型。因此使用“+”運(yùn)算符時(shí)一定要特別注意,如果指定“+”要用來(lái)求和,一定要確?!?”旁邊的兩個(gè)操作數(shù)的數(shù)據(jù)類型都是數(shù)值型(如果不是數(shù)值型,應(yīng)通過VB的相應(yīng)類型轉(zhuǎn)換函數(shù)將其轉(zhuǎn)換為數(shù)值型,例如上面的程序就應(yīng)使用Val函數(shù)來(lái)完成轉(zhuǎn)換);如果指定要做的是字符串連接,最好不要使用“+”,直接使用“”運(yùn)算符。
1.2 潛在的類型不匹配錯(cuò)誤
對(duì)于賦值語(yǔ)句,賦值號(hào)“=”兩邊的數(shù)據(jù)類型一般要求應(yīng)一致,如果兩邊的類型不同,VB的處理方法是:以左邊變量的數(shù)據(jù)類型為基準(zhǔn),如果右邊表達(dá)式計(jì)算結(jié)果的數(shù)據(jù)類型能夠轉(zhuǎn)換成左邊變量的數(shù)據(jù)類型,則先由VB自動(dòng)完成數(shù)據(jù)類型轉(zhuǎn)換后,再賦值給左邊的變量;如果不能轉(zhuǎn)換,就會(huì)出現(xiàn)類型不匹配的錯(cuò)誤。學(xué)生初學(xué)VB時(shí),在程序中很少有意識(shí)地去關(guān)注賦值號(hào)“=”兩邊的數(shù)據(jù)類型是否一致,這使得程序可能隱含著潛在的錯(cuò)誤,導(dǎo)致程序可靠性不高。
例如,要求編寫程序“從鍵盤輸入華氏溫度,將其轉(zhuǎn)換為對(duì)應(yīng)的攝氏溫度”,學(xué)生一般編程如下:
Private Sub Command1_Click()
Dim f As Single, c As Single
f = InputBox(\"請(qǐng)輸入華氏溫度\")
c = 5 * (f - 32) / 9
Print \"c=\"; c
End Sub
對(duì)于上面的程序,在賦值語(yǔ)句“f = InputBox(\"請(qǐng)輸入華氏溫度\")”中,“=”兩邊的數(shù)據(jù)類型是不一致的,變量f是數(shù)值型,而InputBox函數(shù)返回值的數(shù)據(jù)類型是字符串型。學(xué)生測(cè)試程序時(shí),如果只是輸入了數(shù)值(InputBox函數(shù)返回的實(shí)際上是數(shù)值型字符串),由于VB會(huì)自動(dòng)完成數(shù)據(jù)類型轉(zhuǎn)換,程序可以得到正確的結(jié)果,類型不匹配的潛在錯(cuò)誤不會(huì)暴露出來(lái);但是如果不慎輸入的是一個(gè)非數(shù)值型的字符串,VB不能自動(dòng)轉(zhuǎn)換,這種錯(cuò)誤就會(huì)顯現(xiàn),影響程序的正常運(yùn)行。為了避免這種錯(cuò)誤的出現(xiàn),最好由編程者自己通過程序轉(zhuǎn)換的方式使賦值號(hào)“=”兩邊的數(shù)據(jù)類型保持一致,一味寄希望于由VB自動(dòng)進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換是存在一定風(fēng)險(xiǎn)的。
同樣地,對(duì)于關(guān)系運(yùn)算符,兩邊操作數(shù)的數(shù)據(jù)類型最好也應(yīng)保持一致。如果不一致,在某些情況下VB通過自動(dòng)類型轉(zhuǎn)換可以將它們轉(zhuǎn)換為同一數(shù)據(jù)類型后再比較(比如字符串和數(shù)值比較,將字符串轉(zhuǎn)換為數(shù)值再比較;邏輯型數(shù)據(jù)和數(shù)值比較,將True和False分別轉(zhuǎn)換為-1、0后再比較),遇上不能轉(zhuǎn)換的情況,也會(huì)產(chǎn)生類型不匹配的錯(cuò)誤,例如,執(zhí)行語(yǔ)句Print 77>\"teat\"就會(huì)產(chǎn)生這類錯(cuò)誤。
1.3 對(duì)多分支語(yǔ)句執(zhí)行流程理解不透引發(fā)錯(cuò)誤
VB中用來(lái)實(shí)現(xiàn)多分支結(jié)構(gòu)的語(yǔ)句有If(采用If…Then…ElseIf…結(jié)構(gòu))語(yǔ)句和Select Case語(yǔ)句。這兩個(gè)語(yǔ)句的執(zhí)行流程具有兩個(gè)特點(diǎn):(1)不管有多少個(gè)分支,只執(zhí)行其中的一個(gè)分支,執(zhí)行這個(gè)分支后不再執(zhí)行其他的分支,直接執(zhí)行End If或End Select后面的語(yǔ)句;(2)只有前面的分支條件不成立時(shí),才會(huì)去判斷后面的分支條件。學(xué)生初學(xué)VB時(shí),由于對(duì)這個(gè)執(zhí)行流程特點(diǎn)的理解還不夠透徹,在閱讀和編寫多分支結(jié)構(gòu)程序時(shí)經(jīng)常犯錯(cuò)誤。
例如,給出下面的程序閱讀題:程序運(yùn)行后,如果在文本框Text1中輸入10,然后單擊命令按鈕,寫出在Text2中顯示的內(nèi)容。
Private Sub Command1_Click()
n = Val(Text1.Text)
Select Case n
Case 1 To 20: x = 10
Case 2, 4, 6: x = 20
Case Is < 10: x = 30
Case 10: x = 40
End Select
Text2.Text = x
End Sub
對(duì)于上面的程序閱讀題,有相當(dāng)一部分學(xué)生認(rèn)為Text2中顯示的內(nèi)容應(yīng)是40,他們給出的理由是:程序中第1個(gè)和第4個(gè)Case后面的“測(cè)試值”都與Select Case后面n值相匹配,第4個(gè)Case分支給變量x賦的值會(huì)取代第1個(gè)Case分支給變量x賦的值。學(xué)生這樣理解顯然是對(duì)Select Case語(yǔ)句的執(zhí)行流程特點(diǎn)認(rèn)識(shí)不清所致。因?yàn)楦鶕?jù)執(zhí)行流程特點(diǎn)(1),第1個(gè)Case后面的“測(cè)試值”匹配了,就會(huì)執(zhí)行該Case分支相關(guān)聯(lián)的語(yǔ)句,不會(huì)再去判斷其他的分支,直接執(zhí)行End Select后面的語(yǔ)句;根據(jù)執(zhí)行流程特點(diǎn)(2)如果要判斷第4個(gè)Case分支,前面的3個(gè)Case分支必須都是不匹配的。
再如,要求編寫程序?qū)W(xué)生的百分制成績(jī)按要求轉(zhuǎn)換成相應(yīng)的等級(jí)(90~100轉(zhuǎn)換為優(yōu)秀,80~89轉(zhuǎn)換為良好,70~79轉(zhuǎn)換為中等,60~69轉(zhuǎn)換為及格,60分以下轉(zhuǎn)換為不及格),有學(xué)生編程如下:
Private Sub Command1_Click()
Dim Cj As Single, Dj As String
Cj = Val(Text1.Text)
Select Case Cj
Case Is >= 60: Dj = \"及格\"
Case Is >= 70: Dj = \"中等\"
Case Is >= 80: Dj = \"良好\"
Case Is >= 90: Dj = \"優(yōu)秀\"
Case Else: Dj = \"不及格\"
End Select
Label1.Caption = Dj
End Sub
上面的程序,雖然可以正常運(yùn)行,但存在著邏輯錯(cuò)誤。根據(jù)Select Case語(yǔ)句執(zhí)行流程特點(diǎn)(1),當(dāng)輸入98、88、78這些分?jǐn)?shù)時(shí),輸出結(jié)果都是及格。如果學(xué)生完全理解了VB多分支結(jié)構(gòu)語(yǔ)句的執(zhí)行流程,編完程序后按執(zhí)行流程檢驗(yàn)一下,是完全可以避免這類錯(cuò)誤的。
1.4 錯(cuò)寫Select Case語(yǔ)句中Case后面“測(cè)試值”的形式
Select Case語(yǔ)句中Case后面的“測(cè)試值”有三種不同的形式:(1)表達(dá)式1[,表達(dá)式2]…;(2)表達(dá)式1To表達(dá)式2;(3)Is<關(guān)系運(yùn)算符> <表達(dá)式>。第1種形式看上去是一個(gè)表達(dá)式列表,實(shí)際上是一個(gè)離散值的列表,因?yàn)槭潜磉_(dá)式列表中表達(dá)式的值與Select Case后面“測(cè)試表達(dá)式”的值進(jìn)行比較,只要Select Case后面“測(cè)試表達(dá)式”的值與表達(dá)式列表中的任何一個(gè)表達(dá)式的值相同,就認(rèn)為是匹配的;第2種和第3種形式實(shí)際上都是區(qū)間的表示形式,代表的是一系列連續(xù)的值,比如Case 9 To 12表示的是區(qū)間[9,12],Case Is >= 9表示的是區(qū)間[9,+∞],Case Is <= 12表示的是區(qū)間[-∞,12],只要Select Case后面“測(cè)試表達(dá)式”的值落在區(qū)間之內(nèi),就認(rèn)為是匹配的。需要注意的是,第3種形式是VB使用Is關(guān)鍵字表示區(qū)間的一種特定形式,不應(yīng)將其理解為關(guān)系表達(dá)式,不能用邏輯運(yùn)算符來(lái)連接兩個(gè)采用Is表示的區(qū)間。學(xué)生初學(xué)VB時(shí),容易將Select Case語(yǔ)句中Case后面的“測(cè)試值”本應(yīng)是第3種形式的寫法而不自覺地錯(cuò)寫成第1種形式,導(dǎo)致程序出現(xiàn)邏輯錯(cuò)誤。
例如,要求編寫程序?qū)W(xué)生的百分制成績(jī)按要求轉(zhuǎn)換成相應(yīng)的等級(jí),有學(xué)生編寫出如下程序:
Private Sub Command1_Click()
Dim Cj As Single, Dj As String
Cj = Val(Text1.Text)
Select Case Cj
Case Cj >= 90: Dj = \"優(yōu)秀\"
Case Cj >= 80: Dj = \"良好\"
Case Cj >= 70: Dj = \"中等\"
Case Cj >= 60: Dj = \"及格\"
Case Else: Dj = \"不及格\"
End Select
Label1.Caption = Dj
End Sub
對(duì)于上面的程序,輸入98、88、78、68這些分?jǐn)?shù)時(shí),輸出結(jié)果都是不及格,程序出現(xiàn)邏輯錯(cuò)誤。在程序的各個(gè)Case分支中,本應(yīng)采用Is關(guān)鍵字表示區(qū)間的Is被替換成變量名Cj,這一替換使得Case后面的內(nèi)容不再是表示區(qū)間,而成為一個(gè)關(guān)系表達(dá)式,對(duì)應(yīng)的就是Case后面的“測(cè)試值”的第1種表示形式。Case后面跟的是一個(gè)關(guān)系表達(dá)式,關(guān)系表達(dá)式的計(jì)算結(jié)果要么是True,要么是False,與Select Case后面變量Cj的值是不可能相等的,因此Case Else前面的分支都不匹配,從而執(zhí)行Case Else分支關(guān)聯(lián)的語(yǔ)句,輸出不及格。
1.5 使用循環(huán)結(jié)構(gòu)遍歷查找數(shù)據(jù)時(shí)產(chǎn)生錯(cuò)誤
使用循環(huán)結(jié)構(gòu)查找某個(gè)數(shù)據(jù)在一個(gè)數(shù)據(jù)集中是否存在,是常見的編程問題。這類問題的解決思路是將這個(gè)數(shù)據(jù)和數(shù)據(jù)集中的每個(gè)數(shù)據(jù)分別進(jìn)行比較,如果發(fā)現(xiàn)相同的,就表示找到;如果沒有發(fā)現(xiàn)一個(gè)相同的,就表示沒有找到。學(xué)生初學(xué)VB時(shí),解決這類問題也經(jīng)常出現(xiàn)錯(cuò)誤。
例如,要求編寫程序,用來(lái)實(shí)現(xiàn)下面的功能:當(dāng)用戶在組合框中輸入一個(gè)新的項(xiàng)目后,單擊命令按鈕時(shí),如果輸入的項(xiàng)在組合框的列表中不存在,則自動(dòng)添加到組合框的列表中[1]。有學(xué)生編程如下:
Private Sub Command1_Click()
Dim i As Integer
For i = 0 To Combo1.ListCount - 1
If Trim(Combo1.Text) = Combo1.List(i) Then
MsgBox \"輸入項(xiàng)已在組合框中\(zhòng)"
Else
Combo1.AddItem Trim(Combo1.Text)
MsgBox \"已成功添加輸入項(xiàng)\"
End If
Next i
End Sub
對(duì)于上面的程序,假定組合框列表中原來(lái)有“北京、上海、天津、武漢”這4個(gè)選項(xiàng),再輸入1個(gè)新項(xiàng)目“廣州”,單擊命令按鈕后,“廣州”就會(huì)在組合框的列表中被添加4次,顯然程序有錯(cuò)誤,錯(cuò)誤的原因是在循環(huán)結(jié)構(gòu)中一旦發(fā)現(xiàn)新項(xiàng)目與組合框列表中某一個(gè)項(xiàng)目不同時(shí)就馬上去添加,這顯然是不合理的。新項(xiàng)目“廣州”是否添加到組合框的列表中,判斷依據(jù)應(yīng)是將新項(xiàng)目與組合框列表中的項(xiàng)目逐一比較完之后,都沒發(fā)現(xiàn)相同的,才可以添加;當(dāng)然在循環(huán)的過程中如果發(fā)現(xiàn)相同的,這時(shí)立刻就可以得出不添加的結(jié)論,新項(xiàng)目就沒有必要再和組合框列表中剩下的還沒有比較的項(xiàng)目去比較了,循環(huán)就可以提前終止了。據(jù)此上面的程序可以修改如下:
Private Sub Command1_Click()
Dim i As Integer
For i = 0 To Combo1.ListCount - 1
If Trim(Combo1.Text) = Combo1.List(i) Then
MsgBox \"輸入項(xiàng)已在組合框中\(zhòng)"
Exit For
End If
Next i
If i > Combo1.ListCount - 1 Then
Combo1.AddItem Trim(Combo1.Text)
MsgBox \"已成功添加輸入項(xiàng)\"
End If
End Sub
2 結(jié)束語(yǔ)
以上總結(jié)的是學(xué)生初學(xué)VB編程時(shí)常見的一些典型錯(cuò)誤,文中的錯(cuò)誤程序示例不但可以供VB初學(xué)者借鑒,以避免此類錯(cuò)誤再在編程中出現(xiàn),而且也可供VB教師作為教學(xué)素材使用,為他們改進(jìn)課程教學(xué)提供一定的參考依據(jù)。
參考文獻(xiàn):
[1]吳保榮.Visual Basic程序設(shè)計(jì)[M].北京:高等教育出版社.廣州:中山大學(xué)出版社,2007.
作者簡(jiǎn)介:李志輝(1976-),男,湖北紅安人,碩士,講師,研究方向:信息系統(tǒng)、數(shù)據(jù)庫(kù)技術(shù)。