收藏 分享(赏)

第五章 循环控制.ppt

上传人:hskm5268 文档编号:5828229 上传时间:2019-03-18 格式:PPT 页数:70 大小:2.65MB
下载 相关 举报
第五章 循环控制.ppt_第1页
第1页 / 共70页
第五章 循环控制.ppt_第2页
第2页 / 共70页
第五章 循环控制.ppt_第3页
第3页 / 共70页
第五章 循环控制.ppt_第4页
第4页 / 共70页
第五章 循环控制.ppt_第5页
第5页 / 共70页
点击查看更多>>
资源描述

1、第五章 循环控制,循环控制,学习的意义,第3章讨论,第4章讨论,本章讨论,许多实际问题中往往需要有规律地重复某些操作,如菜谱中可以有:“打鸡蛋直到泡沫状”这样的步骤,也就是说,在鸡蛋没有打成泡沫状时要反复地打。相应的操作在计算机程序中就体现为某些语句的重复执行,这就时所谓的循环。,循环控制,程序如下:int s = 0;s = s + 1;s = s + 2;s = s + 3;s = s + 100;printf (“s = %d”, s);,有!就是用循环来编程。,下面来思考一个问题:如何编程来计算1 + 2 + 3 + + 100?,重复100次,晕!,有没有更好的方法来计算呢?,学习目

2、标,循环控制,理解循环结构的含义; 掌握C语言三种循环结构的特点; 掌握while、do-while、for、goto、break、continue语句的使用方法; 掌握不同循环结构的选择及其转换方法; 掌握混合控制结构程序设计的方法。,循环控制,学习内容,实现循环的语句,实现循环的语句,goto语句,一般形式:,goto 语句标号; 语句标号: ,语句标号: goto 语句标号;,或,实现循环的语句,goto语句可与条件语句配合使用来实现条件转移,构成循环。,goto语句的应用:,例:求1100的累计和 #include void main ( ) int i = 1, sum = 0; l

3、oop: sum += i+;if (i = 100) /如果i小于或等于100goto loop; /转到标号为loop的语句去执行printf (“sum = %dn“, sum); ,循环初值,循环终值,循环条件,循环体,循环变量增值,运行结果: sum = 5050,在嵌套循环的情况下,利用goto语句可以直接从最内层的循环体跳出最外层的循环体。,实现循环的语句,int tag = 0; for () while ()if () goto stop; stop: for循环后的第一条语句,注意:在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生

4、困难。,实现循环的语句,while语句(当型循环结构),一般形式:,while (表达式) 循环体语句;,执行流程:,其中: while后面的括号( )不能省。 while后面的表达式可以是任意类型的表达式,但一般是条件表达式或逻辑 表达式。 表达式的值是循环的控制条件。 语句部分称为循环体,当需要执行多条语句时,应使用复合语句。,特点:先判断表达式,再执行循环体,实现循环的语句,例:用while语句求1100的累计和。,#include void main ( ) int i = 1, sum = 0; while ( i = 100 ) sum += i; i+; printf (“sum

5、 = %dn“, sum); ,循环初值,循环终值,循环条件,循环体,循环变量增值,运行结果: sum = 5050,实现循环的语句,例:显示110的平方,#include void main ( ) int i = 1;while ( i = 10 ) printf (“%d*%d=%dn“, i, i, i*i);i+;,运行结果: 1*1=1 2*2=4 3*3=9 4*4=16 5*5=25 6*6=36 7*7=49 8*8=64 9*9=81 10*10=100,实现循环的语句,如果while后的表达式的值一开始就为假,循环体将一次也不执行。,while语句注意事项:,int a

6、= 0, b = 0; while (a 0) /a 0为假,b+不可能执行b+;,循环体中的语句可为任意类型的C语句。,实现循环的语句,int num = 0; /字符计数 while ( 1 ) if (getchar( ) = n) /如果输入的字符是回车符,则返回return;num+; ,遇到下列情况,退出while循环:表达式为假(为0)。循环体内遇到break、return或goto语句(break和goto语句将 在随后介绍)。,实现循环的语句,在执行while语句之前,循环控制变量必须初始化,否则执行的结果将是不可预知的。,例:计算10! #include void main

