《《循环结构训练》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《循环结构训练》PPT课件.ppt(41页珍藏版)》请在三一办公上搜索。
1、综合训练一 循环结构程序,项目一:图形编程项目二:学生成绩的分组汇总 项目三:其他问题项目四:举一反三,项目一 图形输出,项目要求 给定图形,按照要求格式输出项目分析:分析图形的特点,包括行、列上字符的个数,通过多重循环控制图形的输出,*,使用双重循环实现,思路:,一共有4 行,每行由星号组成:变量 i 控制输出行数,从1变化到4变量 j 控制输出每行的星号:j 从1变化到 4,每次输出一个星号,例1:编程序,输出以下图形,参考代码:,#includestdio.hmain()int i,j;for(i=1;i=4;i+)for(j=1;j=4;j+)printf(*);printf(n);,
2、改写例1:,编程序,输出以下图形。,*,思路:,一共有4 行,每行由星号组成:变量 i 控制输出行数,从1变化到4变量 j 控制输出每行的星号:j 从1变化到 i,每次输出一个星号,参考代码:,main()int i,j;for(i=1;i=4;i+)for(j=1;j=i;j+)printf(*);printf(n);,再次改写例1:,编程序,输出以下图形。,*,思路:,一共有4 行,每行由空格和星号组成:空格数按行增加,星号按行减少变量 i 控制输出行数,从1变化到4变量 j 控制输出每行的空格和星号:j 从1变化到 i,每次输出一个空格 j 从1变化到 8-2*i1,每次输出一个星号,参
3、考算法和程序:,main()int i,j;for(i=1;i=4;i+)for(j=1;j=i;j+)printf();for(j=1;j=8-(2*i-1);j+)printf(*);printf(n);,思考:如何输出10行图形?输出图形向右平移20个字符位置,应如何修改程序?,【反复训练】编程显示如下所示的图形,*,分析:题目要求的三角形由5行组成,因此程序中循环结构的循环次数应为5次,每一次输出一行。而“输出一行”又进一步分为三项工作。(1)输出若干个空格;(2)输出若干个星号;(3)回车换行,为新的一行的输出做准备。现在的问题是,如何确定每一行应输出的空格数和字符”*”的数目,以便
4、分别通过循环来输出这两种字符。,#include main()int i,j;for(i=1;i=5;i+)/一共输出5行 for(j=1;j=6-i;j+)printf();/输出空格数 for(j=1;j=2*i-1;j+)printf(*);/输出”*”的数目 printf(“n”);/换行,项目二 学生成绩的分组汇总,项目要求 一个班中有四个小组,求本学期期中考试中每个小组数学成绩的总分及平均分。,项目分析在一个小组中对学生数学成绩的平均分与总分进行计算;然后就是重复进行4次。所以,将这一项目可分成二个任务:任务一:求一个小组学生成绩的总分及平均分;任务二:求四个小组学生成绩的总分及平
5、均分。,分析:如果本小组一共有十个同学,显然不可能定义十个变量x1,x2,x10,然后在程 序中表示成sum=x1+x2+x3+x10。求一个小组的学生总成绩的步骤就是:先输入第一个学生的成绩,然后将这个成绩加到总分中,接下来,输入第二个学生的成绩,再将第二个学生的成绩加入到总分中,不断重复,直到小组中最后一个同学的成绩输入并加入到总分为止。重复执行就是循环。重复工作是计算机特别擅长的工作之一。,任务1 求一个小组学生成绩的总分及平均分,一、问题情景 一个班进行了一次考试,现要输入第一小组学生的成绩,计算这一小组的总分与平均分,并按要求输出。,二、具体实现#include stdio.hmai
6、n()int score,i,sum=0;float avg;i=1;printf(请输入本小组10个学生的成绩:);while(i=10)scanf(%d,while(i=10)scanf(“%d”,任务情景中的程序及流程图,#include stdio.hmain()int score,i,sum=0;float avg;i=1;printf(请输入本小组10个学生的成绩:);while(i=10)scanf(%d,While实例练习,【例2】本学期期末考试进行了三门课程的测试。成绩单下来后,8个室友兄弟要一比高低,这就要得到每个人三门课程的总分和平均分,用C语言实现之。,分析:(1)定义
7、五个实型变量x,y,z,s和avg,依次放每一名学生的三门课程成绩、这三门课程的总成绩和平均分;(2)每次取出一名学生的三门课程成绩,依次给x,y,z,然后再一起放到s中,就可以得到该同学的三门课的总分和平均分。(3)以上步骤重复执行8次。,#include stdio.hmain()int i;float x,y,z,sum,avg;i=1;while(i=8)printf(请输入第%d个同学三门课的成绩,i);scanf(%f%f%f,求一个小组学生成绩的总分及平均分的程序可改写为:,#include stdio.hmain()int score,i,sum=0;float avg;i=1
8、;printf(请输入本小组10个学生的成绩:);do scanf(%d,将例2用do while语句来改进实现。,求8个室友兄弟每个人三门课程的总分和平均分#include stdio.hmain()int i;float x,y,z,sum,avg;i=1;do printf(请输入第%d个同学三门课的成绩,i);scanf(%f%f%f,求一个小组学生成绩的总分及平均分的程序可改写为:,#include stdio.hmain()int score,i,sum=0;float avg;printf(请输入本小组10个学生的成绩:);for(i=1;i=10;i+)scanf(%d,for
9、的进一步练习,用for语句来改进实现例2。(求八位室友每个人三门课的总分及平均分)#include stdio.hmain()int i;float x,y,z,sum,avg;for(i=1;i=8;i+)printf(请输入第%d个同学三门课的成绩,i);scanf(%f%f%f,任务 2 求每个小组学生成绩的总分及平均分,一、问题情景 一个班进行了一次考试,现要输入全班四个小组的学生成绩,计算每一小组的总分与平均分,并按要求输出。,分析,在任务1中,所解决的问题是:一个小组学生成绩的总分及平均分。若现在一个班中有四个小组,现求每个小组的学生成绩的总分及平均分。也就是将任务1重复进行四次,
10、显然写四段程序是不科学的,科学的方法是再嵌套一个循环。,具体实现:#include stdio.hmain()int score,i,j=1,sum;float avg;while(j=4)sum=0;i=1;printf(请输入第%d小组学生成绩:,j);while(i=10)scanf(%d,/下一个小组,程序运行结果,一个循环体内又包含另一个完整的循环体,称为循环的嵌套,与if的嵌套相同,内嵌的循环中还可以嵌套循环,这就是多层循环。内层的优先级比外层的高,只有内层的执行完才能执行外层的,循环嵌套的要领对各种语言都是一样的。三种循环(while循环、dowhile循环、for循环)可以互相
11、嵌套。,本任务用do while循环嵌套do while循环的程序解决:,#include stdio.hmain()int score,i,sum;float avg;int j=1;do sum=0;i=1;printf(请输入第%d小组学生成绩:,j);do scanf(%d,黄色的循环包含在玫瑰色的循环中,本任务用for循环嵌套for循环:,#include stdio.hmain()int score,i,sum;float avg;int j=1;for(;j=4;j+)sum=0;printf(请输入第%d小组学生成绩:,j);for(i=1;i=10;i+)scanf(%d,黄
12、色的循环包含在玫瑰色的循环中,本任务while循环嵌套do while循环,#include stdio.hmain()int score,i,sum;float avg;int j=1;while(j=4)sum=0;printf(请输入第%d小组学生成绩:,j);i=1;do scanf(%d,黄色的循环包含在玫瑰色的循环中,思考:用for循环嵌套while循环、do while循环嵌套for循环编程解决任务2。,项目三:其他问题,例如:百钱买百鸡、水仙花、求素数,【例3】将1100之间不能被3整除的数输出。,分析:定义变量i其初值为1,验证1是否能被3整除?若不能整除,则输出i,然后将i
13、累加到2,再次验证2是否被被3整除?若不能整除,则输出i,这样一直重复,直到i值100。,#include main()int i;i=1;while(i=100)if(i%3!=0)printf(“%3d”,i);i+;,程序如下,将【例3】用for语句来改进实现,将1100之间不能被3整除的数输出。#include main()int i;for(i=1;i=100;i+)if(i%3!=0)printf(“%3d”,i);,将【例3】用do while语句来改进实现。,将1100之间不能被3整除的数输出。#include main()int i;i=1;do if(i%3!=0)prin
14、tf(“%3d”,i);i+;while(i=100);,【例4】编程实现百钱买百鸡,有一老大爷去集贸市场买鸡,他想用100元钱买100只鸡,而且要求所买的鸡有公鸡、母鸡、小鸡。已知公鸡2元一只,母鸡3元一只,小鸡0.5元一只。问老大爷要买多少只公鸡、母鸡、小鸡恰好花去100元钱,并且买到100只鸡?,分析,x+y+z=100 x+3y+0.5z=100,y=1.5z-100 x=200-2.5z,假设公鸡买x只,母鸡买y只,小鸡买z只,则由题意可得:,(1)当z=2时,计算y与x的值(2)当z=4时,计算y与x的值(3)当z=8时,计算y与x的值(4)一直计算到z=98时,计算y与x的值显然
15、,如果x,y的值都大于零,则输出x,y,z。所以用for循环的程序 如左:,#include main()int x,y,z;for(z=2;z0,用双循环实现【例4】的百钱买百鸡。,分析:假设公鸡买x只,母鸡买y只,小鸡买z只,则:(1)y可以是1、2、333的一个值。(2)x可以是1、2、350的一个值。(3)然后由y及x,显然可解得z=100-x-y。(4)如果所花的钱刚好是100,则输出x,y,z。,程序如下:#include main()int x,y,z;for(x=1;x=50;x+)for(y=1;y=33;y+)z=100-x-y;if(2*x+3*y+0.5*z=100)p
16、rintf(“公鸡数为%d,母鸡数为%d,小鸡数为%dn,x,y,z);,【例5】输入二个正整数,求它们的最大公约数,分析,(1)若输入二个正整数分别为a,b,它的最大公约数为k,k的值应小于等于a,b中的一个相对小数;(2)然后进行a%k及b%k的运算,若它们的余数为零,则k就是最大公约数。(3)若a%k及b%k中至少有一个的余数不为零,则k=k-1,然后再执行(2)。,#include main()int a,b,k;printf(请输入二个正整数);scanf(%d%d,程序的运行结果为:请输入二个正整数5 6最大公约数为1,【例6】判断素数,【例5】在数学课上,李老师要同学们对给定的任
17、意正整数进行判断,看是否为素数,这个数学问题,用C语言该如何解决?,分析:因为素数只能被1及本身整除,所以判断一个大于2的正整数x是否为素数,就让x按顺序除以i=2、3、x-1,若x能被它们中的任一个除尽,就可跳出循环。因为此数一定不是素数。所以判断x是不是素数,就可以用i的值来衡量,若i=x,则x一定是素数,否则就不是素数。,#include main()int i,x;printf(请输入一个正整数);scanf(%d,【例7】显示如下的下三角九九乘法表,12 43 6 94 8 12 165 10 15 20 256 12 18 24 30 367 14 21 28 35 42 498
18、16 24 32 40 48 56 649 18 27 36 45 54 63 72 81,分析:该乘法表要列出11,21,22,31,32,33,99的值,乘数的范围是19,针对每一个乘数,被乘数的范围是1到它本身,因此可以用两重循环解决问题。按乘数组织外层循环,i表示从19;按被乘数组织内层循环,j表示从1i,从而确定每一行输出的内容。,#include main()int i,j;for(i=1;i=9;i+)for(j=1;j=i;j+)printf(%-5d,i*j);printf(n);,相关知识,(一)常见的循环嵌套1.while循环嵌套while循环while()while()
19、2.do while循环嵌套do while循环 do do while();while();3.for循环嵌套for循环 for(;)for(;),4.while循环嵌套do while循环 while()do while();5.for循环嵌套while循环 for(;)while()6.do while循环嵌套for循环 do for(;)while();,项目四 举一反三,【例8】程序功能:运行时输入10个数,然后分别输出其中的最大值、最小值。,分析:(1)输入第一个数x,并假定第一个数既是十个数中的最大值max,也是十个数中的最小值min;(2)然后输入下一个数x,将最大值max及最
20、小数min与x分别相比,若max小于x,则max=x;若min大于x,则min=x;(3)不断重复步骤(2),直到第10个数比完为止;类似10个壮士打擂台,第一个壮士先上场,认为自已是“老大”,然后第二个壮士再上场,与前面的“老大”比武,赢者才是真的“老大”,一直到第十个壮士比完为止。,#include void main()float x,max,min;int i;printf(请输入十个同学的成绩:);for(i=1;imax)max=x;if(xmin)min=x;printf(最高分为%.1f,最低分为%.1fn,max,min);,在if语句中比较两个数相等是“=”符号,而不是数学
21、中的“=”符号,在C语言中“=”是赋值号。,【例9】程序功能:运行时输入整数n,输出n各位数字之和。(例如:n=1234,则输出10,n=-123,则输出6。,分析:若n的值为2345,则(1)个位数的取法是:(2)十位数的数字取法是:(3)百位数的数字的取法:(4)同理,要取得千位数的数字:,通过n%10就能获取个位数字“5”,如果能将2345化为234,则就能轻松地取到4,所以执行n=2345/10,再执行n=n%10就行,执行234/10,即n=n/10,新的n的值将成为23,然后再执行n%10就可获取数字“3”;,同理,要取得千位数的数字,只要执行23/10,即n=n/10,新的n的值
22、将成为2,然后再执行n%10就可获取“2”;,总结以上各步骤,可以发现,对任意的一个数n,执行n%10,再执行n=n/10,然后不断的重复,就可以一个一个获取个位数字、十位数字、百位数字,所以可以用循环去执行以上的步骤,但是循环几次呢?仔细分析不难发现,经过若干次的执行n=n/10,则新的n的值肯定会成为0,所以可以得出结论:循环条件是n!=0。,程序的流程图为:,#include#include void main()int n,s=0;printf(请输入一个数:);scanf(%d,【例10】编程求:s=3+33+333+3333+33333+333333+3333333+3333333
23、3,分析:可以将本题化为:s=3(1+11+111+1111+11111+111111+1111111+11111111),所以只要求出了s=1+11+111+1111+11111+111111+1111111+11111111,然后再执行s=s*3,就能达到题目的要求。而s=1+11+111+1111+11111+111111+1111111+11111111是一道累加题,只要执行8次的s=s+t即可,只不过第一次循环中的t是1,第二次是11,第三次是111,分析后项与前项的关系是:前项的10倍加1等于后项,即t=10*t+1,t=0;for(i=1;i=8;i+)t=10*t+1;s=s+
24、t;,#include void main()int i,t=0;long s=0;for(i=1;i=8;i+)t=t*10+1;s=s+t;s=s*3;printf(3+33+333+3333+33333+333333+3333333+33333333=%ldn,s);,分析:(1)首先认为最大值是当x=1时的函数值,即max=1*1-5*1+sin(1);(2)然后计算出x=2时的f(x)与前面的max相比,如果maxf(x),则max=f(x)(3)将x=3,4,.10不断重复步骤(2);(4)输出max。,【例10】对x=1,2,3,10,求f(x)=x*x-5*x+sin(x)的最
25、大值,#include#include void main()int x;float max;max=1*1-5*1+sin(1);for(x=2;x=10;x+)if(maxx*x-5*x+sin(x)max=x*x-5*x+sin(x);printf(%fn,max);,【例11】编程找出100999之间所有的水仙花数,分析:本题的编程思路是用枚举法:即对100999之间的每一个数,取出它的百位数a,十位数b,个位数c,如果a*a*a+b*b*b+c*c*c的值等于它自身,则输出这个数。显然a=i/100,b=(i-a*100)/10;c=i-a*100-b*10;,#include#in
26、cludevoid main()int i,a,b,c;for(i=100;i=999;i+)a=i/100;b=(i-a*100)/10;c=i-a*100-b*10;if(i=a*a*a+b*b*b+c*c*c)printf(%d is a Armstrong number!n,i);,分析:因为要计算前30项之和,可以用一个循环:(1)将a累加到s中,然后新的a变为sqrt(a);(2)重复多次(1)即可;当前30项的和算完后,则输出。,【例12】数列第一项为81,此后各项均为它前1项的正平方根,统计该数列前30项之和。,#include#include void main()float
27、 s=0,a=81,i;for(i=1;i=30;i+)s=s+a;a=sqrt(a);printf(“%fn”,s);,运行结果:121.335854,分析:用一个循环,将每一项累加到一个变量中,因为它需要有效位数保留10位,所以要定义一个双精度型变量。,【例13】编写程序,完成以下功能:计算2的平方根、3的平方根、10的平方根之和,要求计算结果具有小数点后10位有效位数。,#include#include void main()int i;double s=0;for(i=2;i=10;i+)s+=sqrt(i);printf(%.10lfn,s);,程序的运行结果为:21.4682878
28、1868,【例14】a、b、c为区间1,100的整数,统计使等式 c/(a*a+b*b)=1成立的所有解的个数,(若a=1、b=3、c=10是1个解,则a=3、b=1、c=10 也是解),#include void main()int n=0,a,b,c;for(a=1;a=100;a+)for(b=1;b=100;b+)for(c=1;c=100;c+)if(a*a+b*b)=c)n+=1;/注意:不要写成c/(a*a+b*b)=1 printf(%d,n);,程序的运行结果为:69,【例15】韩信点兵:相传汉高祖刘邦问大将军韩信现在统御兵士多少,韩信答,每3人一列余1人、5人一列余2人、7
29、人一列余4人、13人一列余6人、17人一列余2人、19人一列余10人。刘邦茫然而不知其数。你呢?你是一位优秀的程序员,请你帮刘邦解决这一问题,韩信至少统御了多少兵士。,分析:这道题的本质就是;“一个正整数,被3除时余1,被5除时余2,被7除时余4,被13除时余6,被17除时余2,被19除时余10,求这个数。”所以,我们可以从最小自然数出发,一个一个地累加,如果它满足条件,则退出循环。,#include void main()long i;for(i=1;i+)if(i%3=2,程序运行结果为:韩信统领的兵数有:131072,思考:,现在你对循环结构掌握的怎样?多读多写,把C当做你的朋友,他也会将你当做朋友!加油!,