第四章 控制结构
4.1顺序控制结构 注意:当表达式的类型与变量的类型不一致时,强制转换成左边的精度 顺序结构就是各语句按出现的先后次序执行。一般的程序设计语言中,顺序结构的语句主要是赋值语句、输入/输出语句等。在VB中也有赋值语句,而输入/输出可以通过文本框、print方法等实现,也可以通过系统提供的函数和过程来实现。 4.1.1赋值语句 赋值语句的一般形式如下: 变量名=表达式 对象.属性=表达式 程序执行时,先计算右边表达式的值,然后将值赋给左边的变量或属性。 例如: X=100 ‘ 把数值赋给变量X; Text1.Text=" VB欢迎你" ‘把字符串赋给Text1的Text属性 Label1.Caption = Date() ‘把Date函数的结果赋给Label1的Caption属性 Label1.Top = Label1.Top - 100 ‘把表达式的值赋给Label1的Top属性 在赋值语句中,赋值运算符“=”代表赋值操作,而不代表等量关系。 注意:当表达式的类型与变量的类型不一致时,强制转换成左边的精度
表达式可以是任何类型的表达式,一般与左边的变量类型一致 变量名=表达式 表达式可以是任何类型的表达式,一般与左边的变量类型一致 例如:Dim i as Integer i=3+2 如果右边表达式类型与左边变量类型不同,则: 1)表达式均为数值型,但精度不同时,表达式结果自动转换成左边的精度在赋值给变量。如:i%=3.56 i=4
2)变量为数值型,表达式为字符串时,若表达式为数字型字符串,则自动转换为数值型在赋值给变量。 x%=“123” x=123 x%=“abc” 出错 x!=“” 出错 3)变量为数值型,表达式为逻辑型时,true转换成-1,false转换成0后赋值给变量 x%=true x-1
4)变量为逻辑型,表达式为数值型时,非0转换成true,0转换成false后赋值给变量 Dim Boolean b b=21 btrue 5)变量为字符型,表达式为非字符型时,表达式的结果自动转换为字符型后赋值给变量 Dim s as String s=123 s”123”
使用赋值语句时应注意: 以下的赋值语句均是错误的: 不能在一句赋值语句中为多个变量赋值: 5=x+y 常量在左边 x+y=5 表达式在左边 Sin(x)=x+y 不能在一句赋值语句中为多个变量赋值: 正确 x=1 y=1 z=1 错误:x=y=z=1
4.1.2人机交互函数和过程 Vb程序与用户之间的直接交互可以通过InputBox ( )函数、MsgBox ( )函数和Msg过程进行。 1.InputBox()函数 InputBox()函数可以产生一个对话框,这个对话框作为输入数据的界面,等待用户输入数据,当用户单击“确定“按钮或回车时,函数返回输入的值,类型为字符型。函数格式如下: 变量$=InputBox(Prompt[,Title][,Default][,XPos][,YPose])
例4-1 应用InputBox函数进行患者信息的输入,运行界面如图 程序代码如下: Private Sub Form_Click() Dim cl$, msg1$, msg2$, msg3$, msg$, I$ cl = Chr(13) + Chr(10) ‘回车、换行 msg1 = "请输入患者姓名" msg2 = "输入后单击确定按钮" msg3 = "或按回车键" msg = msg1 + cl + msg2 + cl + msg3 I = InputBox (msg, "患者信息输入框", "张三", 400, 400) End Sub
注意 各项参数次序必须一一对应,Prompt项不可省略, 其他项可以省略,但处于中间的默认参数要用逗号占位符跳过 注意 各项参数次序必须一一对应,Prompt项不可省略, 其他项可以省略,但处于中间的默认参数要用逗号占位符跳过 该函数返回的值为字符型,如果需要输入数值并参加运算时,在运算前运用Val(c)函数将其类型转换为数值类型 例:inputBox.vbp
MsgBox()函数可以产生一个消息框,等待用户选择按钮,当用户单击某个按钮时,函数返回按钮的值,类型为整型。函数格式如下: 4.1.2人机交互函数和过程 2.MsgBox()函数和MsgBox过程 MsgBox()函数可以产生一个消息框,等待用户选择按钮,当用户单击某个按钮时,函数返回按钮的值,类型为整型。函数格式如下: 变量%=MsgBox (Prompt[,Type] [,Title]) Promp:字符串表达式,用于提示信息 Type:消息框类型 Title:字符串表达式,在标题栏中显示
变量%=MsgBox (Prompt[,Type] [,Title]) 分组 内部常数 按钮值 描述 按钮数目 VBOkOnly VBOkCancel VBAboutRetryignre VBYesNoCancel VBYesNo VBRetryCancel 1 2 3 4 5 只显示“确定”按钮 显示“确定”“取消”按钮 显示“终止”“重试”“忽略”按钮 显示“是”“否”“取消”按钮 显示“是”“否”按钮 显示“重试”“取消”按钮 图标类型 VBCritical VBQusetion VBExclsmation VBinformation 16 32 48 64 关键信息图标 红色STOP标志 询问信息图标? 警告信息图标! 信息图标i 默认按钮 VBDefaultButton1 VBDefaultButton2 VBDefaultButton3 256 512 第1个按钮为默认 第2个按钮为默认 第3个按钮为默认 模式 VBApplicationModel VBSystemModel 4096 应用模式 系统模式
例如:要显示“重试”、“取消按钮”、关键信息图标 红色stop图标,第一个按钮为默认、系统模式 type值为5+16+0+4096,或 VBRetryCancel+VBCritical+VBDefualtButton+VBSystomModel 例 msgBox.vbp t = vbRetryCancel + vbCritical + VBDefualtButton + VBSystomModel ret = MsgBox("消息框示例", t, "消息框")
MsgBox函数返回所选按钮整数值的意义如下表所示: 内部常数 返回值 被单击的按钮 VBOk VBCancel VBAbout VBRetry VBIgnre VBYes VBNo 1 2 3 4 5 6 7 确定 取消 终止 重试 忽略 是 否 若只需给出prompt参数,可以这样使用 Ret=msgBox “prompt”
4.2选择结构 4.2.1 IF条件语句 1.IF……Then 语句(单分支结构) 语句形式: 表达式 语句块 F T 4.2.1 IF条件语句 1.IF……Then 语句(单分支结构) 语句形式: (1) IF < 表达式 > Then 语句块 End IF 单分支结构流程示意图 (2) IF <表达式> Then 语句块 其中:表达式一般为关系表达式、逻辑表达式,也可以为算术表达式。表达式的值按非零为True ,零为False 进行处理。 语句块:可以是一条或多条语句。如果采用形式(2)表示则语句之间要用冒号分隔,并且一定写在同一行上。 If 和end if 要成对出现
例4-3已知两个变量x和y,比较它们的大小,使x中的值大于y。(要实现两个变量中的数互相交换通常以使用第三变量为过渡,在此为t)语句如下: IF x < y Then t=x ‘将变量x中的值暂时存放于变量t中 x=y ‘用变量y中的值替代变量x中的值 y=t ‘再将原变量x中的值替代变量y中的值 End IF 或者 IF x < y Then t=x : x=y: y=t
2.IF……..Then……Else(双分支结构) 语句形式: IF <表达式> Then <语句块1> Else <语句块1> Else <语句块2> End IF 或者: IF <表达式> Then <语句块1> Else <语句块2> 表达式 语句块1 语句块2 F T 双分支结构流程示意图 如果表达式的值为非零或True执行语句块1,否则执行语句块2。
例4-2 编写一医生工作站的登录检验程序,运行界面如图4-3。对登录名(医生工号)和密码的规定如下: 例4-2 编写一医生工作站的登录检验程序,运行界面如图4-3。对登录名(医生工号)和密码的规定如下: (1)医生工号不超过6位数字,密码为6位字符,密码输入时显示为“*”。本题假设密码为“cljuan”。 (2)当医生工号输入非数字字符,密码不正确时,显示相关信息。 (3)若单击“重试”按钮,则清除原来输入的内容,焦点定位在原输入文本框,等待用户输入。若单击取消按钮,程序停止运行。 本程序运行结果如图所示,程序代码见后页。
例4-2 程序代码如下: Private Sub Command1_Click() Dim I As Integer IF Not Text2 = "cljuan" Then I= MsgBox("密码错误", 5 +64+ 0 + VBSystemModel, "登录密码") IF I = 2 Then End Else Text2 = "" ‘用户单击“取消”按钮返回按钮值 text2=“” ‘用户单击”重试”按钮文本框置空,等待用户重新输入 Text2.SetFocus ‘将焦点设置在文本框2上,方便用户输入 End IF End Sub Private Sub Text1_LostFocus() ‘ 焦点离开文本框1时触发LostFocus事件 IF Not IsNumeric(Text1) Then ‘利用IsNumeric()函数判断文本框中输入的是否为数字字符 MsgBox "医生工号必须是数字字符" Text1 = "" Text1.SetFocus
3.IF……Then……ElseIF(多分支结构) 语句形式: IF <表达式1>Then <语句块1> ElseIF <表达式2> Then <语句块2> [Else <语句块n+1> ] End IF T 表达式1 表达式2 表达式n 语句块1 语句块2 语句块n 语句块n+1 F 多分支结构流程示意图 … … 不管有几个分支,依次判断,当某条件满足,执行相应的语句,其余分支不再执行;若条件都不满足,且有Else子句,则执行该语句块,否则什么也不执行。. ElseIf不能写成 Else If。
例4-5 按照世界卫生组织(WHo)建议使用的血压标准是:凡正常成人收缩压应小于或等于140MmHg,舒张压小于或等于90MmHg。如果成人收缩压大于或等于160MmHg,舒张压大于或等于95MmHg为高血压;血压值在上述两者之间,亦即收缩压在141—159MmHg之间,舒张压在91-94MmHg之间,为临界高血压。低血压通常指血压低于90/60MmHg。运行界面与程序代码如下: Private Sub Command1_Click() Dim x, y Picture1.Cls x = Val(Text1.Text) ‘将文本转换为数值型后赋值给变量x,y y = Val(Text2.Text) IF x < 90 And y < 60 Then Picture1.Print "血压偏低" ElseIF x <= 140 And y <= 90 Then Picture1.Print "血压正常" ElseIF x < 160 And y < 95 Then Picture1.Print "临界高血压" Else Picture1.Print "高血压" End IF End Sub Private Sub Command2_Click() End
例 已知百分制成绩mark,显示对应的五级制成绩 哪些正确,哪些错误? 返回72
Select Case 语句是多分支结构的又一种表示形式,又称情况语句。 语句形式: Select Case 变量或表达式 <语句块1> Case 表达式列表2 <语句块2> …… [Case Else <语句块n+1>] End Select F 表达式列表1 语句块1 表达式列表2 语句块2 表达式列表n 语句块n …. . 语句块n+1 T Select语句流程示意图 …. .
<表达式列表>:与<变量或表达式>同类型的下面四种形式之一: 表达式 例: case "A" 例4-7编写一个简便四则运算器,应用Select Case 判断运算符。运行界面如图 【程序代码】 Private Sub Command1_Click() Dim code As String code = Trim(Text2.Text) Select Case code Case "+" Text4 .Text= Val(Text1) + Val(Text3) Case "-" Text4.Text = Val(Text1) - Val(Text3) Case "*" Text4.Text = Val(Text1) * Val(Text3 Case "/" IF Val(Text3) = 0 Then MsgBox ("除数不能为0,请重新输入") Text3 = "“ Text4.Text = "" Text3.SetFocus Else Text4 = Val(Text1) / Val(Text3 End IF End Select End Sub Private Sub Command2_Click() End End Sub Private Sub Command3_Click() Text1 = "" Text2 = "" Text3 = "" Text4 = "" Text1.SetFocus <表达式列表>:与<变量或表达式>同类型的下面四种形式之一: 表达式 例: case "A" 一组枚举表达式(用逗号分隔) case 2,4,6,8 表达式1 To 表达式2 case 60 To 100 Is 关系运算符表达式 case Is < 60
5.IF 语句的嵌套 语句形式: IF <表达式1> Then 语句块1 IF <表达式2> Then 语句块2 … End IF 语句块3 … End IF
例4-6 输入3个整数,按从小到大的顺序输出。程序运行界面如图 程序代码如下: Private Sub Command1_Click() Dim x%, y%, z%, t% Form1.Cls x = Val(InputBox("请输入1个整数")) y = Val(InputBox("请输入1个整数")) z = Val(InputBox("请输入1个整数")) Print "您输入三个的数是:"; x; Spc(1); y; Spc(1); z IF x > y Then ‘如果x > y则x,y交换 t = x: x = y: y = t End IF IF y > z Then t = y: y = z: z = t IF x > y Then t = x: x = y: y = t Print "从小到大的顺序是:"; x; Spc(1); y; Spc(1); z End Sub Private Sub Command2_Click() End
例2-7在文本框中输入1-1000之间的数字,如果输入非数值,或数值超出范围,给予提示,并重新输入。运行效果及程序代码如下: Private Sub Form_Load() Text1.Text = "" Text2.Text = "" End Sub Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then '回车键的ASCII码值为13 If IsNumeric(Text1.Text) Then '判断是否是数值 x = Val(Text1.Text) If x < 0 Or x > 1000 Then Text1.SetFocus '焦点回到文本框 Text2.Text = "数值超出范围,再输入!" '文本框中显示提示信息 Else Text2.Text = "输入正确!" End If Text1.SetFocus Text2.Text = "请输入数字!"
4.2.3 条件函数 VB中提供的条件函数:IIF()函数和Choose()函数,适用于简单的判断场合。前者代替IF语句,后者可代替Select Case语句, IIF()函数 函数形式: IFF(表达式,条件为True时的值,条件为False时的值) 例如:求x,y中大的数,放入变量T中,可以应用语句 T=IFF( x>y , x ,y) Choose ()函数 Choose(整型表达式,选项列表) 其中整型表达式的值决定函数返回选项列表中的哪个值。如果整型表达式为1,则函数返回选项列表中的第一项的值,若整型表达式为2,则函数返回选项列表中的第2项的值,…依次类推。 如果整型表达式的值小于1或大于列出的选项数目时,函数返回Null。 如果整型表达式的值为非整型时,系统自动取其整数进行判断。 例如,根据x是1~4的值,转换成“内科”、“外科”、“妇科”、“儿科”的语句可以写成: kb=Choose(x,“内科”,“外科”,“妇科”,“儿科”)
4.3循环结构 4.3.1 For循环语句 For循环语句是计数型循环语句,用于控制循环次数预知的循环结构。 语句形式: For 循环变量=初值 To 终值 [ Step 步长 ] Next 循环变量 说明: 循环变量必须是数值型 步长:一般为正数,初值小于终值 ; 若为负数,初值大于终值; Step 缺省时默认为1。 语句块:重复执行的部分,构成循环体, 可以是一句或多句。 Exit For :退出循环,执行Next 后的下一条语句。 循环次数:n=Int( +1 ) T F 循环变量=初值 循环变量≤终值 语句块 有Exit For 循环变量=循环变量+步长 步长>0时For循环语句流程示意图 <语句块> [Exit For] 循环体 终值-初值 步长
例4-8求100以内所有数的和。 程序块如下: Sum =0 ‘sum 为累加和变量,设初值为0 For i= 1 To 100 Sum=Sum+i Next i 又如:求10的阶乘。 T=1 ‘T为连乘积的变量,设初值为1 For i=1 To 10 T=T*i 退出循环时,i的值是多少呢?
Do循环用于控制循环次数未知的循环结构。 语句形式: (1) Do [ {While | Until}<条件> ] 4.3.2Do…Loop循环语句 Do循环用于控制循环次数未知的循环结构。 语句形式: (1) Do [ {While | Until}<条件> ] <语句块> [Exit Do] Loop (2)Do <语句块> [Exit Do] Loop [ {While | Until}<条件> ] T F 表达式列表 语句块 有Exit Do Do While…Loop循环流程图 F T 表达式列表 语句块 Exit Do Do …Loop While流程示意图
例4-9利用Do While循环编写一个将十进制数转换成二进制数的程序。程序运行界面如图: 程序代码如下: Private Sub Command1_Click() Dim x$, n%,a%, n = InputBox("请输入1个整数") Print "十进制数为:"; n x = "" Do While n <> 0 a = n Mod 2 n = n \ 2 x = Chr(48 + a) & x Loop Print "二进制数为:"; x Print End Sub
例 我国有13亿人口,按人口年增长0.8%计算,多少年后我国人口超过26亿。 分析:解此问题两种方法,可根据公式:26=13*(1+0.008)n 直接利用标准对数函数求得;也可利用循环求得,程序如下: Private Sub Command1_Click() x = 13 n = 0 Do While x < 26 x = x * 1.008 n = n + 1 Loop Print n, x End Sub
4.3.3循环的嵌套 例4-10求100以内的素数 素数素数也成质数,就是大于2且只能被1和本身整除的整数。 我们从素数的定义来求解:从i=2,3,4,…,m-1依次判断m能否被i整除,只要有一个能整除m就不是素数,否则m为素数。运行结果如图 Private Sub Command1_Click() Dim i As Integer, m As Integer, Flag As Boolean, n As Integer Print "100以内的素数有" For m = 3 To 100 Flag = True For i = 2 To m - 1 IF (m Mod i) = 0 Then Flag = False Next i IF Flag = True Then n = n + 1 Print Spc(3 - Len(Str(m))); m; IF n Mod 10 = 0 Then Print End IF Next m End Sub
例4-11利用随机函数产生20个50~100范围内的随机数,显示最大值和最小值。运行界面如图 [程序代码] Private Sub Command1_Click() Dim maxa As Integer, mina As Integer, x As Integer, i As Integer Form1.Cls ‘每单击一次清除原来内容 maxa = 50 ‘假设较小的数为最大 mina = 100 ‘假设较大的数为最小 Randomize For i = 1 To 20 x = Int(Rnd * 51 + 50) Print x; IF i Mod 10 = 0 Then Print IF x > maxa Then maxa = x IF x < mina Then mina = x Next i Print Print "最大值为"; maxa Print "最小值为"; mina End Sub
一个循环体内又包含了一个完整的循环结构称为循环的嵌套. 例打印九九乘法表. For i = 1 To 9 For j = 1 To 9 se = i & "×" & j & "=" & i * j Picture1.Print Tab((j - 1) * 9 + 1); se; Next j Picture1.Print Next i For j = 1 To i 思考:打印上三角或下三角程序如何改动?要打印下三角?
For ii =1 To 10 For jj=1 To 20 … Next jj Next ii For ii =1 To 10 对于循环的嵌套,要注意以下事项: 内循环变量与外循环变量不能同名; 外循环必须完全包含内循环,不能交叉; 不能从循环体外转向循环体内,反之则可以。 正确 错误 For ii =1 To 10 For jj=1 To 20 … Next jj Next ii For ii =1 To 10 For jj=1 To 20 … Next ii Next jj For ii =1 To 10 … Next ii For ii =1 To 10 For ii=1 To 20 … Next ii
(1)内外循环变量同名错误: For i=1 To 10 For i =1 To 20 …. Next i 对于循环的嵌套,需要注意以下事项: 内循环变量与外循环变量不能同名。 外循环必须完全包含内循环,不能交叉。 以下程序段是错误的: (1)内外循环变量同名错误: For i=1 To 10 For i =1 To 20 …. Next i (2)内外循环交叉 For i = 1 To 10 For j=1 To 10 … Next i Next j
4.4 其他辅助控制语句 1. Go To 语句 形式: Go To {标号|行号} 作用:无条件地转移到标号或行号指定的那行语句. 4.4 其他辅助控制语句 1. Go To 语句 形式: Go To {标号|行号} 作用:无条件地转移到标号或行号指定的那行语句. 标号是一个字符序列,行号是一个数字序列. 2.Exit语句 多种形式: Exit For、Exit Do、Exit Sub、Exit Function等。 作用:退出某种控制结构的执行。 3. End语句 多种形式: End、 End If、 End Select、 End With、 End Type、 End Sub、 End Function、 作用:End结束一个程序的运行;其余表示某个结构的结束,与对应的结构语句配对出现。
4.5 常用算法(一) 算法是对某个问题求解过程的描述 1. 累加、连乘 4.5 常用算法(一) 算法是对某个问题求解过程的描述 1. 累加、连乘 1~100的5或7的倍数的和 Sum = 0 For i = 1 To 100 If i Mod 5 = 0 Or i Mod 7 = 0 Then Sum = Sum + i End If Next i Print Sum 3~10的乘积 t = 1 For i =3 To 10 t = t * i Next i Print t 思考:若把循环体前面置各变量初值的语句放在循环体内,程序运行时会产生什么情况?
2.穷举法 “穷举法”也称为“枚举法”或“试凑法”,即将可能出现的各种情况一一测试,判断是否满足条件,一般采用循环来实现。 例 百元买百鸡问题。假定小鸡每只5角,公鸡每只2元,母鸡每只3元。现在有100元钱要求买100只鸡,编程列出所有可能的购鸡方案。 设母鸡、公鸡、小鸡各为x、y、z只,根据题目要求,列出方程为: x+y+y=100 3x+2y+0.5z=100 三个未知数,两个方程,此题有若干个解。 解决此类问题采用“试凑法”,把每一种情况都考虑到。 方法一:最简单三个未知数利用三重循环来实现。 方法二:从三个未知数的关系,利用两重循环来实现。
For x=0 to 100 For y=0 to 100 For z=0 to 100 if (x+y+z=100 and _ 3*x+2*y+0.5*z=100) then Print x,y,z end if next z Next y next x For x=0 to 33 For y=0 to 50 if (3*x+2*y+0.5*(100-x-y)=100) then Print x,y,z end if Next y next x
3.递推法 “递推法”又称为“迭代法”,其基本思想是把一个复杂的计算过程转化为简单过程的多次重复。每次重复都从旧值的基础上递推出新值,并由新值代替旧值。 例 猴子吃桃子。小猴在某天摘桃若干个,当天吃掉一半多一个;第二天吃了剩下的桃子的一半多一个;以后每天都吃尚存桃子的一半多一个,到第7天要吃时只剩下一个,问小猴共摘下了多少个桃子? 分析:这是一个“递推”问题,先从最后一天推出倒数第二天的桃子,再从倒数第二天的桃子推出倒数第三天的桃子……。设第n天的桃子为xn,那么它是前一天的桃子数的xn-1 的一半减1,即xn =( xn-1 +1)×2
Private Sub Form_Click() Dim n%, i% x = 1 Print "第7天的桃子数为1只" For i = 6 To 1 Step -1 x = (x + 1) * 2 Print "第"; i; "天桃子的数为:"; x; "只" Next i End Sub
分析,该题利用“试凑法”通过二重循环求残料r的最小值正数,残料不可能是负数。程序如下: 例 实际应用,求最短残料。 有一根长度为321米的钢材料,要将它截取成两种规格a、b的长度分别为17米和27米的短料,每种至少1段,问分隔成a,b各多少段后,剩余的残料r最少? 分析,该题利用“试凑法”通过二重循环求残料r的最小值正数,残料不可能是负数。程序如下: Private Sub Command1_Click() Dim a%, b%, r!, ia%, ib% r = 321 ‘ 最小值初值取钢材料的长度 For b = 1 To 321 \ 27 ‘ b最多的段数 For a = 1 To 321 \ 17 - b ‘ a最多的段数 t = 321 - b * 27 - a * 17 ‘ 当前的残料 If t > 0 And t < r Then r = t ‘ 求最短的残料 ia = a ‘ 最短残料时a的段数 ib = b ‘ 最短残料时b的段数 End If Next a Next b Print ia, ib, r End Sub