VB等级考试常见错误分析及常用程序.docx
《VB等级考试常见错误分析及常用程序.docx》由会员分享,可在线阅读,更多相关《VB等级考试常见错误分析及常用程序.docx(32页珍藏版)》请在冰点文库上搜索。
VB等级考试常见错误分析及常用程序
VB等级考试常见错误分析及常用程序
1改错题常见错误设置归纳
改错题是省二级考试上机考试中的基本题型,该题型可全面考查学生对VB语言的掌握及应用水平,建议学生加大对改错题的练习力度,不仅可使学生提高阅读程序的能力,而且对锻炼逻辑思维能力也很有帮助。
省二级考试的改错题中要求不得增删语句,但可适当调整语句位置。
改错题一般设三个改错点,三处错误的考点不重复。
在进行VB编程时,出现的错误可分为三类:
语法错误,运行错误和逻辑错误。
改错题中一般不会出现语法错误,因为在输入程序时,如果出现了语法错误,系统会进行自动的语法检查,出错处会用醒目的红色标识出来。
改错题中的错误一般设置为运行错误和逻辑错误,现将常出现的错误归纳如下:
1.1循环语句
1、DO循环条件设置有误。
如按照题意应为a<=10,而错写成了a<10
2、DO循环中混淆了Until、while的条件形式,如将DOWhile错写成了DOUntil,将loopuntil写成了loopwhile。
3、For循环语句的上限、下限设置有误。
1.2赋值语句
1、数值变量的初值有误,如应该赋初值1但却赋值为0,将至使作乘法运算时结果为0。
2、变量赋值语句位置不合理;如:
求1!
+2!
+3!
+4!
+5!
,试对比下列两段程序。
S=1:
K=0
Fori=1To5
Forj=1Toi
S=S*j
Nextj
K=K+S
Nexti
运行结果为:
K=34863
K=0
Fori=1To5
S=1
Forj=1Toi
S=S*j
Nextj
K=K+S
NextI
运行结果为:
K=153
由于第一段程序中S=1放的位置不正确,所以不能得出正确的结果。
3、同上,逻辑型变量的初始值及赋值位置不正确。
4、字符型变量的初值S=””和S=”“是有差别的,当在一定的条件下,将影响程序的运行结果。
1.3数组元素下标越界
这往往是由于对数组元素的引用超出了对数组的定义。
例:
dima(5)asinteger
forI=1to5
a(i)=I
printa(i)
nextI
printa(i)‘在这句中引用了a(6)元素,引起下标越界错误。
1.4过程调用
在调用过程时形参与实参的对应位置颠倒。
如:
callabc(x,y)callabc(y,x)
subabc(a,b)subabc(a,b)
这类错误的排除,需要在读懂程序的基础上,发现这钟错误的对应关系并进行纠正。
1、形参的传址、传值形式的应用不正确。
如:
按题意形参应为传值方式,但却错用了传址方式。
例:
privatesubform_click()
……
test(n)
printn
endsub
privatesubtest(Iasinteger)
I=I+1
……
endsub
此处纠正错误的方法有多种,常用的有两种,一是修改形参说明为byvalIasinteger,二是修改实参的形式为test((n))。
2、当形参为传址方式时,对应的实参如果是变量,则二者的数据类型必须一致。
OptionExplicit
OptionBase1
PrivateSubForm_Click()
DimStAsString,CharAsString
Dimdata()AsString,IAsInteger,JAsInteger
St="10281018123811181038"
ForI=1ToLen(St)
IfMid(St,I,1)<>"8"Then
Char=Char&Mid(St,I,1)
Else
J=J+1
ReDimPreservedata(J)
data(J)=Char
Char=""
EndIf
NextI
CallConver(data,Char)
PrintChar
EndSub
PrivateSubConver(A()AsString,ChAsinteger)
DimIAsInteger,JAsInteger,NAsInteger,DecAsInteger
ForI=1ToUBound(A)
Dec=0
N=Len(A(I))
ForJ=1ToN
Dec=Dec+Val(Mid(A(I),J,1))*8^(N-J)
NextJ
Ch=Ch&Chr(Dec)
Next
EndSub
以上程序中划线部分即为此错误类型,与ch相对应的实参是char变量,它们的数据类型分别为integer和string,运行程序出现如下错误提示:
Byref参数类型不符,须将二者修改成相同的数据类型。
1.5Exit语句
1、Exit语句有四种形式:
exitfor,exitdo,exitsub,exitfunction。
在改错题中,常常错用Exit语句的几种形式。
如:
①
privatesubabc(xasinteger,flgasboolean)
forI=2tox-1
ifxmodI=0thenexitfor
nextI
ifI>x-1thenflg=true
endsub
②
privatesubabc(xasinteger,flgasboolean)
forI=2tox-1
ifxmodI=0thenexitsub
nextI
ifI>x-1thenflg=true
endsub
以上两段程序,代码非常相似,所不同的是前一段代码中使用了exitfor语句,而第二段程序中使用了exitsub语句。
Exitfor语句使程序转到了for–next语句下面的第一条语句处执行,这是一个分支语句,根据条件I>x-1决定flg是否赋值为true;第二段程序中的exitsub语句则使程序的执行退出了当前abc过程,转去执行调用过程,而使for-next语句下的if语句没有执行。
2、Exit语句出现的位置是否合适?
ForI=1ToUBound(P)-1
ForJ=I+1ToUBound(P)
M=P(I)*P(J)
IfM=NThen
S1=P(I):
S2=P(J)
ExitFunction‘此语句的执行将使下一句Fun=true无法执行
Fun=True‘考虑将这两句调换位置
EndIf
NextJ
NextI
1.6动态数组
1、当动态数组的输出结果为全0时,应考虑是否在redim语句中加preserve参数。
我们知道,对动态数组可使用redim语句进行重新声明,如果redim语句中不加preserve参数,则会在重新声明数组的同时,将已有的元素值全部进行初始化,对数值型的数组,其原有元素值会全部清为0。
如果在redim语句中加上了preserve参数,则在重新声明动态数组的时候,保留元素原有值不变。
2、在使用动态数组时,往往采用这样的固定结构:
100n=n+1
200redimpreservea(n)
300a(n)=abc
学生可有针对性地检查各语句是否配套出现且先后次序是否正确,如果将100号语句和200号语句交换位置,就会发生下标越界错误。
1.7函数混淆
1、cstr(x)与str(x)混淆。
这两个函数的作用都是将数值型数据转化为字符串型数据,但还是存在着微小的差别,如果X=5,则cstr(x)=”5”,而str(x)=”5”,也就是说len(cstr(x))=1而len(str(x))=2,相差一个符号位。
2、ASC()与Chr()混淆。
Chr函数为求一个数值所对应的字符,如Chr(65)=“A”,ASC函数为求一个字符的ASCII码,如ASC(”B”)=66,一定要依据题意选用合适的函数。
1.8运算符
1、关系运算符.这一类错误常设置在包含条件判断的语句中,如If—endif语句,do—loop语句。
错用了关系运算符,如>错用为>=,<错用为<=,=错用为<>等。
2、逻辑运算符
这一类错误中往往将AND与OR错用,如:
AANDB写成了AORB,致使程序运行得不到正确结果,如果在条件判断语句中出现了逻辑运算符AND、OR,请仔细考查其正确性。
3、算术运算符
这类错误经常出现在mod和\(整除)上,AmodB表示A除以B的余数,如:
5mod2=1,而A\B表示A除以B的整数部分,如:
5\2=2
1.9变量的数据类型
1、在声明变量时使用了不符合题意的数据类型。
如:
本程序的功能是求数列
的和,规定计算到第k项的值≤10-6为止(输入X=2测试程序,正确结果为S=0.9985868)。
OptionExplicit
PrivateFunctionpt(xAsSingle,nAsInteger)AsSingle
DimpAsInteger,iAsInteger ‘改为pAsSingle ①
p=0 ‘改为p=1
Fori=1Ton
p=p*i/(x+i)
Nexti
pt=p
EndFunction
PrivateSubForm_Click()
DimxAsSingle,kAsInteger,iAsInteger
DimaAsDouble,sAsSingle,pAsDouble
Do
x=InputBox("输入一个大于1的数:
",,1)
Ifx<=1ThenMsgBox"数据错误,重输!
",vbOKOnly
LoopUntilx<1 ‘改为x>1
k=1
Do
a=pt(x,k)
s=s+a
Ifa<=0.000001ThenExitDo
k=k+1
Loop
Prints
EndSub
在求数列之和时,由于数列本身的值为一个小于1的数,如果①不进行更正,其它错误均已更正,也得不到正确的运行结果而始终为0。
练习题:
【题目】本程序的功能是:
从给定的数据范围中找出所有各位数字之和为10的数据,若一次求得各位数字之和不是壹位数,则继续求此和数的各位数字之和。
例如47854=>28=>10就是符合要求的数。
(2004秋上机试卷VB01改错题)
PrivateSubCommand1_Click()
DimstAsLong,seAsLong,iAsLong
DimsAsString
st=Text1
se=Text2
Fori=stTose
Ifsum(i)=10Then
s=s&i&vbCrLf
EndIf
Nexti
Text3=s
EndSub
PrivateFunctionsum(nAsLong)AsInteger‘ByValnaslong
DimkAsInteger
sum=0‘下移至横线位置
Do
Do
k=nMod10
sum=sum+k
n=n\10
LoopUntiln<0‘n<=0
Ifsum>10Then
n=sum
Else
ExitFunction
EndIf
Loop
EndFunction
VB常用公共程序
1求最大公约数
PrivateSubCommand1_Click()
DimmAsInteger,nAsInteger
DimrAsInteger
m=Text1.Text
n=TextText
Do
r=mModn
m=n
n=r
LoopWhiler<>0
Text3.Text=m
EndSub
PrivateSubCommand2_Click()
End
EndSub
PrivateSubCommand3_Click()
Text1=“”
Text2=“”
Text3=“”
EndSub
2几种不同的排序法
Dims(10)AsInteger,nAsInteger
PrivateSubCommand1_Click()
Picture1.Cls
Randomize
n=10
Fori=1To10
s(i)=Int(100*Rnd)+1
Picture1.Prints(i);
Nexti
Picture1.Print
Picture1.Print
EndSub
‘选择排序法
PrivateSubCommand2_Click()
Fori=1Ton-1'外层循环N-1次
Forj=i+1Ton'内层依赖外层
Ifs(j)>s(i)Then
t=s(i)'交换
s(i)=s(j)
s(j)=t
EndIf
Nextj
Nexti
Fori=1Ton
Picture1.Prints(i);
Nexti
Picture1.Print
Picture1.Print
EndSub
‘直接排序法
PrivateSubCommand3_Click()
Fori=1Ton-1
pointer=i'初始化pointer,在每轮比较开始处
Forj=i+1Ton
Ifs(j)>s(pointer)Thenpointer=j
Nextj
Ifi<>pointerThen
t=s(i)
s(i)=s(pointer)
s(pointer)=t
EndIf
Nexti
Fori=1Ton
Picture1.Prints(i);
Nexti
Picture1.Print
Picture1.Print
EndSub
’冒泡排序法
PrivateSubCommand4_Click()
Fori=1Ton-1
Forj=1Ton-i'比较次数逐次减少
Ifs(j)
t=s(j)
s(j)=s(j+1)
s(j+1)=t'立即互换
EndIf
Nextj
Nexti
Fori=1Ton
Picture1.Prints(i);
Nexti
Picture1.Print
Picture1.Print
EndSub
3几种不同的查找方法
OptionBase1
Dims(10)AsInteger,xAsInteger,nAsInteger
PrivateSubCommand1_Click()
DimiAsInteger
n=10
Fori=1Ton
s(i)=Int(100*Rnd)+1
Picture1.Prints(i);
Nexti
Picture1.Print
x=InputBox("输入待查找的数:
")
EndSub
PrivateSubCommand2_Click()‘顺序查找
Fori=1ToUBound(s)
Ifs(i)=xThenExitFor
Nexti
'退出的两种情况
Ifi<=UBound(s)Then
Picture1.Print"找到"&x&"它的位置数为:
"&I
Else
Picture1.Print"对不起,没找到!
"
EndIf
EndSub
PrivateSubCommand3_Click()‘二分查找
DimresultAsBoolean
DimtopAsInteger,bottomAsInteger,middleAsInteger
Fori=LBound(s)ToUBound(s)–1‘先排序,后查找
Forj=i+1Ton
Ifs(i)>s(j)Then
temp=s(i)
s(i)=s(j)
s(j)=temp
EndIf
Nextj
Nexti
Picture1.Print"排序后的数组是:
";
Fori=LBound(s)ToUBound(s)
Picture1.Prints(i);
Nexti
Picture1.Print
result=False'初始化逻辑变量
top=LBound(s)'初始化指针
bottom=UBound(s)
DoWhile(top<=bottom)
middle=(bottom+top)/2
Ifx=s(middle)Then
result=True'找到
ExitDo
ElseIfx>s(middle)Then'未找到,根据大小确定下一步比较范围
top=middle+1
Else
bottom=middle-1
EndIf
Loop
IfresultThen
Picture1.Print"找到"&x&"它的位置数为:
"&CInt(middle)
Else
Picture1.Print"对不起,没找到!
"
EndIf
EndSub
注:
由于二分查找是在有序数列中进行查找的一种方法,所以要先排序后再进行查找。
4判断素数的方法
方法一:
调用通用过程
privatesubcmd1_click()
dimxasinteger,flgasBoolean
x=val(text1.text)
CallPrime(x,flg)
ifflg=truethen
msgboxX&“是素数”
else
msgboxX&“不是素数”
endif
endsub
SubPrime(xAsInteger,YnAsBoolean)
DimiAsInteger
Yn=false
forI=2ToSqr(x)
IfxModi=0TheExitfor
NextI
IfI>Sqr(x)thenYn=True
EndSub
方法二:
调用函数过程
privatesubcmd1_click()
dimxasinteger,flgasBoolean
x=val(text1.text)
ifPrime(x)then
msgboxX&“是素数”
else
msgboxX&“不是素数”
endif
endsub
FunctionPrime(xAsInteger)AsBoolean
DimiAsInteger
Fori=2ToSqr(x)
ifxModi=0ThenExitFunction
EndIf
nexti
Prime=True
EndFunction
5求出一个任意正整数的因子和质因子
方法一:
求因子
Privatesubcommand1_click()
Dimintaasinteger,stasstring
Inta=text1.text
Callfactor(inta,st)
Texttext=st
Endsub
Privatesubfactor(byvalNasinteger,sasstring)
DimIasinteger
ForI=1ton-1
IfNmodI=0thens=s&str(i)
NextI
Endsub
方法二:
求质因子
PrivateSubfactor(ByValNAsInteger,sAsString)
DimIAsInteger
A=N:
I=2
DoWhileA<>1AndI<=N/2
Do
IfAModI=0Then
s=s&Str(I)
Else
ExitDo
EndIf
A=A\I
Loop
I=I+1
Loop
EndSub
6求裴波拉契数列的前N项
方法一:
使用数组
Privatesubform_click()
Dimfb()asinteger,Iasinteger
N=inputbox(“输入N的值”)
Redimfb(n)
Fb
(1)=1:
fb
(2)=1
ForI=3ton
Fb(i)=fb(I-2)+fb(I-1)
NextI
ForI=1ton
Text1=Text1&str(fb(i))&““
NextI
Endsub
方法二:
递归过程
Privatesubform_click()
Dimnasinteger,Iasinteger
N=inputbox(“输入N的值”)
ForI=1toN
Printfib(i)
Nexti
Endsub
Privatefunctionfib(ByvalNasinteger)aslong
IfN=1o