第4章-程序控制结构_第1页
第4章-程序控制结构_第2页
第4章-程序控制结构_第3页
第4章-程序控制结构_第4页
第4章-程序控制结构_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第4章程序的控制结构在程序设计中,常常采用三种流程控制结构,分别是顺序结构,分支结构(又叫选择结构)和循环结构。流程控制结构是结构化程序设计的基本思想。一个复杂的问题一般可以转化为有限个顺序,分支或者循环结构来解决。顺序结构是使用最为广泛的控制结构,程序从上往下顺序执行,即使是分支结构和选择结构,其内部也往往采用顺序结构。另外各个模块之间也是从上向下顺序执行的。分支结构是指程序执行到某个地方之后有多个分支,程序需要根据某个条件来决定到底执行哪个分支的一种流程控制结构。正是因为有了分支结构,程序和用户之间的交互能力才得以大大增强。在Delphi中提供了两种分支结构的语句,分别是If语句和Case语句。如果在程序中需要重复执行某些语句和程序段。这时候往往使用循环结构来解决,循环结构可以避免我们重复书写相同的或者类似的程序代码,使得程序更加清晰明了,极大地简化了程序,提高了效率。在Delphi中提供了三种循环语句,分别是while语句、repeat语句和For语句。4.1分支结构分支结构通过判断条件表达式,再根据结果进行不同的操作。条件表达式一般是逻辑表达式或者关系表达式,类型为Boolean型,其值为true或者false。Boolean类型是顺序型,false的序号为0,true的序号为1。4.1.1if语句if语句是最常见的分支结构的语句,if语句是这样操作的,如果所给条件成立(值为true)则执行<语句序列1>,否则执行<语句序列2>,其流程图如图4-1所示。1.if语句的语法格式if语句的语法格式为:if<条件>then<语句序列1>[else<语句序列2>]说明:(1)条件是关系表达式或者逻辑表达式,程序是这样判断的,如果条件成立(值为true),则执行<语句序列1>,如果条件不成立(值为false)则执行<语句序列2>。(2)<语句序列1>和<语句序列2>都可以省略。(3)如果<语句序列1>或者<语句序列2>是几个语句,则用begin和end括起来形成复合语句的形式。(4)整个if语句看成一个语句,因此不能在if语句中间加分号。例如:ifa>bthenwriteln(a);//这个分号有错误,elsewriteln(b);再看下面:ifa>bthenbegint:=a;a:=b;b:=t;//可以加分号,和Begin、End形成复合语句

end//不可加分号,整个If…Then…Else是一个语句elsebeginwriteln(‘1111’);writeln(‘2222’);

end;2.if语句的应用【例4-1】求3个数的最大值。分析:可以使用if语句来编写程序,程序比较简单。程序如下:programProject1;{$APPTYPECONSOLE}usesSysUtils;varma,a,b,c:real;beginwrite('a,b,c=?');readln(a,b,c);ma:=a;//假设a最大ifb>mathenma:=b;//若b>ma,则最大为bifc>mathenma:=c;//若c>ma,则最大为cwriteln('最大数为',ma);readln;end.【例4-2】简单的密码程序。程序设计步骤:(1)添加组件GroupBox、Edit、Button和Panel到窗体,设置组件的属性:GroupBox1的Caption设置为“输入口令”,Edit1的Passwordchar设置为“*”,设置Button1的Caption为“确定[&E]”,界面如图4-2(a)和4-2(b)所示。(2)编写Button1的OnClick事件过程如下:procedureTForm1.Button1Click(Sender:TObject);beginifuppercase(edit1.Text)='ABCDEF'//口令是“abcdef”,不分大小写thenpanel1.Caption:='欢迎使用本系统'elsebeginedit1.Text:='';edit1.SetFocus;//清空文本框并置焦点panel1.Caption:='口令错误';end;end;另外我们希望输入口令后按回车键也可以判断口令是否正确,因此编写Eidt1的OnKeyPress事件过程如下:procedureTForm1.Edit1KeyPress(Sender:TObject;varKey:Char);beginifkey=#13then//如果按了回车键beginifuppercase(edit1.Text)='ABCDEF'thenpanel1.Caption:='欢迎使用本系统'elsebeginedit1.Text:='';edit1.SetFocus;panel1.Caption:='口令错误';end;end;end;下面的Edit1的OnChange事件过程用于清除Panel1中的内容:procedureTForm1.Edit1Change(Sender:TObject);beginpanel1.Caption:='';end;

