C语言循环解析.pptx
程序及程序设计的初步知识当条件判断表达式为真循环体语句判断表达式循环体语句真假循环体语句直到判断表达式为假循环体语句判断表达式假真循环结构比较当型循环直到型循环第1页/共104页【例5.1】计算ex,lnx。其中x=1,2,3,4,5。#include#include main()int x;float y,z;x=1;y=exp(x);z=log(x);printf(”y=%f,z=%f”,y,z);x=2;y=exp(x);z=log(x);printf(”y=%f,z=%f”,y,z);x=3;y=exp(x);z=log(x);printf(”y=%f,z=%f”,y,z);x=4;y=exp(x);z=log(x);printf(”y=%f,z=%f”,y,z);x=5;y=exp(x);z=log(x);printf(”y=%f,z=%f”,y,z);return(1);第2页/共104页采用循环控制语句实现#include#include main()int x;float y,z;x=1;while (x=5)y=exp(x);z=log(x);x+;printf(“y=%f,z=%f”,y,z)循环执行的条件:(x=5)每一次循环执行:计算y和z 改变x的值 输出y和z第3页/共104页4while while 语句语句“当型当型”循环结构循环结构一般形式:一般形式:while(表达式)语句;/*循环体*/说明:说明:“表达式表达式”为循环条件;为循环条件;“语句语句”为循环体。为循环体。特点:特点:先判断表达式,后执行语句先判断表达式,后执行语句图6_1难点:如何设置表达式和循环体中的语句.第4页/共104页【例5.2】求 。数学方法SUM=1+2+3+4+5+99+100SUM=1+2+3+4+5+N-1+N第5页/共104页改进方法:设两个变量:一个变量sum代表和,一个变量I代表序列中的某一个数。每一次相加的结果再放入sum中,再和下一项进行运算,表示如下:sum=1+2+3+4+5+N-1+NsumIsumIsumIsumI第6页/共104页7算法如下:用循环来表示算法,可以将算法表示如下:S1:读入NS2:sum=0S3:I=1S4:将sum+I 的和赋给sum,即:sum=sum+IS5:使I 的值加1,即:I=I+1S6:如果I=N,再做S4,否则,算法结束。第7页/共104页9main()main()int i=1,sum=0;int i=1,sum=0;while(i=100)while(i=100)sum=sum+i;sum=sum+i;i+;i+;printf(%d n,sum);printf(%d n,sum);编程求解:1+2+3+100?图6_2“i1”可否换成:“i0”第9页/共104页10注意:注意:JJwhilewhile语句中的语句中的“表达式表达式”(即判断条件)可以是任意的表达式,但一般为关(即判断条件)可以是任意的表达式,但一般为关系表达式或逻辑表达式。系表达式或逻辑表达式。JJ循环体如果包含一个以上的语句,应该用花括弧括起来,以复合语句形式出现。循环体如果包含一个以上的语句,应该用花括弧括起来,以复合语句形式出现。JJ在循环体中应有使循环趋向于结束的语句,以免形成死循环。在循环体中应有使循环趋向于结束的语句,以免形成死循环。第10页/共104页11典型例题1.累加求和、求积(迭代算法)分析:这一类题型是求一数列的和(积)。在处理此类问题时,通常采用的方法是:用一个变量存放累加和(积),从0(1)开始.第二个变量代表加数(或乘数),每次按一定的规律进行变换.第三个变量控制循环.从一个初始值(一般从1开始),每做一次循环,其值改变,然后判断表达式的值,最终跳出循环.【例5.3】输入10个数,求和第11页/共104页【例5.3】输入10个数,求和算法分析:sum:存放累加和.(初值为0)x:加数 i:控制循环.(初值为1)sum=0 i=1i=10得到加数 计算sum改变i01sum=0 i=1i=10scanf(“%f”,x)sum=sum+xi+01sum x1 x2 x3 x4 x10 1:sum2:sum3:sum10:sum设置表达式:i=10设置循环体:得到第 i个数(加数)计算sum 改变循环变量i第12页/共104页#include“stdio.h”main()floatx,sum;inti;sum=0;i=1;/*对sum和i赋初值*/While(i=10)/*循环取决于i的值*/scanf(“%f”,&x);sum=sum+x;i+;printf(”sum=%f”,sum);算法描述如下:/*此时加数为一个输入量循环体每执行一次则执行一次输入语句,即读入一个数*/第13页/共104页加数的变化规律:后一项=前一项+1(即增量为1)循环变量的规律:每做一次循环,则增1.因此可用一个变量i来代表加数和循环变量.设置表达式:isum 改变加数 改变循环变量 (i+);sum=0 i=1i=100sum=sum+ii+01【例5.4】求 1+2+3+4+100 的和第14页/共104页源程序如下:#include “stdio.h”main()int i,sum=0;/*累加求和从0开始*/i=1;/*i 既是加数,又是循环变量*/while(i=100)/*循环执行的条件是i=100*/sum=sum+i;i+;/*改变i*/printf(“%d”,sum);第15页/共104页可能是有规律可寻的,比方说存在通项公式:a(I)=f(I);或递推公式:a(I)=f(a(i-1),I)算法可描述为:s=0;n=1;While (n=100)s=s+通项(某一项);/*这时通项需要通过计算*/n+;每次从变量的一个旧值推出新值(即迭代算法)。第16页/共104页main()int i,sum=0;i=1;/*i 既是通项,又是循环变量*/while(i=99)/*循环执行的条件是i=99*/sum=sum+i;i=i+2;printf(“%d”,sum);【例5.5】求1+3+5+7+9+99难点:1)找出通项公式,即找出加数的变化规律为:后一项=前一项+2;2)循环如何控制:每一次增加2.思考:如果数列是:1+1.1+1.2+1.3+1.4+1.5+2.0第17页/共104页18典型例题1.累加求和、求积(迭代算法)【例5.6】计算n!,其中n由键盘输入。输入fac=1 i=1i=nfac=fac*ii+01分析如下:fac:存放累加乘积.i:乘数,又控制循环.设置循环表达式:ifac 改变乘数 改变循环变量 (i+);第18页/共104页源程序如下:注意:这里,尽管n和n!是整数,但当n较大时,n!可能超过整型数范围。所以将变量fac定义为实型。算法为:main()float fac;int i,n;scanf(“%f”,&n);fac=1=1;i=2;i=2;While (i=n)fac=fac*i;i+;i+;printf(“fac=%8.0f”,fac);思考:如何求S=1!+2!+3!+n!(这是一个累加问题,通项a(n)=n!=n*a(n-1)第19页/共104页20【例【例5.75.7】求】求2 2n n。main()int i=1,n;long int p=1;scanf(%d,&n);while(i=n)p*=2;i+;printf(%dn,p);图5_3分析;输入:n输出:P(表示n!)第20页/共104页典型例题2.菲波拉契数列问题【例5.8】:求菲波拉契数列a0,a1a20分析:该数列的规律是:a0=0,a1=1,a2=1,a3=2,a4=3 an=an2+an1 即:a2=a0+a1;a3=a1+a2;a4=a2+a3;a20=a18+a19 难点:如何设置循环体:an=an2+an1考虑an、an2、an1如何变换:a3a2a3a4a2a1a0:代表前一个数a1:代表后一个数a2:代表需要计算的数每计算一次a2则a1 a0a2 a1第21页/共104页a2=a0+a1;a0=a1;a1=a2;a2=a0+a1;(a3=a1+a2;)(a4=a2+a3;)a0=a1;a1=a2;a2=a0+a1;用a2代表所求的某一项,a0、a1代表该项的前两项,每求一次a2,将a1、a2作为下一次的a0和a1。第22页/共104页算法描述:分析:1)序列中的前两项已知,可直接输出,需要计算的是a2,a3a20共19项.且通项公式为:每一项=前两项之和 2)设置循环表达式:i=19 3)设置循环体:计算a2;求a0,a1;输出a2;改变循环变量 (i+);输出a0、a1i=19计算a2,a0,a1输出a2,i+01第23页/共104页 源程序如下:#include “stdio.h”void main()float a0,a1,a2;int i=1;a0=0;a1=1;printf(“%10.0f,%10.0fd”,a0,a1);/*循环外给a0,a1赋初值,并输出这两个值*/while (i=19)/*从a2开始进入循环,到a20结束*/a2=a0+a1;/*计算公式*/a0=a1;a1=a2;i+;printf(“%10.0f”,a2)/*输出a2*/*这两个语句顺序不能颠倒,下标不能错*/第24页/共104页典型例题2.菲波拉契数列问题【例5.9】:输出菲波拉契数列前21项,并求和。分析:在求和之前,应先求出通项的值,并输出.#include“stdio.h”main()float s,a0,a1,a2;int i=0;a0=0;a1=1;printf(“%10.f,%10.0f”,a0,a1);s=a0+a1;/*累加单元先求前两项的和*/While (i=0时.因此,循环表达式为 while (x=0)2)设置循环体:每得到一个新的数x,就将它和max比较,如果(xmax),就执行max=x,否则比较x和min,如果(xmax)max=x;else if (x=0)/*当x非负,执行循环体*/scanf(%f,&x);if (xmax)max=x;else if(x0 xmax10max=xX=a&c=A&c=0&ch=a&c=A&c=0&c=a&c=A&c=0&ch=9)s2+=1;ch=getchar();/*scanf(“%c”,&C);*/第30页/共104页【例5.12】:输入某班学生的成绩,以负数 结束,输出各分数段的人数。score:成绩 S1:存放90分以上人数 S2:存放8089分人数 S3:存放7079分人数 S4:存放6069分人数 S5:存放60分以下的人数 循环终止条件为score=0.设置循环体:每次得到一个新的成绩score,然后判断它在哪个分数段,将它所在的分数段对应的计数变量增1.如score=89,则s2=s2+1;第31页/共104页#include “stdio.h”main()float score;int s1=s2=s3=s4=s5=0;scanf(“%f”,&score);while (score=0)if(score=90)s1=s1+1;else if(score=80)s2+=1;else if (score=70)s3+;else if(score=60)s4+;else s5+;printf(“%8.1f,%8.1f,%8.1f,%8.1f,%8.1f”,s1,s2,s3,s4,s5);scanf(“%f”,&score);67 78 91 55 60 -77scorescore=67 s4=1score=78 s3=1score=91 s1=1score=55 s5=1score=60 s4=2score=-77 跳出循环第32页/共104页33while while 语句语句在while循环体内也允许空语句。例如:while(c=getchar()!=X0D);/*这个循环直到键入回车为止 */可以有多层循环嵌套。语句可以是复合语句,此时必须用“”和“”括起来第33页/共104页例:有如下程序,该程序段的输出结果是main()int n=8;while(n6)n-;printf(“%d”,n);WHILE语句中的条件表达式:(n6)1)n-;即n=7,输出72)n-;即n=6,输出6(n6)条件不满足,结束循环76第35页/共104页例:若输入字符串:ENGLISH,则以下while循环体将执行 _ 次。While(ch=getchar()=S)printf(“*”);循环体执行的条件:(ch=getchar())=S输入为:ENGLISH则ch=E因此条件不满足,结束循环0第37页/共104页do-while do-while 语句语句_“直到型直到型”循环结构循环结构一.格式(直到型)do 语句while(表达式);二.执行过程 系统首先执行循环体,再判断表达式的值,若值为“真”,则继续执行循环体;否则跳出循环体,执行后续语句。它的特点是“先执行,后判断”。至少要执行一次循环语句循环体表达式01第38页/共104页39三.典型例题【例5.13】:求 1+2+3+4+100 的和main()int i,sum=0;i=1;do sum=sum+i;i+;while(i=100)printf(“%d”,sum);sum=0 i=1i=100sum=sum+ii+10第39页/共104页例:假定a和b为int型变量,则执行以下语句后b的值为a=1;b=20;do b-=a;a+;while(b-0);Do-while循环的特点:先执行后判断。循环体是:b-=a;a+;得到b=b-a=19;a=2;(b-0)先判断(b0)之后再执行b-18第41页/共104页【例【例5.14】#include main()char c;do c=getchar();if(c=A&c=Z)c+=32;putchar(c);while(c!=n);将键盘输入字符中所有大写字母转换为小写字母,其他字符不变。第44页/共104页比较 while语句与do-while语句1.do-while语句循环体至少执行一次2.都是在表达式值为真时执行循环体,为假时结束。3.do,while必须成对出现。do与while之间的语句组成循环体,可以是一句,也可以是多句。可以嵌套其它循环语句。循环体表达式100表达式循环体1第45页/共104页for for 语句语句一.格式for(;)语句;初始化是一个赋值语句,它用来给循环控制变量赋初值;条件表达式是一个关系表达式,它决定什么时候退出循环;增量定义循环控制变量每循环一次后按什么方式变化。【例】for(i=1;i=5;i-)printf(“%d”,i);执行此语句将输出:98765第47页/共104页FOR 语句语句s1.求解表达式1s2.求解表达式2,值为“真”,执行循环 体;值为“假”,跳出循环执行下一条语句s3.执行内嵌语句(循环语句)s4.求解表达式3;返回s2s5.执行语句下面的一条语句 注意注意 应用FOR语句时:循环体被执行的次数(N)应是已知的。求解表达式1循环体表达式210求解表达式3二.循环执行过程第48页/共104页49【例5.15】求 。(改【例5.4】)main()int i,sum=0;for(i=1;i=100;i+)sum=sum+i;printf(%d n,sum);第49页/共104页51FOR 语句语句 注意注意 for循环中语句可以为语句体,但要用“”和“”将参加循环的语句括起来。for循环中的“初始化”、“条件表达式”和“增量”都是选择项,即可以缺省,但“;”不能缺省。第51页/共104页52FOR 语句语句1)省略了表达式1(初始化),表示不对循环控制变量赋初值。例:for(;i=100;i+)sum=sum+i;可在循环开始之前初始化变量:i=1;for(;i=100;i+)sum=sum+i;第52页/共104页53FOR 语句语句2)省略了表达式 2(条件表达式),则不做其它处理时便成为死循环。例:for(i=1;i+)sum=sum+i;/*成为死循环*/第53页/共104页54FOR 语句语句3)省略了表达式3(增量),则不对循环控制变量进行操作。例:for(i=1;i=100;)sum=sum+i;可在循环体中控制循环变量:for(i=1;i=100;)sum=sum+i;i+;第54页/共104页55FOR 语句语句4)可以省略表达式1和表达式3,即只有循环条件。例:for(;i=100;)sum=sum+i;i+;相当于 while(i=100)sum=sum+i;i+;第55页/共104页56FOR 语句语句5)省略了表达式 1,2,3,则不做其它处理时便成为死循环。例:for(;)语句 /*成为死循环*/第56页/共104页57FOR 语句语句6)表达式1可以是设置循环变量初值的赋值表达式,也可以是与循环变量无关的其它表达式。例:for(sum=0,i=1;i=100;i+)sum=sum+i;for(i=0,j=100;ij;i+,j-)k=k+i+j;第57页/共104页【例【例5.16】求调和级数1+1/2+1/3+1+1/2+1/3+1/+1/n n 前n n项的和。分析:输入项 n,输出项 sum。调和级数的通项公式为1/n一级算法:1.输入n,sum置0;2.计算和sum;3.输出sum二级求精:2-1 for(i=1;i=n;i+)sum=sum+1.0/isum=0i=1i=nsum=sum+1/i1i=i+10第66页/共104页【例5.17】求两个正整数(a、b)的最大公约数(gcd)及最小公倍数(lcm)算法分析:确定输入(输入两个整数a和b)、输出(最大公约数gcd、最小公倍数lcm)确定计算方法。即如何得到最大公约数和最小公倍数。最大公约数:即两个数的最大公因子。最小公倍数:即能被两个数整除的最小整数,可由两数的乘积除以最大公约数得到。第68页/共104页 方案一确定范围:1=最大公约数=两个数中的较小数(min)算法思想:用1,2,3min逐个去除a和b,如果其中的某一个数能将两个数除尽,说明它是a和b的公因子,将其保留下来。一级算法:1输入两个数a、b2比较两个数的大小,得到较小数min3FOR (j=1;j=min;j+)4如果a和b均能被j整除,则将j的值暂时保留,赋值给gcd,否则做下一次循环。5计算lcm=a*b/gcd6输出gcd、lcm。二级求精:4-1 if (!(a%j)&(b%j=0)gcd=j;第69页/共104页程序段如下:scanf(“%d,%d”,&a,&b);min=(ab)?a:b;for (j=1;j=1;j-)if (!(a%j)&(b%j=0)gcd=j;break;用WHILE语句实现:j=min;while (a%j|b%j)j-;gcd=j;第71页/共104页72三种循环的比较:三种循环的比较:三种循环的比较:三种循环的比较:三种循环都可以用来处理同一问题,一般情况下它们可以互相代替。三种循环都可以用来处理同一问题,一般情况下它们可以互相代替。用用whilewhile和和do do whilewhile循环时,循环变量初始化的操作在循环时,循环变量初始化的操作在while while 和和do do whilewhile语句前完成;语句前完成;forfor语句可以在表达式语句可以在表达式1 1中完成。中完成。第72页/共104页73三种循环的比较三种循环的比较三种循环的比较三种循环的比较(续续续续):whilewhile和和do do whilewhile循环只在循环只在whilewhile后面指定循环条件,且在循环体中应包含后面指定循环条件,且在循环体中应包含使循环趋于结束的语句;使循环趋于结束的语句;forfor循环可以在表达式循环可以在表达式3 3中包含使循环趋于结束的操中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式作,甚至可以将循环体中的操作全部放到表达式3 3中,功能更强。中,功能更强。while while 和和forfor循环是先判断表达式,后执行语句;循环是先判断表达式,后执行语句;do do whilewhile循环是先执行语循环是先执行语句后判断表达式。句后判断表达式。第73页/共104页74循环的嵌套循环的嵌套定义:一个循环体中又包含一个完整的循环结构,称为循环的嵌套。说明:while 循环、do while循环和 for循环都可以进行嵌套,而且可以相互嵌套。第74页/共104页几种合法的嵌套结构:while()while()dodowhile();while();for(;)for(;)while()dowhile();for(;)while()dofor(;)while();第75页/共104页76使用循环嵌套时注意:使用循环嵌套时注意:要保证嵌套的每一层循环在逻辑上都是完整的,避免嵌套交叉使用。要保证循环到最后有一个跳出循环的条件,否则会产生死循环(嵌套循环中检查死循环错误,相对来说比较困难)。在编程时,注意循环嵌套的书写最好用阶梯缩进阶梯缩进的形式,可使程序层次分明。第76页/共104页【例5.20】输出1100内所有的素数。(穷举算法)分析:素数是大于,且除了和它本身外,不能被其它任何整数所整除的整数。一级算法:for(i=2;i=100;i+)1.判断每一个数i是否为素数1-1for(j=2;j=i1;j+)if(i%j!=0)flag=1;Elseflag=0;1-2if(flag=1)输出素数i二级算法:1-1.用2i-1去除i,考察是否能除尽,设置标识.1-2.判断标识,如果一直除不尽,输出I是素数的信息.二级求精:对于一个数i,如果从2i-1都不能将i整除,才能说明i是素数,否则i不是素数。1-1flag=1;1-2for(j=2;j=i1;j+)if(i%j=0)flag=0;1-3if(flag=1)输出素数i第80页/共104页【例5.20】输出1100内所有的素数。优化算法优化算法:为判断某数I是否为素数,用2 sqrt(i)去除该数,若全都除不尽,则是素数。若被其中一个数除尽,则不是素数。二级算法:1-1.用2sqrt(i)去除i,考察是否能除尽,设置标识.1-2.判断标识,如果一直除不尽,输出I是素数的信息.二级求精:1-1flag=1;1-2 for(j=2;j=sqrt(i);j+)if(i%j=0)flag=0;1-3if(flag=1)输出素数i第81页/共104页#include Void main()int I,j,flag;for(I=2;I100;I+)flag=1;for(j=2;j=sqrt(i);j+)if (i%j=0)flag=0;if (flag=1)printf(“%d is a prime number”,I);以I=49为例j=2 flag=149%2=1 j=3 flag=149%3=1 j=4 flag=1.49%7=0 flag=0【例5.20】输出1100内所有的素数。第82页/共104页【例5.20】输出1100内所有的素数。思考:如果将for-for嵌套改为for-while嵌套,程序如何修改?For(I=2;I=100;I+);j=2;flag=1;while(j=(sqrt(i)&flag)if(i%j=0)flag=0;j=j+1;If(flag)printf(“%disaprimenumber”,i);第83页/共104页break break 语句语句无条件转移语无条件转移语句句vv一般形式:break;vv功能:v用在switch语句中使流程跳出switch结构,继续执行switch语句后面的语句。v用在循环体内,迫使所在循环立即终止(跳出当前循环体),继续执行循环体后面的第一条语句。vv说明:该语句仅能用于switch语句和循环语句。第84页/共104页【例5.20】输出1100内所有的素数。优化算法优化算法:为判断某数I是否为素数,用2 sqrt(i)去除该数,若全都除不尽,则是素数。若被其中一个数除尽,则不是素数,不再对此数继续判断。一级算法:for(i=2;i=100;i+)1.2sqrt(i)去除i,考察是否能除尽2.if除不尽输出素数i二级求精:1-1flag=1;1-2 for(j=2;j=sqrt(i);j+)if(i%j=0)flag=0;break;第85页/共104页Main()int i,j,flag;For (i=2;i=100;i+)j=2,flag=1;for (;j=sqrt(i);j+)if i%j=0 flag=0;break;if flag printf(“%d is a prime number”,i);i=100j=2,flag=1j=sqrt(i)i%j=0flag=0101100例:I=16进入外循环,j=2,flag=1进入内循环,经过1次内循环,flag=0,内循环结束,没有输出 flag输出i例:I=17进入外循环,j=2,flag=1进入内循环,经过3次内循环flag=1,内循环结束,输出17 isaprimenumber 第86页/共104页continuecontinue语句语句无条件转移语无条件转移语无条件转移语无条件转移语句句句句一般形式:continue;功能:结束本次循环(跳过循环体中尚未执行的语句),接着进行是否执行下一次循环的判定。continue和break的区别:continue只结束本次循环,而非终止整个循环。break则是结束所在循环,不再进行条件判断。第87页/共104页例设x和y均为int型变量,则y值为 for(y=1,x=1;y=10)break;if(x%2)x+=5;continue;x-=3;If(x%2=1)1)x=1;x%2=1;x=x+5=6,结束本次循环,Y=1+1=22)(6%2=1)条件不满足,执行X=X-3=6-3=3,Y=2+1=33)(3%2=1)条件满足,则X=X+5=8;结束本次循环,Y=3+1=4;4)(8%2=1)不满足,则X=X-3=5;Y=4+1=5;5)(5%2=1)满足,则X=X+5=10;Y=5+1=6;6)(X=10)条件满足,执行break;结束循环。6第91页/共104页【例5.25】输出如下图形:*#include Void main()int i,j,n;scanf(“%d”,&n);for(i=1;i=n;i+)for(j=1;j=1;i-)for(j=1;j=2*i-1;j+)printf(“*”);printf(“n”);第100页/共104页101第101页/共104页102goto goto 语句语句一般形式:goto 语句标号;说明:goto为无条件转向语句。语句标号必须是合法的标识符。不能用整数作标号。用途:与if语句一起构成循环结构;从多层循环体的内层循环跳到外层循环。结构化程序设计方法主张限制使用goto语句,因为滥用goto语句将使程序流程无规律、可读性差只有不得已只有不得已(如能大大提高效率如能大大提高效率)时才能使用时才能使用gotogoto!第102页/共104页【例【例5.245.24】用】用ifif和和gotogoto语句构成循环,求语句构成循环,求 。main()int i=1,sum=0;loop:if(i=100)sum=sum+i;i+;goto loop;printf(Sum=%d,sum);第103页/共104页104感谢您的欣赏!第104页/共104页