7、 ( )int i; / i应赋初始值10long s = 1;while (i = 1)s *= i-;printf (“10! = %ldn“, s);,实现循环的语句,i = 1; while (i 100) /死循环,因为i的值没变化,永远小于100sum += i; printf (“sum = %dn“, sum);,要在while语句的某处(表达式或循环体内)改变循环控制变量,否则极易构成死循环。,实现循环的语句,i = 1; while (i = 9)j = 1;while (j = 9)printf (“%d * %d = %dn“, i, j, i * j);j+;i+;,

8、允许while语句的循环体又是while语句,从而形成双重循环。,例 求两个正整数的最大公因子。我们采用Euclid(欧几里德)算法来求最大公因子,其算法是:(1) 输入两个正整数m和n。(2) 用m除以n,余数为r,如果r等于0,则n是最大公因子,算法结束,否则(3)。(3) 把n赋给m,把r赋给n,转(2)。,#include void main ( ) int m, n, r;printf (“Please input two positive integer: “);scanf (“%d%d“, ,运行结果: Please input two positive integer: 24

9、56 Their greatest common divisor is 8,实现循环的语句,do_while语句 (直到型循环),一般形式:,do 循环体语句; while(表达式);,执行流程:,其中: while后面的括号( )不能省。 while最后面的分号;不能省。 while后面的表达式可以是任意类型的表达式,但一般是条件表达式或逻辑表达式。 表达式的值是循环的控制条件。 语句部分称为循环体,当需要执行多条语句时,应使用复合语句。,特点:先执行循环体,再判断表达式,实现循环的语句,例:用do_while语句求1100的累计和。,#include void main ( ) int i

10、 = 1, sum = 0; do sum += i; i+; while ( i = 100 );printf (“sum = %dn“, sum); ,运行结果: sum = 5050,循环初值,循环终值,循环条件,循环体,循环变量增值,实现循环的语句,#include void main ( ) int sum = 0,i; scanf(“%d”, ,#include void main ( ) int sum = 0,i; scanf(“%d”, ,例 while和dowhile比较,运行结果: 1 sum=55,运行结果: 1 sum=55,运行结果: 11 sum=0,运行结果:

11、11 sum=11,实现循环的语句,do_while语句注意事项:,int a = 0, b = 0;dob+; while (a 0) ;,如果do-while后的表达式的值一开始就为假,循环体还是要执行一次。,在if语句、while语句中,表达式后面都不能加分号,而在do-while语句的表达式后面则必须加分号,否则将产生语法错误。,实现循环的语句,循环体中的语句可为任意类型的C语句 和while语句一样,在使用do-while语句时,不要忘记初始化循环控制变量,否则执行的结果将是不可预知的。 要在do-while语句的某处(表达式或循环体内)改变循环控制变量的值,否则极易构成死循环。 d

12、o-while语句也可以组成多重循环,而且也可以和while语句相互嵌套。,实现循环的语句,for语句,一般形式:,for (表达式1;表达式2;表达式3)循环体语句;,执行流程:,其中: for后面的括号( )不能省。 表达式1:一般为赋值表达式,给控制变量赋初值。 表达式2:关系表达式或逻辑表达式,循环控制条件。 表达式3:一般为赋值表达式,给控制变量增量或减量。 表达式之间用分号分隔。 语句部分称为循环体,当需要执行多条语句时,应使用复合语句。,for语句很好地体现了正确表达循环结构应注意的三个问题: 控制变量的初始化。 循环的条件。 循环控制变量的更新。,实现循环的语句,例:用for语

13、句求1100的累计和。,#include void main ( ) int i , sum = 0; for (i = 1; i = 100; i+) sum += i; printf (“sum = %dn“, sum); ,运行结果: sum = 5050,实现循环的语句,for语句注意事项:,例:计算1*2+3*4+5*6+99*100。 int i, j; long sum = 0; for ( i =1, j = 2; i = 99; i = i + 2, j = j + 2 )sum += i *j; printf (“sum = %ldn“, sum);,表达式1、表达式2和表