(3)按F9键运行程序,运行程序的界面如图4-3(a)和4-3(b)所示。3.if语句的嵌套如果在if语句中还有if语句就称之为if语句的嵌套。有时候if语句的嵌套会产生歧义性。例如:ifyuwen>=60thenifyuwen>=85thenwriteln(‘优秀’)elsewriteln(‘不及格’);我们本希望else子句属于前面一个if语句,但是实际上本例中的else子句属于后面一个if语句。Delphi规定:else子句总是属于与它最靠近的那个没有else子句的if…then语句。虽然如此,但是用户还是比较容易理解错误。因此,建议把上面的这个嵌套if语句写成如下形式:ifyuwen>=60thenifyuwen>=85thenwriteln(‘优秀’)elseelsewriteln(‘不及格’);或者:ifyuwen>=60thenbeginifyuwen>=85thenwriteln(‘优秀’)end elsewriteln(‘不及格’);这样就不容易理解错误了,另外建议书写程序的时候将程序行适当缩进,这样也可以避免对程序的错误理解。【例4-3】修改上面的密码程序,允许用户3次出错,如果第3次密码仍然错误,则结束程序。请使用嵌套的if语句完成。只需要简单Button1的OnClick事件过程即可:procedureTForm1.Button1Click(Sender:TObject);beginifuppercase(edit1.Text)='ABCDEF'thenpanel1.Caption:='欢迎使用本系统'elsebeginedit1.Tag:=edit1.Tag+1;//无需重新定义变量ifedit1.Tag=3then

beginmessagedlg('3次密码错误,您无权使用本程序',mterror,[mbok],1);//显示错误信息application.Terminate;//程序停止

