第4章 控制程序流程.docx
《第4章 控制程序流程.docx》由会员分享,可在线阅读,更多相关《第4章 控制程序流程.docx(60页珍藏版)》请在冰豆网上搜索。
第4章控制程序流程
第4章控制程序流程
如果没有任何控制程序结构的代码干涉,程序运行时基本的流程是由左而右,由上而下运行各个语句,直到整个程序结束。
对于简单的问题来说,仅仅运用这种流程来编写程序是可以的,但是随着问题的复杂化,程序运行中不同的状况不断发生,这种一路到底的模式是不可能解决问题的。
程序控制结构从最简单的强制跳行GoTo语句,到选择控制与循环控制两个主要类型,而且控制结构还能包含在其他控制结构中形成嵌套控制结构,样式千变万化,可以改变程序的运行方向。
第1节条件表达式
在日常生活中,常常需要对给定的条件进行分析、比较和判断,并根据判断结果采取不同的操作。
例如我们出门时,会根据天气情况决定是否带伞等。
4.1.1程序的三种基本结构
结构化程序由若干个基本结构组成,每一个基本结构可以包含一个或若干个语句。
结构化程序设计的基本控制结构有三种:
顺序结构、选择结构和循环结构。
1.顺序结构
前面设计和编写的一些程序(事件过程)都是顺序结构的,即整个程序按书写顺序依次执行。
如图4.1所示,先执行A,再执行B,即自上而下依次运行。
图4.1顺序结构图4.2选择结构
其中,图4.1(b)为N-S结构化流程图。
N-S图规定了一些图形元素,以表示三种基本结构,每个元素用不同的框来表示。
或者说,一个算法框是由一些代表基本结构的基本框像堆积木一样构造而成的。
由于N-S图像是一个多层的盒子,也称盒图。
2.选择结构
如图4.2所示,P代表一个条件,当P条件成立(或称为“真”)时执行A,否则执行B。
只能执行A或B之一,两条路径汇合在一起然后是出口。
3.循环结构
有两种循环结构:
(1)当型循环结构,如图4.3所示。
当P条件成立时,反复执行A操作。
直到P为假时才停止循环。
(2)直到型循环结构,如图4.4所示。
先执行A操作,再判断条件P是否为“假”,若为“假”,再执行A,如此反复,到P为“真”时为止。
图4.3当型循环结构图4.4直到型循环结构
由以上基本结构组成的程序能处理任何复杂的问题。
图中方框A、B既可以是一条简单的语句,也可以是一个基本结构。
4.1.2关系表达式
在条件语句P中作为判断依据的表达式称为“条件表达式”,条件表达式的取值为布尔值:
真(True)或假(False)。
关系表达式是条件表达式中比较简单的一种,它是指用关系运算符将两个表达式连接起来的式子。
关系运算符也称比较运算符,用来对两个表达式的值进行比较,比较结果是一个布尔值。
VisualBasic关系运算符主要有以下6种:
<(小于)
<=(小于等于)
>(大于)
>=(大于等于)
=(等于)
<>(不等于)
关系运算符的优先级别相同,它们低于算术运算符,但高于逻辑运算符。
关系运算符两侧可以是数值表达式、字符型表达式或日期型表达式,也可以是常量、变量或函数,但其两侧的数据类型必须完全一致。
例如,下面都是合法的关系表达式:
a>b,3<=7,-2.6>7.5,'a'<'b',(x+2)<>(b-2),a>b<(c/2)
需要注意的是:
(1)关系运算符低于算术运算符,如计算表达式“(x+2)<>(b-2)”值与“x+2<>b-2”是一样的,即同为真或同为假。
(2)数值型数据按其数值大小进行比较,日期型数据可看成“yyyymmdd”的整数形式进行数值比较,字符型数据按其ASCII码值进行比较。
例如:
3<=7'结果为True
-2.6>7.5'结果为False
'a'<'b''结果为True
(3)当对单精度或双精度使用比较运算时,可能会得出非常接近但不相等的结果。
例如:
1.0/3.0*3.0=1.0
该式子在数学中是一个恒等式,但在计算机上执行时可能会给出假值(0)。
因此,应避免对两个浮点数作“相等”或“不相等”的判断。
可以把上式改为“只要它们小于一个很小的数时,就认为它们相等”的形式,如:
Abs(1.0/3.0*3.0-1.0)<1E-5
(4)注意关系表达式与数学不等式的区别,如数学表达式:
x≤y≤z,并不能写成x<=y<=z,其含义为:
x<=y且y<=z。
4.1.3逻辑表达式
逻辑运算也称布尔运算。
用逻辑运算符连接两个或多个关系表达式,组成一个逻辑表达式。
VisualBasic提供的逻辑运算符有:
And,Or,Not,Xor,Eqv,Imp等6种,其中常用的为前3种。
(1)And(与)。
对两个关系表达式的值进行比较,如果两个表达式的值均为True,结果才为True,否则为False。
例如:
2+3>5And3<5'结果为False
2+3>=5And1'结果为True
(2)Or(或)。
对两个表达式进行比较,如果其中某一个表达式的值为True,结果为True。
只有两个表达式的值均为False时,结果才为False。
例如:
2+3>5Or3<5'结果为True
(3)Not(非)。
由真变假或由假变真,进行“取反”运算。
例如:
3>8'结果为False
Not(3>8)'结果为True
另外,Xor(异或)是指如果两个表达式同时为True或同时为False,结果为False,否则为True。
Eqv(等价)与异或正好相反,即如果两个表达式同时为True或同时为False,结果为True,否则为False。
Imp(蕴含)则是指当第一个表达式为True,且第二个表达式为False时,结果为False。
其真值表如表4.1所示。
表4.1逻辑运算真值表
a
b
aAndb
aOrb
Nota
aXorb
aEqvb
aImpb
True
True
True
True
False
False
True
True
True
False
False
True
False
True
False
False
False
True
False
True
True
True
False
True
False
False
False
False
True
False
True
True
逻辑运算符的优先顺序为:
Not→And→Or→Xor→Eqv→Imp。
也就是说,逻辑非(Not)级别最高,逻辑蕴含(Imp)级别最低。
逻辑运算符的优先级别低于关系运算符,更低于算术运算符。
第2节选择结构程序语句
选择结构是计算机科学用来描述自然界和社会生活中分支现象的重要手段。
其特点是根据所给定的条件为真与否,而决定从各实际可能的不同分支中执行某一分支的相应操作。
在VisualBasic中,实现选择结构的语句主要有:
If语句和SelectCase语句。
4.2.1If语句
IF语句的格式有两种:
单行结构和块结构。
1.单行结构条件语句
单行条件语句的格式为:
If<条件>Then<语句1>[Else<语句2>]
If语句的<条件>可以是关系表达式、逻辑表达式,也可以是数值表达式(非0为真,0为假)。
在条件成立时,执行语句1,不成立时执行语句2,且语句2可省略。
例如,在从键盘上输入数据时,如果值为0,则弹出提示信息的语句可写成:
Ifx=0ThenMsgBox("输入数据错误!
")
【例4.1】输入x,计算y的值。
其中:
分析:
该题是数学中的一个分段函数,它表示当x≥0时,用公式y=1+x来计算y的值;当x<0时,用公式y=1-2x来计算y的值。
在选择条件时,即可以选择x≥0作为条件,也可选择x<0作为条件。
如图4.5所示,为选择x≥0作为条件的流程图。
图4.5例4.1程序流程图图4.6例4.1用户界面
可建立如图4.6所示的用户界面,并设置其相应的属性值。
然后,编写命令按钮的Click代码。
程序代码如下:
PrivateSubCommand1_Click()
Dimx,yAsSingle
x=Val(Text1.Text)
Ifx>=0Theny=1+xElsey=1-2*x
Label3.Caption=y
EndSub
前面的例3.2,曾经设置了一个通过单选按钮改变字体的字体浏览程序。
可以通过使用If语句对其进行修改,比如增加加粗、倾斜、下划线等字形浏览功能,如图4.7所示。
图4.7改进的字体浏览器
这只需编写3个复选框的Click事件代码,程序代码如下:
PrivateSubCheck1_Click()
IfCheck1.Value=1ThenDisplay.FontItalic=True_
ElseDisplay.FontItalic=False
EndSub
PrivateSubCheck2_Click()
IfCheck2.Value=1ThenDisplay.FontBold=True_
ElseDisplay.FontBold=False
EndSub
PrivateSubCheck3_Click()
IfCheck3.Value=1ThenDisplay.FontUnderline=True_
ElseDisplay.FontUnderline=False
EndSub
另外,格式中的<语句1>和<语句2>也可以是包含If语句的语句,如:
Ifx>=0ThenIfx>0Theny=1Elsey=0Elsey=-1
当嵌套层数较多时,应注意嵌套的正确性,一般原则是每一个Else部分都与它前面未配对的IF-Then配对。
2.IIF函数
在If语句中,若条件表达式为“真”和“假”时,且都只执行一个赋值语句给同一个变量赋值时,可以用IIF函数来处理。
例如,若有以下If语句:
If(a>b)Thenmax=aElsemax=b
可以用下面的函数来处理:
max=IIF(a>b,a,b)
可见,IIF函数就是If语句简写版本,其格式为:
IIF(<条件表达式>,<真部分>,<假部分>)
<真部分>与<假部分>是当条件表达式为真(或假)时函数的返回的值,它们可以是任何表达式。
例如,例4.1中的Command_Click的代码可改写为:
PrivateSubCommand1_Click()
DimxAsSingle
x=Val(Text1.Text)
Label3.Caption=IIF(x>=0,1+x,1-2*x)
EndSub
3.块结构条件语句
虽然单行If语句使用方便,可以满足许多选择结构程序设计的需要,但是当Then部分和Else部分包含较多内容时,在一行中就难以容纳所有命令。
为此,VisualBasic提供了块If语句,将一个选择结构用多个语句行来实现。
块If语句也称为多行If语句,其格式为:
If<条件>Then
语句序列1
[Else
语句序列2]
EndIf
块结构条件语句的执行过程是:
先测试条件,如果条件为True,则执行Then后面的语句序列1;如果条件为False,并且有Else子句,则程序执行Else部分的语句序列2。
在执行了Then或Else后面语句块之后,程序退出块结构条件语句,继续执行EndIf后面的语句。
例如,可用块结构形式编写例4.1中的程序代码,如下所示:
PrivateSubCommand1_Click()
Dimx,yAsSingle
x=Val(Text1.Text)
Ifx>=0Then
y=1+x
Else
y=1-2*x
EndIf
Label3.Caption=y
EndSub
语句序列中的语句不能与其前面的Then在同一行,否则VisualBasic认为是一个单行结构的条件语句。
也就是说,块结构与单行结构条件语句的主要区别就是看Then后面的语句是否和Then在同一行。
如果在同一行,为单行结构,否则为块结构。
对于块结构,必须以“EndIf”结束,单行结构没有“EndIf”。
【例4.2】数字时钟。
用户可以根据个人爱好选择时钟显示是24小时制式,还是12小时制式。
分析:
在第3章的3.2.5节中,已经建立了一个简单的数字时钟。
这里,可以为其增加两个单选按钮,以便用户选择24或12小时显示格式。
并且希望上午显示AM,下午显示PM,这可通过增加一个标签来显示AM/PM,如图4.8所示。
图4.8数字时钟
各事件过程代码如下:
PrivateSubOption1_Click(IndexAsInteger)
Label2.Visible=True
EndSub
PrivateSubOption2_Click()
Label2.Visible=False
EndSub
PrivateSubTimer1_Timer()
Label2.Caption=IIf(Hour(Time)>12,"PM","AM")
IfOption2.Value=TrueThen
Form1.Tag="hh:
mm:
ss"
Else
Form1.Tag="hh:
mm:
ssAM/PM"
EndIf
Label1.Caption=Format(Time,Form1.Tag)
EndSub
4.IF语句的嵌套
如果在IF语句中,语句序列1或语句序列2本身又是一个If语句,则称为IF语句的嵌套。
【例4.3】编程求一元二次方程ax2+bx+c=0的根,其中a不等于0。
分析:
由数学知识可知,在求一元二次方程式根时,要使用b2-4ac,如果a不等于0,有以下几种情况:
∙当b2-4ac>0时,有两个实根:
,
∙当b2-4ac=0时,有两个相等实根:
∙当b2-4ac<0时,有两个虚根,即在实数范围内方程无解。
如图4.9所示,为求解方程的程序流程图。
图4.9求解方程流程图
可以通过文本框输入二次方程ax2+bx+c=0的3个系数a,b,c的值。
利用标签显示求解方程的结果。
由于方程可以无根,可增加一个标签专门用来显示无根情况,这就需要对几个标签的Visible属性进行设置。
在窗体上添加的控件结构如图4.10所示。
图4.10例4.3的用户界面
编写两个命令按钮的Click事件,程序代码为:
PrivateSubCommand1_Click()
Text1.Locked=False
Text2.Locked=False
Text3.Locked=False
Label1.Visible=False
Label2.Visible=False
Label3.Visible=False
Label8.Visible=False
Label9.Visible=False
EndSub
PrivateSubCommand2_Click()
Dima,b,cAsInteger
Dimd,p1,p2AsSingle
Text1.Locked=True
Text2.Locked=True
Text3.Locked=True
a=Val(Text1.Text)
b=Val(Text2.Text)
c=Val(Text3.Text)
Ifa=0Then
Label3.Caption="非二次方程"
Label3.Visible=True
Else
d=b*b-4*a*c
p1=-b/(2*a)
Ifd>=0Then
Label1.Visible=True
Label2.Visible=True
Label8.Visible=True
Label9.Visible=True
Ifd>0Then
p2=Sqr(d)/(2*a)
Label1.Caption=p1+p2
Label2.Caption=p1-p2
Else
Label1.Caption=p1
Label2.Caption=p1
EndIf
Else
Label3.Caption="无实根"
Label3.Visible=True
EndIf
EndIf
EndSub
如图4.11所示为程序运行后的结果。
图4.11例4.3程序运行结果
在嵌套结构中,只能实现完全“包含”,不能相互“骑跨”,即把If…Then…Else看作另一个IF结构中的语句序列中的一条语句。
另外,当出现多层If语句嵌套时,程序比较冗长,为了简化书写,VisualBasic提供了带ElseIf的块If语句来处理当条件为假时又内嵌块If语句的情形。
其语法格式为:
If<条件1>Then
[语句序列1]
ElseIf<条件2>Then
[语句序列2]
…
[Else
[其他语句序列]]
EndIf
在If块中,Else和ElseIf子句都是可选的。
可以放置任意多个ElseIf子句,但是都必须在Else子句之前。
当程序运行到If块时,首选测试<条件1>,如果条件为True,则执行Then之后的语句。
如果条件为False,则每个ElseIf部分的条件式会依次计算并加以测试。
如果找到某个为True的条件时,则其紧接在相关的Then之后的语句序列会被执行。
如果没有一个EsleIf条件为True(或根本就没有ElseIf子句),则程序会执行Else部分的其他语句序列。
在执行完Then或Else之后的语句序列后,会继续执行EndIf之后的语句。
4.2.2SelectCase语句
IF语句只有两个分支可供选择,而实际问题中常常需要用到多分支的选择。
例如,学生成绩分类,90分以上为优、80~90分为良、70~80分为中、……。
当然这些都可以用嵌套的IF语句来处理,但如果分支较多,则嵌套的IF语句层数多,程序冗长而且可读性降低。
VisualBasic中提供了SelectCase语句以实现多分支选择。
SelectCase语句的语法格式为:
SelectCase<测试条件>
[Case<表达式1>
[语句序列1]]
[Case<表达式2>
[语句序列2]]
……
[CaseElse
[<其他语句序列>]]
EndSelect
SelectCase语句的功能是根据“测试条件”的值从多个语句块中选择符合条件的一个语句序列执行。
<表达式n>用来测试其中是否有值与测试条件相匹配,其形式可以为下面的几种格式:
∙表达式[,表达式][,…]。
例如:
Case1,3,5,7。
∙表达式To表达式。
用来指定一个值范围,例如:
Case1To7。
∙Is关系运算表达式。
可以配合关系运算符来指定一个数值范围,例如:
Is<300。
SelectCase语句的执行过程是先对“测试条件”求值,然后测试该值与哪一个Case子句中的“表达式”相匹配。
如果找到了,执行与该Case语句有关的语句序列,并把控制转移到EndSelect后面的语句。
如果没有找到,执行与CaseElse子句有关的语句序列,再把控制转移到EndSelect后面的语句。
【例4.4】某商场为了促销,采用购物打折扣的优惠办法,每位顾客一次购物:
(1)在1000元以上者,按八折优惠;
(2)在500元以上,但不足1000元者,按八五折优惠;
(3)在300元以上,但不足500元者,按九折优惠;
(4)在100元以上,但不足300元者,按九五折优惠;
(5)不足100元者,没有优惠。
分析:
设购物款数为a元,优惠价为b元,优惠付款公式为:
0.8a(a≥1000)
0.85a(1000>a≥500)
b=0.9a(500>a≥300)
0.95a(300>a≥100)
a(100>a)
其流程图如图4.12所示。
图4.12例4.4程序流程图
这里,我们通过文本框输入购物款,标签输出优惠价,单击命令按钮进行计算。
其中,命令按钮的代码如下:
PrivateSubCommand1_Click()
Dima,bAsSingle
a=Val(Text1.Text)
SelectCasea
CaseIs>=1000
b=0.8*a
CaseIs>=500
b=0.85*a
CaseIs>=300
b=0.9*a
CaseIs>=100
b=0.95*a
CaseElse
b=a
EndSelect
Label3.Caption=b
EndSub
程序执行结果如图4.13所示。
图4.13例4.4程序执行结果
当然,命令按钮的事件过程代码也可以用If语句的嵌套形式来实现,如下:
PrivateSubCommand1_Click()
Dima,bAsSingle
a=Val(Text1.Text)
Ifa>=1000Then
b=0.8*a
ElseIfa>=500Then
b=0.85*a
ElseIfa>=300Then
b=0.9*a
ElseIfa>=100Then
b=0.95*a
Else
b=a
EndIf
Label3.Caption=b
EndSub
SelectCase语句与If语句的功能类似。
一般来说,可以使用If语句形式的地方,也可以使用SelectCase语句。
在使用SelectCase语句时,如果同一个值在多个Case子句中出现,则只执行符合要求的第一个Case子句的语句序列。
Case子句的顺序对执行结果没有影响,但必须放在CaseElse子句之前。
如果任何一个Case子句都没有与测试条件相匹配的值,而且也没有CaseElse子句,则不执行任何操作。
4.2.3秒表的设计
秒表可以在运动场上测试运动员赛跑项目的成绩,日常生活也常常用到它。
当按下表的“开始”按钮后,秒表开始计时,如图4.14所示。
可重新开始计时,也可暂停,然后继续计时。
图4.14简单的秒表图4.15秒表的设计界面
1.建立用户界面
选择“新建”工程,进入窗体设计器,添加两个命令按钮Command1,Command2、一个标签Label1、一个计时器Timer1,如图4.15所示。
各对象属性的设置如表4.2所示。
表4.2秒表中各对象属性设置值
控件
属性
设置值
Command1
Caption
开始
Command2
Caption
重置&R
Label1
Caption
00:
00:
00.00
FontName
TimesNewRoman
FontSize
48
Timer1
Interv