14、达式3可以是任何类型的表达式。比方说,这三个表达式都可以是逗号表达式,即每个表达式都可由多个表达式组成。,逗号表达式,逗号表达式,实现循环的语句,#include void main ( ) int i, sum = 0;i = 1;for ( ; i = 100; i+)sum += i;printf(“sum = %dn“, sum); ,省掉表达式1,表达式1、表达式2、和表达式3都是任选项,可以省掉其中的 一个、两个或全部,但其用于间隔的分号是一个也不能省的。,循环前给变量赋初值,#include void main ( ) int i, sum = 0;for (i = 1; ;i+

15、 )sum += i;printf(“sum = %dn“, sum); ,省掉表达式2,无终止的循环下去,实现循环的语句,#include void main ( ) int i, sum = 0;for (i = 1; i=100; )sum += i+;printf(“sum = %dn“, sum); ,省掉表达式3,另外设计循环变量增值,#include void main ( ) int i, sum = 0;i = 1;for (; i=100; )sum += i+;printf(“sum = %dn“, sum); ,省掉表达式1、3,相当于while语句,实现循环的语句,#

16、include void main ( ) int i, sum = 0;i = 1;for ( ; ; )if (i 100) break;sum += i+;printf(“sum = %dn“, sum); ,省掉表达式1,2,3,如无适当设计也会陷入死循环,循环体中的语句可为任意类型的C语句。for语句也可以组成多重循环,而且也可以和while语句和do-while语句相互嵌套。 循环体可以是空语句。,例:计算用户输入的字符数(当输入是回车符时统计结束)。 #include void main ( ) int n = 0;printf (“input a string:n“);for

17、( ; getchar( ) != n; n+) ; printf (“%d“,n); ,表示循环体为空语句,并非表示for语句结束,实现循环的语句,循环控制,学习内容,循环的嵌套与比较,注意事项: 三种循环可互相嵌套,层数不限。 外层循环可包含两个以上内循环,但不能相互交叉。 在嵌套的各层循环中,应使用复合语句保证逻辑上的正确性。 内层和外层循环控制量不应同名,以免造成混乱。 嵌套循环最好采用右缩进格式书写,以保证层次的清晰性。,循环嵌套,一个循环的循环体中有另一个循环称为循环嵌套。,嵌套循环的跳转时禁止: 从外层跳入内层 跳入同层的另一循环 向上跳转,循环的嵌套与比较,while() wh

18、ile() .,do do while( );.while( );,while() do while( );.,嵌套循环的执行流程,for(;) for(;) .,for(;) while() .,do for(;) .while( );,循环的嵌套与比较,例:循环嵌套,输出九九表,#include void main ( ) int i, j;for (i = 1; i 10; i+)printf (“%4d“, i);printf (“n-n“);for (i = 1; i 10; i+)for (j = 1; j 10; j+)printf(j=9) ? “%4dn“ : “%4d“,

19、i * j); ,循环的嵌套与比较,for(i=1;i10;i+)for(j=1;j10;j+)printf(j=9)?“%4dn“:“%4d“,i*j);,循环的嵌套与比较,几种循环的比较,4种循环都可以用来处理同一问题,一般情况下它们可以相互替换,但一般不提倡用goto语句。 在while循环和do-while循环中,只在while后面的括号内指定循环条件,为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句(如i+/i=i+1)。for循环可以在表达式3中包含使循环趋于结束的操作。 用while循环和do-while循环时,循环变量初始化的操作应在while和do-while语句之

20、前完成,for语句可以在表达式1中实现循环变量初始化。 while循环、do-while循环和for循环,可以用break语句跳出循环,用continue语句结束本次循环,而对于用goto语句与if语句构成的循环,不能用break语句和continue语句进行控制。,循环的嵌套与比较,选择三种循环的一般原则,如果循环次数已知,计数控制的循环 用for 如果循环次数未知,条件控制的循环 用while或do-while 如果循环体至少要执行一次 用do-while 循环体可能一次也不执行, 用while,这只是“一般”原则,不是“原则”,例:求1100之间的所有素数,问题分析:素数是指除了能被1和

