循环结构程序设计.ppt
2023/3/24,1,第5章 循环结构程序设计,学习目标,理解循环结构的概念。掌握如何用while语句构成循环结构。掌握如何用do-while语句构成循环结构。熟练掌握如何用for语句构成循环结构。掌握循环结构的嵌套使用。理解break和continue语句应用于循环体。,2023/3/24,2,引言循环是一种对同一程序段有规律的重复。被重复执行的部分叫循环体。循环结构的构成:用while语句 用do-while语句 用for语句 用if语句和goto语句(非结构化,不提倡)此外,在结构化循环语句的循环体中还可以包含break和continue语句,2023/3/24,3,while语句,while语句格式:while(条件表达式)SS是循环体,往往是一个复合语句当条件满足则继续循环特点是:先判断后执行特殊情况:开始时条件不满足就不进入循环;条件永远满足则永远循环(死循环),2023/3/24,4,真(非零),循环体,假(零),while语句流程图,2023/3/24,5,算法:S1:定义初始化变量。本程序需要三个变量,一个用来输入整数的n,一个i 用来表示求阶乘过程中数据从1到n的变化,还有一个fac用来保存计算阶乘的结果S2:输入n,需要考虑输入数据的合法性S3:计算n!,就是一个循环累乘求积的过程 n!=1*2*3*.(n-1)*n,【例5-1】用while语句求n!,2023/3/24,6,#include stdio.hvoid main()int n,i=1;long fac;printf(input an integer:);scanf(%d,/*此例改用后面的for循环语句更合理*/,输入:5 输出:5!=60,2023/3/24,7,#include stdio.h void main()float n;scanf(%f,/*继续输入*/,输入:1.2 7-3.5 9 0 输出:+-+,【例】输入一系列实数,判断其正负,当输入零时结束循环。,2023/3/24,8,#include stdio.h void main()char ch;int num=0;ch=getchar();while(ch!=n)num+;ch=getchar();printf(num=%dn,num);,输入:abcd 输出:num=4,【例】统计从键盘输入的一行字符的个数(以回车键作为输入结束标记),2023/3/24,9,do-while语句,do-while语句格式:do S while(条件表达式)当条件满足则继续循环特点是:先执行后判断至少循环一次特殊情况:条件永远满足则死循环,2023/3/24,10,do-while语句流程图,2023/3/24,11,void main()int n,i=1;long fac;scanf(%d,/*此例改用后面的for循环语句更合理*/,输入:5 输出:5!=60,【例5-2】用do-while语句求n!,2023/3/24,12,【例】输入一系列整数求和,直到输入的整数是零为止。void main()int n,s=0;/*累加器初始化*/do scanf(%d,输入:8 6 4 2 0 9 7 输出:s=20,2023/3/24,13,【例】用二分法求下面方程在0,1的近似解 x3+1.1x2+0.9x-1.4=0 令f(x)=x3+1.1x2+0.9x-1.4。因f(0)0,且f(x)0(x0,1),故f(x)为单调递增函数,故在 0,1间方程有一根。又f(x)0(x0,1),得下图 设a=0,b=1,为两端点,循环做:求a与b的中点送x,判断若f(x)0,则b=x,即产生新右端点;否则a=x,即产生新左端点;经多次循环后,得到的x即为所求。,2023/3/24,14,void main()float a=0.0,b=1.0,x;do x=(a+b)/2;if(f(x)0.0)b=x;else a=x;while(fabs(f(x)1e-6);printf(x=%fn,x);,程序如下:#includemath.h#includestdio.hfloat f(float x)return(x*x*x+1.1*x*x+0.9*x-1.4);,输出:x=0.670657,2023/3/24,15,for语句,for语句格式:for(表达式1;表达式2;表达式3)S 先计算初始化表达式1 若条件表达式2为真则执行S,否则结束循环 执行S之后,计算修正表达式3 重新执行 循环结束则执行for之后的语句,初始化表达式,条件表达式,修正表达式,2023/3/24,16,for语句流程图,2023/3/24,17,【例】用for语句改写【例5-1】for(fac=1,i=1;i=n;i+)fac*=i;它相当于以下语句:fac=1;i=1;/*相当于表达式1*/while(i=n)/*相当于表达式2*/fac*=i;i+;/*相当于表达式3*/,2023/3/24,18,【例】求1!+2!+3!+20!#include stdio.h void main()int i;float s=0.,t=1.;for(i=1;i=20;i+)t*=i;s+=t;printf(1!+2!+3!+20!=%-20.0fn,s);,输出:1!+2!+3!+20!=2561327455189073920,2023/3/24,19,【例】求和:1-1/2+1/3-1/4+-1/100 void main()float sum,t;int sign=1,i;/*sign为正负1*/for(i=1,sum=0;i=100;i+)t=sign*1./i;sum+=t;sign=-sign;printf(sum=%fn,sum);,输出:sum=0.688172,2023/3/24,20,for语句中表达式省略的几种情况:,(1)for语句一般形式中的“表达式1”可以省略 如:fac=1;i=1;for(;i=n;i+)fac*=i;,(2)表达式2省略,即不判断循环条件,循环会无终止地进行下去,所以此时循环体中要保证循环能正常结束 如:for(fac=1,i=1;i+)if(in)break;fac*=i;,2023/3/24,21,(3)表达式3也可以省略,同样,此时循环体中要保证循环能正常结束 如:for(fac=1,i=1;i=n;)fac*=i;i+;,(4)可以省略表达式1和表达式3,只有表达式2 如:fac=1;i=1;for(;i=n;)fac*=i;i+;,2023/3/24,22,(5)三个表达式都可省略,同样此时循环体中要保证循环能正常结束 如:fac=1;i=1;相当于 for(;)if(in)break;fac*=i;i+;,(6)循环体可以是空语句 如:for(fac=1,i=1;i=n;fac*=i,i+);,fac=1,i=1;while(1)if(in)break;fac*=i;i+;,2023/3/24,23,continue语句的使用continue语句的作用是结束本次循环,即跳过本次循环体中continue 语句之后的语句,转入下一次循环条件的判断,决定下次循环是否继续执行在while和do-while循环中,continue语句使得流程直接跳到循环控制条件的测试部分在for循环中,遇到continue后,跳过循环体中余下的语句,而转去对for语句中的“表达式3”求值,然后进行“表达式2”的条件测试,最后根据“表达式2”的值来决定for循环是否执行。,2023/3/24,24,break语句的使用break语句只能使用在循环体和switch语句内用break语句可以使程序执行流程跳出switch语句体,从而构成多分支选择结构break出现在循环体中时,用于结束当前循环,跳出break所在的循环结构break语句是完全从循环中跳出,而continue语句只结束本次循环,2023/3/24,25,【例5-3】找出1100之间的前10个偶数 void main()int n=0,count=0;while(n100)n+;if(count=10)break;/*判断是否满10个*/if(n%2!=0)/*判断是否奇数*/continue;/*若是奇数则重新循环*/printf(%d,n);/*打印偶数*/count+;/*统计偶数个数*/*此例改用for循环语句更合理*/,输出:2 4 6 8 10 12 14 16 18 20,2023/3/24,26,【例】输入10个正整数(非正整数则无效)求和 void main()int a,i=0,s=0;for(;)/*用for(i=s=0;)更合理*/scanf(%d,输入:1 2 3-1 4 5 6-2-4 7 8 9 10 输出:sum=55,2023/3/24,27,循环的嵌套,一个循环体内又包含另一个循环语句,称为循环的嵌套循环可以多重嵌套,如两重循环、三重循环、甚至四重循环三种不同循环语句可以互相嵌套执行时,整个内循环循环完后外循环才前进一步,内循环又从头循环循环中若执行break,则只能跳出该层循环,2023/3/24,28,循环嵌套时正确和错误的逻辑关系,2023/3/24,29,【例】输出由数字1、2、3、4、5组成的所有不重复数码的三位十进制整数#includestdio.h if(i!=jk+)/*共得到60个数*/,2023/3/24,30,【例5-4】打印九九乘法表#includevoid main()int i,j;for(i=1;i=9;i+)for(j=1;j=i;j+)printf(%d*%d=%-4d,j,i,i*j);printf(n);,输出:1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9,2023/3/24,31,【例5-6】判断一个正整数是否为素数void main()int x,k;int flag=1;/*设立标志*/scanf(%d,输入:6 输出:6 is not a prime.,应用举例,2023/3/24,32,【例5-7】求Fibonacci序列前n个数 1,1,2,3,5,8,13,21 其规律为:f1=f2=1 fn=fn-1+fn-2 用循环移位算法:其循环体为:f1 f2 f3 f3=f1+f2;1+1 2 f1=f2;1+2 3 f2=f3;2+3 5 程序见下页:,2023/3/24,33,void main()int n,i;long f1=1,f2=1,f3;scanf(%d,输入:11 输出:1 1 2 3 5 8 13 2134 55 89,2023/3/24,34,【例】将180分成4整数之和,第一数加5、第二数减5、第三数乘5、第四数除以5,其值均相等,问原来从180分出的4个整数各是什么?一个有疑问的算法:(请改进之!)for i:1180 做/*130*/for j:1180 做/*140*/for k:1180 做/*17*/m=180-i-j-k;w=i+5;x=j-5;y=k*5;z=m/5;若 w=x且x=y且y=z 则 输出 i,j,k,m,2023/3/24,35,【例】将180分成4整数之和,第一数加5、第二数减5、第三数乘5、第四数除以5,其值均相等,问原来从180分出的4个整数各是什么?一个改进的最优算法(逆向思维):for t:730 做 i=t-5;j=t+5;k=t/5;m=t*5;若 i+j+k+m=180 则 输出 i,j,k,m/*得出t=25*/,输出:i=20 j=30 k=5 m=125,2023/3/24,36,【例之一】利用公式/4=1-1/3+1/5-1/7+求的近似值(法1.用while结构)s=1;n=1.0;pi=0.0;t=1.0;/*s控制正负变化*/while(fabs(t)=1e-6)/*若通项不接近0*/t=s/n;/*计算通项*/pi=pi+t;/*累加器求和*/n=n+2;/*预算下次分母*/s=-s;/*变正负1*/pi=4*pi;,输出:pi=3.141598,2023/3/24,37,【例之二】(法2.用do.while结构)s=1;n=1.0;pi=0.0;/*不必t=1.0;*/do t=s/n;pi=pi+t;n=n+2;s=-s;while(fabs(t)=1e-6);pi=4*pi;,输出:pi=3.141598,2023/3/24,38,【例之三】(法3.若循环次数固定,用for结构)s=1;n=1.0;pi=0.0;for(i=1L;i=100000L;i+)t=s/n;pi=pi+t;n=2.*i+1;s=-s;pi=4*pi;printf(“pi=%fn”,pi);,输出:pi=3.141586,2023/3/24,39,一些较有用的标准库函数介绍延时:delay(unsigned ms)dos.h清屏:clrscr(void)conio.h定位:gotoxy(int x,int y)conio.h模式:textmode(int n)conio.h前景色:textcolor(int n)conio.h 背景色:textbackground(int n)conio.h彩色显示:cprintf()conio.h,