第5章循环结构程序设计.ppt
第5章 循环结构程序设计,5.1 循环结构的控制语句5.2 循环的嵌套5.3 break语句和continue语句5.4 应用举例,5.1循环结构的控制语句,5.1.1 while循环语句1.什么是while循环while即当的时候,也就是当满足条件时就循环执行指定的代码。2while 语句的形式:while(表达式)循环体;计算机首先判断表达式中的值,若值非0,则执行循环体中的语句,一旦语句执行完毕,表达式中的值将会被重新计算,如果还是为非0,语句将会再次执行,这样一直重复下去,直至表达式中的值为0为止。其具体执行流程如图5-1所示。,表达式,非0,0,语句,3说明1)while循环的特点是:先判断表达式,后执行语句。2)表达式同if语句后的表达式一样,可以是任何类型的表达式。3)while循环常用于循环次数不固定,根据是否满足某个条件决定循环与否的情况。4循环体中的语句多于一句时,用一对 括起。,【例5-1】用while循环语句求100以内所有奇数的累计和。分析:此题可以用“1+3+99”来求解,但显然很繁琐。现在换个思路来考虑:首先设置一个累计器sum,其初值为0,反复利用sum=sum+i来计算(i依次取1、3、99),编程只要采取以下3个步骤即可:(1)将i的初值置为1;(2)每执行1次“sum=sum+i”后,i增2;(3)当i增到大于99时,停止计算。此时sum的值就是100以内所有奇数的累计和。,#include main()int i=1,sum=0;while(i=99)sum=sum+i;i=i+2;printf(sum=%dn,sum);运行结果:sum=2500,不能少,复合语句,5.1.2 dowhile循环语句1.什么是dowhile循环do-while语句常称为“直到型”循环语句,其特点是先执行一次循环体的操作,然后再判断条件是否满足。2dowhile 语句的形式:do 循环体;while(表达式);计算机首先执行循环体中的语句,然后判断表达式中的值,若值非0,则语句将会再次执行,这样一直重复下去,直至表达式中的值为0为止。其具体执行流程如图5-2所示。,表达式,非0,0,循环体语句,3说明1)while循环结构是先判断后执行;dowhile循环结构是先执行后判断。当初始情况不满足循环条件时,while循环一次都不会执行,而dowhile循环不管任何情况都至少执行一次。因而,当第一次条件为真时,while、dowhile等价;第一次条件为假时,二者不同。2)dowhile循环结构表达式后面有分号,while循环结构表达式后面没有分号,编程时一定要注意。,【例5-2】用dowhile循环语句编程求123.10的累乘积。分析:首先设置一个累乘器m,其初值为1,反复利用m=mi来计算(i依次取1、2、10),编程只要采取以下3个步骤即可:(1)将i的初值置为1;(2)每执行1次“m=mi”后,i增1;(3)当i增到大于10时,停止计算。此时m的值就是123.10的累乘积。,源程序:#includemain()int i=1;long m=1;do m=m*i;i+;while(i=10);printf(%ldn,m);,运行结果:3628800,必须赋值为1,后面的分号不可少,5.1.3 for循环语句1.什么是for循环for循环也是C语言中一种处理循环的编程结构,for语句使用最为灵活,它完全可以取代 while 语句,应用在循环次数已知的场合尤为方便。,2for语句的形式:for(表达式1;表达式2;表达式3)循环体;具体来说,for语句的执行过程如下:(1)先求解表达式1;(2)求解表达式2,若为0(假),则结束循环,并转到(5);(3)若表达式2为非0(真),则执行循环体,然后求解循环表达式3;(4)转回(2);(5)执行for语句下面的一个语句。其具体执行流程如图5-3所示:,3说明1)for语句最简单的应用形式也是最容易理解的形式如下:for(循环变量赋初值;循环条件;循环变量增量)循环体;2)三个表达式都允许省略,但要注意省略表达式后,分号间隔符不能省略。例如:for(;)表示不设初值,不判断条件(始终认为表达式2为真),循环变量不变化,无终止执行循环体的语句。3)while、dowhile和for语句可以用来处理同一问题,一般情况下它们可以互相代替。,【例5-3】用for语句求1-3+5-7+-99。分析:原题就是计算1+(-3)+5+(-7)+(-99)的累计和,还是一个连加问题。加数符号的交叉变化,可在程序中增加一个符号控制变量j,j的初值设置为1,并在每次循环中对j都乘以负1,用j改变相加项的正、负。,源程序:#include main()int i,j,sum=0;j=1;for(i=1;i=99;i+=2)sum=sum+i*j;j=j*-1;printf(1-3+5-7+-99=%dn,sum);,运行结果:1-3+5-7+-99=-50由此例可见,在循环次数已知的场合下,for语句将循环体所用的控制都放在循环顶部统一表示,显得更简洁和直观。,j的初值设置为1,在每次循环中对j都乘以负1,5.2 循环的嵌套,1.什么是循环的嵌套一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多重循环。上述三种循环(while循环,do-while循环和for循环)语句之间可以相互嵌套使用。,2循环嵌套的形式:例如,下面几种都是合法的嵌套形式:,(1)while()while(),(2)while()do while();,(3)do while()while();,(4)for()for(),3说明在循环嵌套时,外循环必须完全包含内循环,即不允许循环的交叉嵌套。【例5-4】百钱买百鸡,公鸡5元一只,母鸡3元一只,小鸡1元三只;一百元钱买一百只鸡,且公鸡、母鸡、小鸡都要有,编程求解所有购鸡方案。分析:设公鸡、母鸡、小鸡各为i、j、k,列出方程为:i+j+k=100 3i+2j+1/3*k=100三个未知数,两个方程,此题有若干个组解。计算机求解此类问题,采用试凑法(也称枚举法)来实现,即将可能出现的各种情况一一罗列测试,判断是否是问题真正的解。此题可以采用二重循环,列举出该问题所有可能的解进行筛选。,源程序:#include void main()int i,j,k,n=0;for(i=1;i=20;i+)for(j=1;j=33;j+)k=100-i-j;if(5*i+3*j+k*1/3=100)n+;printf(i=%d,j=%d,k=%dn,i,j,k);printf(n 共有%d种购鸡方案,n);,运行结果:i=3,j=20,k=77i=4,j=18,k=78i=7,j=13,k=80i=8,j=11,k=81i=11,j=6,k=83i=12,j=4,k=84共有6种购鸡方案,公鸡的个数不会超过20个,母鸡的个数不会超过33个,5.3 break语句和continue语句,5.3.1 break语句1.什么是break语句break语句是改变程序控制流的语句,通常用在循环语句和开关语句中。当break语句用于do-while、for、while循环语句中时,可使程序提前终止循环而执行循环后面的语句。此时通常break语句总是与if语句联在一起。即满足条件时便跳出循环。,2break语句的形式:break;例如:while(表达式1)语句A if(表达式2)break;语句B其执行过程如图5-4所示:,3说明1)break语句不能用于循环语句和switch语句之外的任何其他语句中。2)在多重循环中,一个break语句只向外跳一层。,【例5-5】求100以内能被7整除的最大的数。分析:首先设置变量x,设置其初值为100,利用循环,从100开始对依此递减1的每一个数进行测试,一旦该数能被7整除(x%7=0)就强制结束循环,此时的x就是所要求的数。,源程序:#include stdio.hmain()int x;for(x=100;x=1;x-)if(x%7=0)break;printf(x=%dn,x);,运行结果:x=98,若能被7整除,提前结束循环,5.3.2 continue语句1.什么是continue语句continue语句也是改变程序控制流的语句,其作用是:结束当前正在执行的这一次循环(for、while、dowhile),接着执行下一次循环。即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。2continue语句的形式:continue;例如:while(表达式1)语句A if(表达式2)continue;语句B其执行过程如图5-5所示:3说明1)continue语句只用在for、while、do-while等循环语句中,常与if条件语句一起使用。2)continue语句和break语句的区别是:continue语句只结束本次的循环,并不跳出循环,转而去判断是否执行下一次循环;而break语句则是终止整个循环的执行,不再进行条件判断。,【例5-6】使用continue语句,输出100以内能被7整除的所有整数。分析:首先设置变量x,其初值为1,利用循环对1100的每一个数进行测试,如该数不能被7整除(x%7!=0),则由continue语句转去下一次循环。只有当该数能被7整除(x%7=0),才能执行后面的printf语句,输出能被7整除的数。,源程序:#include main()int x;for(x=1;x=100;x+)if(x%7!=0)continue;printf(%d,x);,运行结果:7 14 21 28 35 42 49 56 63 70 77 84 91 98,若能被7整除,结束本次循环,转而判断是否执行下一次循环,5.4 应用举例,【例5-7】编程计算级数 的和,当最后一项小于10-5时结束。分析:本例涉及到程序设计中两个重要运算累加和连乘,其程序设计方法已在前面做过介绍。此题可以先使用连乘的方法求i!,再将(i+i)/i!进行累加,循环次数未知,可用while循环来实现。,源程序:#include main()int i=1;long n=1;float s=0,t=1;while(t=1e-5)n=n*i;t=(float)(i+i)/n;s=s+t;i+;printf(s=%fn,s);,运行结果:s=5.436563,当(i+i)/i!小于10-5时退出循环,求i!,将(i+i)/i!进行累加,【例5-8】编程输出下面的数字金字塔(1到9)1 121 12321.12345678987654321分析:可采用双重循环,用外循环控制行数,逐行输出。每一行输出步骤一般3步:1)光标定位;2)输出图形;例如本题:共9行,若行号用i表示,则每行前半部分输出数字1到i,后半部分输出数字(i-1)到1。3)每输完一行光标换行(n)。,源程序:#includemain()int i,j,k;for(i=1;i=1;k-)printf(%d,k);printf(n);,外循环控制行数,内循环用空格光标定位,内循环输出每行前半部分数字1到i,内循环输出每行后半部分数字(i-1)到1,每输完一行光标换行,【例5-9】输出10100之间的全部素数。所谓素数n是指,除1和n之外,不能被2(n-1)之间的任何整数整除。分析:显然,只要设计出判断某数n是否是素数的算法,外面再套一个for循环即可。判断某数n是否是素数可用2(n-1)之间的每一个数去整除n,如果都不能被整除,则表示该数是一个素数。而判断一个数是否能被另一个数整除,可通过判断它们整除的余数是否为0来实现。,源程序:#include main()int i,j,counter=0;for(i=11;i=i)printf(%d,i);counter+;if(counter%10=0)printf(n);,运行结果:11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97,外循环:为内循环提供一个整数i,内循环:判断整数i是否是素数,若i不是素数,强行结束内循环,执行下面的if语句,若整数i是素数:输出,计数器加1,每输出10个数换一行,【例5-10】求Fibonacci数列的前20个数。该数列的生成方法为:F1=1,F2=1,Fn=Fn-1+Fn-2(n=3),即从第3个数开始,每个数等于前2个数之和。分析:此题可用递推法来解决。所谓递推法就是从初值出发,归纳出新值与旧值间的关系,直到求出所需值为止。假设 f1为第一个数,f2为第二个数,f3为第三个数,根据该数列定义:f1=1;f2=1;f3=f1+f2;以后只要在循环中改变f1、f2的值:f1+=f2;f2+=f1;即可不断求出下2个数。,源程序:#include main()long int f1=1,f2=1;int i;for(i=1;i=10;i+)printf(“%15ld%15ld”,f1,f2);if(i%2=0)printf(“n”);f1+=f2;f2+=f1;,运行结果:1 1 2 3 5 8 13 21 34 55 89 144233 377 610 7871597 2584 4181 6765,定义并初始化数列的头2个数,定义并初始化循环控制变量i,1组2个,10组20个数,输出当前的2个数,输出2次(4个数),换行,计算下2个数,【例5-11】编程统计用09这十个数字可以组成多少无重复的三位数。分析:本题也是采用枚举法来实现,即列举出该问题所有可能的解,并在逐一列举的过程中,检验每个可能解是否是问题的真正解。程序利用for循环控制100-999个数,每个数分解出个位,十位,百位后进行判断。对于所列举的值,既不能遗漏也不能重复。,源程序:#include stdio.hvoid main()int x,a,b,c,num=0;for(x=100;x=999;x+)a=x/100;b=x/10%10;c=x%10;if(a!=b,运行结果:number=648,a,b,c代表百位、十位、个位num存放满足条件的数的个数,注意num要赋初值,将每个三位数分别取出百位、十位、个位,