21、它本身整除外,不能被其它任何整数整除的数。例如,17就是一个素数,除了1和17之外,它不能被216之间的任何整数整除。根据素数的这个定义,可得到判断素数的方法:把m作为被除数,把i = 2 (m-1)依次作为除数,判断被除数m与除数i相除的结果,若都除不尽,即余数都不为0,则说明m是素数,反之,只要有一次能除尽(余数为0),则说明m存在一个1和它本身以外的另一个因子,它不是素数。事实上,根本用不着除那么多次,用数学的方法可以证明:只需用2 之间(取整数)数去除m,即可得到正确的判定结果。,这一思路的算法如下:从键盘输入一正整数m。计算k = i从2变化到k,依次检查m % i是否为0。若m %

22、 i为0,则判定m不是素数,并终止对其余i值的检验;否则,令i = i + 1;并继续对其余i值进行检验,直到全部检验完毕为止,这时判定m是素数。,循环控制,学习内容,break语句与continue语句,while (表达式1) if (表达式2) break; 语句,do if (表达式2) break; while (表达式1); 语句,for (; 表达式1; ) if (表达式2)break; 语句,break语句,break语句与continue语句,例:输出圆面积,面积大于100时停止,#define PI 3.14159 void main() int r;float area

23、;for(r=1;r100)break;printf(“r=%d,area=%.2fn“,r,area); ,break语句与continue语句,例:将用户输入的小写字母转换成大写字母,直到 输入非小写字母字符。,#include void main ( ) char c;while ( 1 ) c = getchar ( ); /读取一个字符if ( c = a /循环退出 ,运行结果: howareyou HOWAREYOU,break语句与continue语句,方法:通过设置一标志变量tag,然后在每层循环后加上一条语句:if (tag) break; 其值为1表示 跳出循环体,为0则

24、不跳出。,for () while ()if () break; while循环后的第一条语句 ,多重循环中,break的使用,int tag = 0; for () while ()if () tag = 1; break; if ( tag ) break; for循环后的第一条语句,在嵌套循环情况下,如何让break语句跳出最外层的的循环体?,break语句与continue语句,for () while ()if () continue; while循环后的第一条语句 ,continue语句,break语句与continue语句,例:求输入的十个整数中正数的个数及其平均值。,#incl

25、ude void main ( ) int i, a, num = 0;float sum = 0;for (i = 0; i 10; i+) scanf (“%d“, ,运行结果: 8 plus integers sum: 45 average value: 5.63,假设输入的10个整数为:1 2 3 4 5 6 7 8 9 10,void Init(void) char *p1 = NULL;char *p2 = NULL;char *p3 = NULL;p1 = (char*)malloc(256);if (p1 = NULL)goto Exit;p2 = (char*)malloc(

26、256);if (p2 = NULL)goto Exit;p3 = (char*)malloc(256);if (p3 = NULL)goto Exit;,两种适合使用goto的情况: 跳向共同的出口位置,进行退出前的处理工作,break语句与continue语句,跳出多重循环的一条捷径,break语句与continue语句,goto error;,循环控制,学习内容,例:利用下面的公式求的近似值,要求累加到最后 一项小于10-6为止。,问题分析:这是一个累加求和的问题,但这里的循环次数是预先未知的,而且累加项以正负交替的规律出现,如何解决这类问题呢?在本例中,累加项的构成规律可用寻找累加项通

27、式的方法得到,具体表示为t = s / n;即累加项由分子和分母两部分组成,分子s按+1,-1,+1,-1,交替变化,可用赋值语句s = -s;实现,s的初始值取为1,分母n按1,3,5,7,变化,用n = n +2;语句实现即可,n的初始值取为1.0。,循环控制程序举例,循环控制程序举例,#include #include void main ( ) int s = 1;float n = 1.0, t = 1, pi = 0;while (fabs(t) = 1e-6)pi += t;n += 2;s = -s;t = s / n;pi *= 4;printf (“pi = %.6fn“,

28、 pi); ,运行结果: pi = 3.141594,例:古典算术问题搬砖头,某地需要搬运砖块,已知男人一人搬3块,女人一人搬2块, 小孩两人搬一块。问用45人正好搬45块砖,有多少种搬法?,循环控制程序举例,#include void main() int men,women,child; for (men = 0; men = 45; men+)for (women = 0; women = 45; women+)for (child = 0; child = 45; child+)if (men+women+child=45) ,运行结果: men=0 women=15 child=30