end;edit1.Text:='';//此处无需加Elseedit1.SetFocus;panel1.Caption:='口令错误';end;end;别忘了将Edit1的OnKeyPress事件过程也做类似修改。此处省略。4.1.2case语句if语句可以解决两路分支问题,而case语句可以解决多路分支问题,即从多个语句序列中选择一路语句序列执行。1.case语句的语法格式case语句的语法格式为:case<表达式>of[常量表1:[语句序列1;]][常量表2:[语句序列2;]][常量表3:[语句序列3;]]…… [常量表n:[语句序列1;]][else[语句序列n+1;]]end;说明:(1)表达式必须是顺序类型,如整型、字符型、枚举、子界、布尔型等。(2)各个常量表中的常量应该用逗号隔开,各个常量表中的常量不能够相同。(3)如果语句序列是多个语句可以使用begin和end括起来形成复合语句。(4)如果表达式的值与某个常量表中的某个常量值相等则程序就执行该语句序列,执行完毕,程序转到case语句之外执行其他余句;如果表达式的值与所有常量表中的常量的值都不相等,则程序执行else之后的语句序列n+1(如果有else部分的话)。case语句的流程图如图4-4所示。2.case语句的应用【例4-4】计算每个月的天数。分析:根据常识1、3、5、7、8、10和12月每个月有31天,而4、6、9和11月每个月有30天,2月份闰年有29天,平年有28天。符合下列情况之一就是闰年:I)年号能被400整除;II)年号能被4整除但是不能够被100整除。建立ConsoleApplication应用程序如下:programCadays;{$APPTYPECONSOLE}usesSysUtils;varyear,month,days:integer;beginwrite('year,month=?');readln(year,month);casemonthof1,3,5,7,8,10,12:days:=31;4,6,9,11:days:=30;2:if(yearmod400=0)or(yearmod100<>0)and(yearmod4=0)thendays:=29elsedays:=28;elsewriteln('Inputyearerror!');end;writeln(year:4,'年',month:1,'月有',days:2,'天。');readln;4.2循环结构Delphi提供了三种循环结构的语句,分别是While语句、Repeat语句和For语句,这三种语句分别在不同的环境条件下使用,一般情况下,它们是可以互相替代的。三种循环语句各有各的特色,其中While语句和Repeat语句用于循环次数未知的情况下,根据循环条件来控制循环次数,For语句用于循环次数已知的循环。在实际应用中用户可以选择合适的循环语句,对于有的问题,三种循环都可以实现。4.2.1while语句while语句属于前测型循环语句。首先判断条件,根据条件来决定是否循环,如果条件成立则循环,否则不循环,也有可能一次也不循环。其流程图如图4-5(a)和图4-5(b)所示。1.while语句的语法格式while语句的语法格式为:while<条件>do[循环体];说明:(1)条件是这样判断的,如果条件成立(值为true),则执行循环体,如果条件不成立(值为false),则结束循环,执行循环体之后的语句。(2)循环体可以是若干个语句,如果是一个以上的语句,可以使用begin和end括起来,形成复合语句的形式。(3)可以在循环体中添加continue语句,用if语句来控制continue,程序执行continue用于结束本次循环执行下一次循环。(4)还可以在循环体中添加break语句,用if语句来控制break,程序执行break用于结束整个循环,执行循环体之后的语句,程序结束循环之前无需判断循环条件。2.while循环的应用【例4-5】求s=1+2+3+…+100的值。分析:可以使用变量n来作为加数,n的值从1一直计数到100变化,每一次将n的值加到s中,n都要自加1,s用来保存1+2+3+…+100的和,s的初始值赋值为0。根据分析流程图如图4-6所示。程序设计步骤(1)添加组件到窗体,设置组件的属性,界面如图4-7所示。(2)编写Button1的OnClick时间过程。procedureTForm1.Button1Click(Sender:TObject);

vars,n:integer;begins:=0;n:=1;whilen<=100dobegins:=s+n;n:=n+1;end;panel1.Caption:='s=1+2+3+...+100='+inttostr(s);end;(3)按F9键运行程序,运行程序界面如图4-8所示。4.2.2repeat语句repeat语句一般用于循环次数不确定的循环。首先执行循环语句,然后再来判断循环条件来决定是否继续执行循环,因此repeat语句至少要执行一次循环语句。repeat语句的流程图如图4-9(a)和图4-9(b)所示。1.repeat语句的语法格式repeat语句的语法格式为:repeat循环体;until<条件>;说明:(1)repeat循环是后侧型循环,首先执行循环体,再判断循环条件。(2)语句体可以是若干个语句,多条语句无需用begin和end括起来,用自身的repeat和until将其括起来。(3)循环条件是这样判断的:如果条件为真则结束循环,转而执行循环体之后语句,如果循环条件为假则继续循环。一般循环条件在执行的过程中是会改变的。(4)可以在循环体中加入continue语句,一般用if来控制continue,continue语句可以让程序提前结束本次循环(无需判断循环条件),转而去执行下一次循环。(5)还可以在循环体中加入break语句,一般使用if语句来控制break,break语句可以让程序结束整个循环(无需判断循环条件),转而去执行循环体之后的语句。2.repeat循环的应用【例4-6】求π的值,利用公式π/4≈1-1/3+1/5-1/7+…求近似值。直到最后一项的绝对值小于0.0001为止。分析:先计算出右边多项的和,然后再乘以4即为所求的近似π的值。令右边各项之和的值为pi,右边每一项的分母分别为奇数1、3、5…,符号是一正一负的。可以使用n作为计数器,控制分母,fh用来控制正负,则每一项的值为fh/n,使用循环将每一项加到pi中就可以得到右边各项之和。最后乘以4即可得到近似π的值。根据分析绘制出流程图如图4-10所示。程序设计步骤(1)添加组件到窗体,设置组件的属性,界面如图4-11所示。(2)编写Button1的OnClick事件过程,如下:procedureTForm1.Button1Click(Sender:TObject);varfh,pi,n:real;beginpi:=0;n:=1;fh:=1.0;repeatpi:=pi+fh/n;n:=n+2;//分母为奇数fh:=-fh;//每项的符号是变化的until1/n<=0.0001;pi:=4*pi;panel1.Caption:='π='+floattostr(pi)end;(3)按F9键运行程序,运行程序界面如图4-12所示。procedureTForm1.Edit1KeyPress(Sender:TObject;varKey:Char);

