《]第5章 循环结构.ppt》由会员分享,可在线阅读,更多相关《]第5章 循环结构.ppt(57页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、5.1 工作场景导入 5.x goto语句以及用goto语句构成循环5.2while语句5.3 do while语句5.4 for 语句5.x循环的嵌套5.x几种循环的比较5.5 break语句和continue语句5.6.7 回到工作场景/实训营第第5 5章章 循环结构循环结构5.05.0计算机大部分功能都涉及循环计算机大部分功能都涉及循环在许多问题中需要用到循环控制在许多问题中需要用到循环控制。例如。例如,要输入全校学生成,要输入全校学生成绩;求若干个数之和;迭代求根等。几乎所有实用的程序绩;求若干个数之和;迭代求根等。几乎所有实用的程序都包含循环。循环结构是结构化程序设计的基本结构之一,
2、都包含循环。循环结构是结构化程序设计的基本结构之一,它和顺序结构、选择结构共同作为各种复杂程序的基本构它和顺序结构、选择结构共同作为各种复杂程序的基本构造单元造单元。什么叫循环?(从前有座山。什么叫循环?(从前有座山ATM取钱等)取钱等)因此熟练掌握选择结构和循环结构的概念及使用是程序设计因此熟练掌握选择结构和循环结构的概念及使用是程序设计的最基本的要求。的最基本的要求。(1)用用goto语句和语句和if语句构成循环;语句构成循环;(2)用用while语句;语句;(3)用用do|while语句;语句;(4)用用for语句。语句。在下面各节中将分别作介绍。在下面各节中将分别作介绍。5.1 5.1
3、 工作场景导入工作场景导入北京某毕业生需要贷款100万买房,贷款的银行年利率为7%,由于此同学工资水平有限,希望尽量拖延还款的结束日期,但其认为还款总额不可超过150万。此外,银行规定还款期限不应超过30年。试为此人编程求出满足他要求的最大还款期限。1)如何通过循环结构来解决此问题2)运用何种循环结构来具体描述此场景3)循环结构(while、do-while或者for)具体如何使用。5.x 5.x gotogoto语句以及用语句以及用gotogoto语句语句构成循环构成循环goto语句为语句为无条件转向语句无条件转向语句,它的一般形式为,它的一般形式为 goto 语句语句标号;标号;语句标号用
4、标识符表示,它的定名规则与变量名相语句标号用标识符表示,它的定名规则与变量名相同,即由字母、数字和下划线组成,其第一个字同,即由字母、数字和下划线组成,其第一个字符必须为字母或下划线。不能用整数来做标号。符必须为字母或下划线。不能用整数来做标号。例如:例如:goto label_1;是合法的,而是合法的,而goto 123;是不合法的是不合法的。5.X goto5.X goto语句以及循环语句以及循环结构化程序设计方法主张结构化程序设计方法主张限制使用限制使用goto语句语句,因为,因为滥用滥用goto语句将使程序流程无规律、可读性语句将使程序流程无规律、可读性差。但差。但也不是绝对禁止使用也
5、不是绝对禁止使用goto语句。一般来说,可以有语句。一般来说,可以有两种用途:两种用途:(1)与与if语句一起构成循环结构;语句一起构成循环结构;(2)从循环体中跳转到循环体外,但在从循环体中跳转到循环体外,但在c语言中可以语言中可以用用break语句和语句和continue语句语句(见见6.8节节)跳出本层循环跳出本层循环和结束本次循环。和结束本次循环。goto语句的使用机会已大大减少,语句的使用机会已大大减少,只是需要只是需要从多层循环的内层循环跳到外层循环外从多层循环的内层循环跳到外层循环外时才用到时才用到goto语句。语句。但是这种用法不符合结构化原但是这种用法不符合结构化原则,一般不
6、宜采用,只有在不得已时则,一般不宜采用,只有在不得已时(例如能大大例如能大大提高效率提高效率)才使用。才使用。举个栗子举个栗子例5.1用if语句和goto语句构成循环,求n。此问题的算法是比较简单的,可以直接写出程序:main()int i,sum=0;i=1;loop:if(i=100)sum=sum+i;i+;goto loop;printf(%d,sum);运行结果如下:5050这里用的是“当型”循环结构,当满足“i=100”时执行花括弧内的循环体。请想象一下如何绘制流程图。Ill be there in 5 minutes.If not,read this again.我5分钟后到,如
7、果没到,请再读一遍此短信5.25.2whilewhile语句语句while语句用来实现“当型”循环结构。其一般形式如下:while(表达式)语句当表达式为非0值时,执行while语句中的内嵌语句。其流程图见图5.1。其特点是:先判断表达式,后执行语句。图图5 5.1例5.2求n。用传统流程图和NS结构流程图表示算法,见图5.2(a)和图5.2(b)。根据流程图写出程序:main()int i,sum=0;i=1;while(i100”,因此在循环体中应该有使i增值以最终导致i100的语句,今用“i+;”语句来达到此目的。如果无此语句,则i值始终不改变,循环永不结束。5.3 do while 5
8、.3 do while 语句语句do while语句的特点是先执行循环体,然后判断循环条件是否成立。其一般形式为 do 循环体语句while(表达式);它是这样执行的:先执行一次指定的循环体语句,然后判别表达式,当表达式的值为非零(“真”)时,返回重新执行循环体语句,如此反复,直到表达式的值等于0为止,此时循环结束。可以用图5.3表示其流程。请注意do while循环用N-S流程图的表示形式(图5.3(b)。图5.3例5.3用dowhile语句求n。先画出流程图,见图5.4。图图5.45.4图图5.55.5程序如下:main()int i,sum=0;i=1;do sum=sum+i;i+;w
9、hile(i=100);printf(%d,sum);可以看到:对同一个问题可以用while语句处理,也可以用do-while语句处理。Do-while语句结构可以转换成while结构。图5.3可以改画成图5.5形式,二者完全等价。而图5.5中线框部分就是一个while结构。可见,do-while结构是由一个语句加一个while结构构成的。若图6.1中表达式值为真,则图5.1也与图5.5等价(因为都要先执行一次语句)。在一般情况下,用while语句和用do-while语句处理同一问题时,若二者的循环体部分是一样的,它们的结果也一样。如例5.2和例5.3程序中的循环体是相同的,得到结果也相同。但
10、是如果while后面的表达式一开始就为假(0值)时,两种循环的结果是不同的。例5.4while和do-while循环的比较。(1)main()(2)main()int sum=0,i;int sum=0,i;scanf(“%d”,&i);scanf(%d,&i);while(i=10)do sum=sum+i;sum=sum+i;i+;i+;while(i10时,二者结果就不同了。这是因为此时对while循环来说,一次也不执行循环体(表达式“i100”。因为“当i100时继续执行循环”和“直到i100结束循环”是对同一问题的两种表述方式。千万不要在图5.4(b)中写成“直到i100”。某互联网
11、公司的自动售货机上写着只收5元和10元的纸币,一日被一个同事发现竟然还可以识别1元的纸币,不过每次交易只能识别一张。他冷静的说:”这个机器,5块10块肯定是用while-do写的,1块的是用do-while写的。自举了这个栗子之后,老师就亲身经历在赤岗塔买票,无良的自动售票机不认1元钱硬币啊5 5.4 for.4 for语句语句C语言中的for语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替while语句。for语句的一般形式为:for(表达式1;表达式2;表达式3)语句 它的执行过程如下:(1)先求解表达式1。(2)求
12、解表达式2,若其值为真(值为非0),则执行for语句中指定的内嵌语句,然后执行下面第(3)步。若为假(值为0),则结束循环,转到第(5)步。for(表达式1;表达式2;表达式3)语句(3)求解表达式3。(4)转回上面第(2)步骤继续执行。(5)循环结束,执行for语句下面的一个语句。可以用图5.6来表示for语句的执行过程。图图5.6for语句最简单的应用形式也就是最易理解的如下形式:for(循环变量赋初值;循环条件;循环变量增值)语句 例如:for(i=1;i=100;i+)sum=sum+i;它的执行过程与图5.2完全一样。可以看到它相当于以下语句:i=1;while(i=100)sum=
13、sum+i;i+;显然,用for语句简单、方便。对于以上for语句的一般形式也可以改写为while循环的形式:(考点)表达式1;while(表达式2)语句 表达式3;说明:(1)for语句的一般形式中的“表达式1”可以省略,此时应在for语句之前给循环变量赋初值。注意省略表达式1时,其后的分号不能省略。如for(;i=100;i+)sum=sum+i;执行时,跳过“求解表达式1”这一步,其他不变。图图5.75.7(2)如果表达式2省略,即不判断循环条件,循环无终止地进行下去。也就是认为表达式2始终为真。见图5.7。例如:for(i=1;i+)sum=sum+i;表达式1是一个赋值表达式,表达式
14、2空缺。它相当于:i=1;while(1)sum=sum+1;i+;(3)表达式3也可以省略,但此时程序设计者应另外设法保证循环能正常结束。例如for(i=1;i=100;)sum=sum+i;i+;(4)可以省略表达式1和表达式3,只有表达式2,即只给循环条件,如:for(;i=100;)while(i=100)sum=sum+i;相当于 sum=sum+i;i+;i+;在这种情况下,完全等同于while语句。可见for语句比while语句功能强,除了可以给出循环条件外,还可以赋初值,使循环变量自动增值等。(5)三个表达式都可省略,如:for(;)语句相当于while(1)语句。即不设初值,
15、不判断条件(认为表达式2为真值),循环变量不增值。无终止地执行循环体。(6)表达式1可以是设置循环变量初值的赋值表达式,也可以是与循环变量无关的其他表达式。如:for(sum=0;i=100;i+)sum=sum+i;表达式3也可以是与循环控制无关的任意表达式。表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式,即包含一个以上的简单表达式,中间用逗号间隔。如:for(sum=0,i=1;i=100;i+)sum=sum+i;或for(i=0,j=100;i=j;i+,j-)k+=i*j;(6)表达式1和表达式3都是逗号表达式,各包含两个赋值表达式,即同时设两个初值,使两个变量增值,执
16、行情况见图5.8。在逗号表达式内按自左至右顺序求解,整个逗号表达式的值为其中最右边的表达式的值。如:for(i=1;i=100;i+,i+)sum=sum+i;相当于for(i=1;i=100;i=i+2)sum=sum+i;图图5.9图图5.8(7)表达式一般是关系表达式(如i=100)或逻辑表达式(如ab&xy),但也可以是数值表达式或字符表达式,只要其值为非零,就执行循环体。分析下面两个例子:for(i=0;(c=getchar()!=n;i+=c);在表达式2中先从终端接收一个字符赋给c,然后判断此赋值表达式的值是否不等于n(换行符),如果不等于n,就执行循环体。此for语句的执行过程
17、见图6.9,它的作用是不断输入字符,将它们的ascII码相加,直到输入一个“换行”符为止。注意:此for语句的循环体为空语句,把本来要在循环体内处理的内容放在表达式3中,作用是一样的。可见for语句功能强,可以在表达式中完成本来应在循环体内完成的操作。for(;(c=getchar()!=n;)printf(%c,c);只有表达式2,而无表达式1和表达式3。其作用是每读入一个字符后立即输出该字符,直到输入一个“换行”为止。请注意,从终端键盘向计算机输入时,是在按Enter键以后才送到内存缓冲区中去的。运行情况:computer(输入)computer (输出)而不是ccoommppuuttee
18、rr即不是从终端敲入一个字符马上输出一个字符,而是按Enter键后数据送入内存缓冲区,然后每次从缓冲区读一个字符,再输出该字符。从上面介绍可以知道c语言中的for语句比其他语言(如basic,Pascal)中的for语句功能强得多。可以把循环体和一些与循环控制无关的操作也作为表达式1或表达式3出现,这样程序可以短小简洁。但过分地利用这一特点会使for语句显得杂乱,可读性降低,建议不要把与循环控制无关的内容放到for语句中。5.X 5.X 循环的嵌套循环的嵌套一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多层循环。各种语言中关于循环的嵌套的概念都是一样
19、的。三种循环(while循环、dowhile循环和for循环)可以互相嵌套。例如,下面几种都是合法的形式:(1)while()while()(2)dodo while();while();(3)for(;)for(;)(4)while()dowhile();(5)for(;)while()(6)dofor(;)while();5.X 5.X 几种循环的比较(考点)几种循环的比较(考点)(1)四种循环都可以用来处理同一问题,一般情况下它们可以互相代替。但一般不提倡用goto型循环。(2)while和do-while循环,只在while后面指定循环条件,在循环体中应包含使循环趋于结束的语句(如i+
20、,或i=i+1等)。for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式3中。因此for语句的功能更强,凡用while循环能完成的,用for循环都能实现。(3)用while和do-while循环时,循环变量初始化的操作应在while和do-while语句之前完成。而for语句可以在表达式1中实现循环变量的初始化。(4)while循型、do-while循环和for循环,可以用break语句跳出循环,用continue语句结束本次循环(break语句和continue语句见6.8节)。而对用goto语句和if语句构成的循环,不能用break语句和continu
21、e语句进行控制。5.5 break5.5 break语句和语句和continuecontinue语句语句break语句:在前面已经介绍过用break语句可以使流程跳出Switch结构,继续执行Switch语句下面的一个语句。实际上,break语句还可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句。如:for(r=1;r100)break;printf(%f,area);计算r=1到r=10时的圆面积,直到面积area大于100为止。从上面的for循环可以看到:当area100时,执行break语句,提前结束循环,即不再继续执行其余的几次循环。break语句的一般形式为:br
22、eak;break语句不能用于循环语句和Switch语句之外的任何其他语句中。ContinueContinue语句语句一般形式为:continue;其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。continue语句和break语句的区别是(考点):continue语句只结束本次循环,而不是终止整个循环的执行。而break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。如果有以下两个循环结构:(2)while(表达式1)if(表达式2)continue;(1)while(表达式1)if(表达式2)break;图图5 5.11图图5 5.10
23、程序(1)的流程图如图5.10所示,而程序(2)的流程如图5.11所示。请注意图5.10和图5.11中当“表达式2”为真时流程的转向。main()int n;for(n=100;n=200;n+)if(n%3=0)continue;printf(%d,n);例5.5把100200之间的不能被3整除的数输出。程序解析:程序解析:当n能被3整除时,执行continue语句,结束本次循环(即跳过printf函数语句),只有n不能被3整除时才执行printf函数。当然,例5.5中循环体也可以改用一个语句处理:if(n%3!=0)printf(%d,n);我们在程序中用continue语句无非为了说明c
24、ontinue语句的作用。简单的说,如果我们班有同学上课需要上厕所,上完厕所他又回来了,那么他就使用了continue语句反之,如果他趁着这个机会逃课了,就是break语句5.6.7 5.6.7 程序举例与实操程序举例与实操例5.6用/41-1/3+1/5-1/7+公式求的近似值,直到最后一项的绝对值小于10-6为止。用N|S结构化流程图表示算法(见图6.12)。图图5.125.12程序程序#includemain()int s;float n,t,Pi;t=1;Pi=0;n=1.0;S=1;while(fabs(t)1e-6)Pi=Pi+t;n=n+2;s=-s;t=S/n;Pi=Pi*4;
25、printf(Pi=%10.6fn,Pi);运行结果为:Pi=3.141594古典数学问题:有一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假设所有兔子都不死,问每个月的兔子总数为多少?(百度:斐波那契数列)例5.7求fibonacci数列40个数。这个数列有如下特点:第1,2两个数为1,1。从第3个数开始,该数是其前面两个数之和。即:f1=1(n=1)f2=1 (n=2)fn=fn-1+fn-2 (n3)解此题的算法如上图所示。main()long int f1,f2;int i;f1=1;f2=1;for(i=1;i=20;i+)printf(%1
26、2ld%12ld,f1,f2);if(i%2=0)printf(n);f1=f1+f2;f2=f2+f1;运行结果为:1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 57022887 9227465 14930352 24157817 39088169 63245986 102334155程序中在printf函数中输出格式符用“%12
27、 ld”,而不是用“%12d”,这是由于在第23个数之后,整数值已超过整数最大值32767,因此必须用“%ld”格式输出。if语句的作用是使输出4个数后换行。i是循环变量,当i为偶数时换行,而i每增值1,就要计算和输出2个数(f1,f2),因此i每隔2换一次行相当于每输出4个数后换行输出。例例5.8判断判断m是否素数。算法如是否素数。算法如图图5.14所示。所示。我们采用的算法是这样的:让m被2到m 除,如果m能被2m 之中任何一个整数整除,则提前结束循环,此时i必然小于或等于k(即m);如果m不能被2k(即m)之间的任一整数整除,则在完成最后一次循环后,i还要加1,因此i=k+1,然后才终止
28、循环。在循环之后判别i的值是否大于或等于k+1,若是,则表明未曾被2k之间任一整数整除过,因此输出“是素数”。求素数求素数图5.14程序如下:#include main()int m,i,k;scanf(%d,&m);k=sqrt(m+1);/*加1是为了避免在求m时可能出现的误差*/for(i=2;i=k+1)printf(%d is a Prime mubern,m);else printf(%d is not a Prime numbern,m);运行情况如下:1717 is a Prime number例例5.95.9求求100100200200间间的素数。的素数。在例5.8的基础上,
29、对本题用一个嵌套的for循环即可处理。程序如下:#include main()int m,k,i,n=0;for(m=101;m=200;m=m+2)k=sqrt(m);for(i=2;i=k+1)printf(%d ,m);n=n+1;if(n%10=0)printf(n);printf(n);运行结果如下:101 103 107 109 113 127 131 137 139 149151 157 163 167 173 179 181 191 193 197199 n的作用是累计输出素数的个数,控制每行输出10个数据。例5.10译密码。为使电文保密,往往按一定规律将其转换成密码,收报人再
30、按约定的规律将其译回原文。例如,可以按以下规律将电文变成密码:将字母a变成字母E,a变成e,即变成其后的第4个字母,W变成a,X变成b,Y变成c,Z变成D。见图6.15。字母按上述规律转换,非字母字符不变。如“china!”转换为“Glmre!”。输入一行字符,要求输出其相应的密码。图5.15程序如下:#include main()char c;while(c=getchar()!=n)if(c=a&c=a&cZ&cz)c=c-26;printf(%c,c);运行结果如下:china!Glmre!程序中对输入的字符处理办法是:先判定它是否大写字母或小写字母,若是,则将其值加4(变成其后的第4个
31、字母)。如果加4以后字符值大于Z或z,则表示原来的字母在V(或v)之后,应按图6.15所示的规律将它转换为aD(或ad)之一。办法是使c减26,如果对此还有疑问,请查ascII码表即可清楚。还有一点请读者注意:内嵌的if语句不能写成if(cZ|cz)c=c-26;因为当字母为小写时都满足“cZ”条件,从而也执行“c=c-26;”语句,这就会出错。因此必须限制其范围为“cZ&cz&cz”即可。6.10习题6.1 输入两个正整数m和n,求其最大公约数和最小公倍数。6.2 输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。6.3 求Sn=a+aa+aaa+aaa n个a之值,其中a是
32、一个数字。例如:2+22+222+2222+22222(此时n=5),n由键盘输入。6.4 求 (即求1!+2!+3!+4!+20!)。6.5 打印出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。例如,153是一水仙花数,因为153=13+53+33。6.6 一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如,6的因子为1、2、3,而6=1+2+3,因此6是“完数”。编程序找出1000之内的所有完数,并按下面格式输出其因子:6itS factorS are 1,2,36.7 有一分数序列2/1,3/2,5/3,8/5,13/8,21/13,求出这个数列的前20项之和。6.8 猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,就只剩一个桃子了。求第一天共摘多少桃子。6.9 用迭代法求 。求平方根的迭代公式为要求前后两次求出的x的差的绝对值小于10-5。本节本节课就到这里,谢谢大家课就到这里,谢谢大家