29、 men=3 women=10 child=32 men=6 women=5 child=34 men=9 women=0 child=36,循环控制程序举例,例:求Fibonacci数列的前40个数,1202年,意大利数学家斐波那契出版了他的算盘全书。 他在书中提出了一个关于兔子繁殖的问题: 如果一对兔子每月能生一对小兔(一雄一雌),而每对小兔在 它出生后的第三个月里,又能开始生一对小兔,假定在不发生死亡 的情况下,由一对出生的小兔开始,50个月后会有多少对兔子?,循环控制程序举例,#include void main ( ) long int f1=1,f2=1;int i;for(i=1

30、;i=20;i+);printf (“ %12ld %12ld“,f1,f2);if(i%2=0)printf(“n”); f1=f1+f2;f2=f2+f1; ,循环控制程序举例,例:国王的许诺,相传国际象棋是古印度舍罕王的宰相达依尔发明的。舍罕王 十分喜欢象棋,决定让宰相自己选择何种赏赐。这位聪明的宰相指着88共64格的象棋盘说:陛下,请您赏给 我一些麦子吧,就在棋盘的第一个格子中放1粒,第2格中放2粒, 第3格放4粒,以后每一格都比前一格增加一倍,依此放完棋盘上 的64个格子,我就感恩不尽了。舍罕王让人扛来一袋麦子,他要兑现他的许诺。 国王能兑现他的许诺吗?试编程计算舍罕王共要多少麦子赏

31、赐 他的宰相,这些麦子合多少立方米?(已知1立方米麦子约1.42e8粒) 总粒数为:sum=1+2+22+23+263,#define CONST 1.42e8 #include #include main() int n;double term, sum = 0; /*累加求和变量赋初值*/for (n=1; n=64; n+)term = pow(2, n-1); /*根据累加项的规律计算累加项 */sum = sum + term; /*作累加运算*/printf(“sum = %en“, sum); /*打印总麦粒数*/printf(“volum = %en“, sum/CONST);

32、/*折合总麦粒体积数*/ ,方法1,运行结果: sum=1.84467e+19 volum=1.29907e+11,循环控制程序举例,韩信有一队兵,他想知道有多少人,便让士兵排队报数。按从1至5报数,最末一个士兵报的数为1;按从1至6报数,最末一个士兵报的数为5;按从1至7报数,最末一个士兵报的数为4;最后再按从1至11报数,最末一个士兵报的数为10。你知道韩信至少有多少兵吗? 设兵数为x,则x应满足: x%5 = 1 & x%6 = 5 & x%7 = 4 & x%11 = 10 穷举法对x从1开始试验,例:韩信点兵,循环控制程序举例,#include main() int x;for (x