varpn,fn:real;beginifkey=#13then//输入误差后按回车键beginpn:=sqrt(2);fn:=2/pn;//第一项的分母和第一项repeatpn:=sqrt(pn+2);//第n项的分母fn:=fn*2/pn;//n项乘积,再乘以2就是π的近似值untilabs(2*(fn*2/pn)-2*fn)<=strtofloat(edit1.Text);//相邻的两个近似π分别为2*(fn*2/pn)和2*fnpanel1.Caption:='π='+floattostr(2*fn);end;end;(3)按F9键运行程序,运行程序界面如图4-15所示。4.2.3for语句在循环次数不确定的时候,使用while循环或者repeat循环比较好,如果循环次数确定,最好使用for循环。与前两个循环不同的是for循环有一个循环变量用于控制循环次数,每循环一次循环变量就会自动增加或者减少。for语句的流程图如图4-16(a)和图4-16(b)所示。1.for语句的格式for语句的格式为:for<循环变量>:=<初值>{to|downto}<终值>do[循环体];说明:(1)<循环变量>为必要参数,它必须是顺序类型,用作循环次数的计数器,并且在循环体中不允许人为地改变循环变量的值。(2)<初值>和<终值>是循环变量的初始取值和终值,它可以是变量或者表达式,但是类型必须和循环变量保持一致。如果循环变量是表达式,则在进入循环的时候,表达式的值应该是确定的。(3)To表示循环计数器递增,downto表示循环变量计数器递减。(4)<循环体>可以是一个语句或者多个语句,如果是多个语句可以使用begin和end。(5)for循环语句是这样执行的:首先将循环变量的初始值赋值给循环变量,然后判断循环变量是否“越过”循环变量的终值(对于to类型“越过”表示大于,对于downto类型,“越过”表示小于),如果已经“越过”循环变量的终值,则循环结束,程序执行循环结构之后的语句;如果没有“越过”循环变量的终值,则执行循环语句,然后循环变量自动递增(to类型)或者递减(downto类型)。(6)如果在循环中有break语句,不论循环条件是否满足,都可以提前结束循环,可以使用If语句来控制break语句。(7)可以在循环中加入continue语句,continue语句的作用是结束本次循环进入下次循环。可以使用if来控制continue语句。(8)break语句和continue语句可以使得for循环结构更加巧妙。2.for循环语句的应用【例4-8】求s=1+2+4+5+7+8+10+11+…,当s的值刚好大于1000时的S的值。分析:本程序是求s=1+2+4+5+7+8+10+11+…当s的值刚好大于1000时的s的值,由于不知道循环多少次时s的值刚好大于1000,因此可以把循环次数设计为1000次,然后在循环的过程中根据条件中途退出循环,中途退出循环的条件是s>1000。另外本程序求和的时候没有包括3的倍数,所有3的倍数都排除在外,因此如果在加的过程中如果判断加数是3的倍数则结束本次循环,进入下一次循环。流程图如图4-17所示。程序设计步骤如下:(1)界面设置,属性设置。界面如图4-18所示。(2)编写Button1的OnClick事件过程。procedureTForm1.Button1Click(Sender:TObject);vars,i:integer;begins:=0;fori:=1to1000dobeginifimod3=0thencontinue;s:=s+i;ifs>1000thenbreak;end;panel1.Caption:='1+2+4+5...+';panel1.Caption:=panel1.Caption+inttostr(i)+'='+inttostr(s);end;(3)按F9键运行程序,运行程序界面如图4-19所示。4.2.4多重循环如果在循环中还有循环,就构成多重循环结构。常用的多重循环有二重循环和三重循环。可以使用相同的循环语句或者不同的循环语句来现实多重循环。【例4-9】求100以内的素数。分析:判断n是否为素数可以这样进行,先假设n是素数,设一个标志flag的值为True;然后在2到之间寻找n的因子,只要能够找到n的因子(一个足够),就令flag的值为False;如果经过2到的循环flag的值仍然是True,说明n是素数,否则n不是素数;如果n是素数,则输出这个n。由于1不是素数,让n从2到100循环,执行上面的操作,即可输出100以内所有的素数。本程序的循环次数已知,因此两个循环都用For语句来实现。根据以上分析,不难画出本程序的流程图,如图4-20所示。程序设计步骤如下:(1)添加组件,属性设置省略,界面如图4-21所示。(2)编写Button1的OnClick事件过程。procedureTForm1.Button1Click(Sender:TObject);

varn,i:integer;flag:boolean;beginforn:=2to100do

beginflag:=true;//假设n是素数fori:=2totrunc(sqrt(n))do//在2到trunc(sqrt(n))之间寻找n的因子//循环变量的初值和终值为整型,因此要取整ifnmodi=0thenflag:=false;//i是n的因子,因此n不是素数,故修改flag为falseifflagthenlistbox1.Items.Add(inttostr(n));//输出素数nend;end;(3)按F9键运行,运行界面如图4-22所示。【例4-10】验证歌德巴赫猜想,歌德巴赫认为一个非常大的偶数可以分解成为两个素数之和的形式。本程序要求输入一个较大的偶数n,将这个偶数n分解成为两个素数p和q相加的形式,例如,输入10,输出10=3+7和10=5+5。试编写程序。分析:一个数n可以分解成p+q的形式:p从2到n/2循环,而q始终取值为n-p;现在只要满足p和q都是素数即可,如果p和q都是素数就输出p和q。判断p和q是否是素数,可以使用for循环,外加p从2到n/2的循环,这样使用二重循环即可解答本题。根据分析画出流程图如图4-23所示。(2)编写Button1的OnClick事件过程。procedureTForm1.Button1Click(Sender:TObject);

varn,p,q,i:integer;flagp,flagq:boolean;s:string;beginlistbox1.Items.Clear;n:=strtoint(inputbox('输入一个正整数n','输入n',''));p:=1;repeatp:=p+1;q:=n-p;flagp:=true;//假设p是素数fori:=2totrunc(sqrt(p))doifpmodi=0thenflagp:=false;//p不是素数flagq:=true;//假设q是素数fori:=2totrunc(sqrt(q))doifqmodi=0thenflagq:=false;//q不是素数ifflagpandflagqthen

begins:=inttostr(n)+'='+inttostr(p)+'+'+inttostr(q);listbox1.Items.Add(s);

end;//输出untilp>=n/2;end;(3)按F9键运行程序,运行程序界面如图4-25所示。在设计循环类程序时,一定要思路清晰,最好画出流程图,对于多重循环,应该注意以下几个问题:(1)内外循环只能嵌套,不能交叉;(2)不同层的循环,不要使用相同的循环变量,并列的循环除外;(3)注意程序的缩进格式,这样可以减少循环程序出错的概率。4.3小结本章讲述了程序的控制结构,包括顺序结构、分支结构和循环结构。本章的各个控制结构都安排有典型的例题,通过这些例题,读者应该掌握这三种基本控制结构的用法,并能够在程序中灵活运用。读者要注意iF语句和case语句的区别和适用场合;注意三种循环语句的特点和优点,在何种情况下适合使用哪种循环,这些读者都应该熟知,并灵活掌握和使用。多重循环是难点,读者要注意其中一些注意事项。习题1.有下面一段代码:a:=6;b:=20;ifa>5then

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论