33、=1; x 5000 ;x+)if (x%5=1 ,瞎猫碰死耗子,#include main() int x;for (x=1; ;x+)if (x%5=1 ,死循环,循环控制程序举例,#include main() int x;for (x=1; ;x+)if (x%5=1 ,方法一:goto,#include main() int x;for (x=1; ;x+)if (x%5=1 ,方法二:break,#include main() int x;int find=0;for (x=1; !find ;x+)if (x%5=1 ,方法三:标志变量,例:验证哥德巴赫猜想:任一充分大的偶数,可

34、以用两个素数之和表示。例如:4 = 2 + 2,6 = 3 + 3,98 = 19 + 79,这一思路的算法如下:读入大于3的偶数n。p = 1do p = p + 1; q = n - p;p是素数吗?q是素数吗? while p、q有一个不是素数。输出n = p + q。,问题分析:读入一个偶数n,将它分成p和q,使n = p + q。怎样分呢?可以令p从2开始,每次加1,而令q = n - p,如果p、q均为素数,则正为所求,否则令p = p + 1再试。,flagp = 1; for (j = 2; j = (int)sqrt(p); j+)if (p除以j的余数 = 0) flagp

35、 = 0; break; ,flagq = 1; for (j = 2; j = (int)sqrt(q); j+)if (q除以j的余数 = 0) flagq = 0; break; ,设置两个标志量flagp和flagq, 0-是不素数,1-是素数 while (flagp * flagq = 0);,循环控制程序举例,#include #include void main ( ) int i, n, p, q, flagp, flagq;printf (“please input n: “);scanf (“%d“, /程序结束,p = 1;do p+; q = n - p;flagp

36、= 1;for (i = 2; i = (int) sqrt(p); i+)if (p % i = 0) flagp = 0; break; flagq = 1;for (i = 2; i = (int)sqrt (q); i+)if (q % i = 0) flagq = 0; break ; while (flagp * flagq = 0); printf (“%d = %d + %dn“, n, p, q); stop: printf (“input data error!n“);,判断p是否为素数,判断q是否为素数,运行结果: please input n: 98 98 = 19 +

37、 79 please input n: 9 input data error!,例:打印大小可变的菱形图案(下面菱形的大小是7)。, ,问题分析:菱形的大小size其实就是中间行中*号的个数,也是整个菱形的行数,其值必须是奇数。问题的关键之一是如何确定每行中*号的个数。经过分析得知:当行数i(假设最上面的一行为第1行) (size+1)/2时,该行上的*号个数为n = 2*i-1,否则n = 2*( size-i+1)-1。问题的关键之二是如何确定每行显示的第一个*号的位置,也就是显示第一个*号之前应显示多少个空格。经过分析得知:每行应显示的空格数为m = (size - n) / 2个。,循

38、环控制程序举例,循环控制程序举例,#include #include void main ( ) int i, j, k, m, n, size;printf (“input size: “); /输入大小提示scanf (“%d”, /程序结束,for (i = 1; i = size; i+) /控制行数n = (i = (size+1)/2) ? i : size-i+1; /每行中“*“号的个数n = 2 * n - 1;m = (size - n) / 2 + 15; /每行打印“*“之前应打印的空格数for (k = 1; k = m; k+) /打印每行前面的空格printf (

39、“ “);for (j = 1; j = n; j+) /打印每行的“*“printf (“*“);printf (“n“); /打印一行后,回车换行 ,本章主要讨论了循环结构程序设计的有关方法,重点介绍了与C语言三种循环控制结构有关的while语句、do-while语句及for语句。本章所涉及到的主要关键字有:while、do、for、goto、break、continue。 语言提供了三种循环语句。for语句主要适用于循环次数确定的循环结构。循环次数及控制条件要在循环过程中才能确定的循环可用 while或do-while语句。三种循环语句可以相互嵌套组成多重循环,循环之间可以并列但不能交叉

40、。三种循环结构可以相互转换。可用转移语句把流程转出循环体外,但不能从外面转向循环体内。在循环程序中应避免出现死循环,即应保证循环控制变量的值在运行过程中可以得到修改,并使循环条件逐步变为假,从而结束循环。break、continue和goto语句都可用于流程控制。其中,break语句用于退出switch或一层循环结构,continue语句用于结束本次循环,继续执行下一次循环,goto语句无条件转移到标号所标识的语句处去执行。当程序需要退出多重循环时,用goto语句比用break语句更直接方便。,结构化程序设计,Structured Programming,简称SP 1965年,最早由E.W.D

41、ijkstra在一次国际会议上提出 1966年,C.Bohm和G.Jacopini首先证明了: 只用顺序、选择、循环三种基本的控制结构就能实现任何单入口、单出口的程序 给结构化程序设计奠定了基础 1971年,IBM公司的Mills提出: 程序应该只有一个入口和一个出口 进一步补充了结构化程序的规则,一个比较流行的定义是: 结构化程序设计是一种进行程序设计的原则和方法 它避免使用goto语句 采用“自顶向下、逐步求精”方法进行程序设计 按照这种原则和方法设计出的程序的特点为:,结构化程序设计,结构清晰 容易阅读 容易修改 容易验证,结构化程序设计的核心思想,采用顺序、选择和循环三种基本结构作为程序设计的基本单元 只有一个入口; 只有一个出口; 无死语句,即不存在永远都执行不到的语句; 无死循环,即不存在永远都执行不完的循环。 采用“自顶向下、逐步求精”和模块化的方法进行结构化程序设计 Top-down, Stepwise refinement1971年,wirth提出 先全局后局部 先整体后细节 先抽象后具体,结构化程序设计,if-else switch for while do-while break continue,结构化程序设计,结构化的控制语句:,_ _,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医学治疗 > 基础医学

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报