第4章 循环结构程序设计_第1页
第4章 循环结构程序设计_第2页
第4章 循环结构程序设计_第3页
第4章 循环结构程序设计_第4页
第4章 循环结构程序设计_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第4章循环结构程序设计4.1引例4.2循环控制结构与循环语句4.3几种循环的比较4.4循环嵌套4.5流程控制语句4.6循环程序举例4.1引例【例4.1】编写程序,输入全班30个学生的数学、英语、计算机成绩,计算每位学生的总分和平均分,并输出。

printf("InputMathscore,Englishscore,Computerscore:\n");

scanf("%d%d%d",&MaScore,&EnScore,&CScore);

sum=MaScore+EnScore+CScore;

aver=sum/3.0;

printf("Thesumis%d\nTheaverageis%.1f\n",sum,aver);

i=1; while(i<=30)

{

i++; }#include<stdio.h> intmain(void) { inti,MaScore,EnScore,CScore,sum; floataver;

i=1; //循环变量i赋初值为1

while(i<=30) //当i<=30时执行花括号内的语句

{

printf("InputMathscore,Englishscore,Computerscore:\n");scanf("%d%d%d",&MaScore,&EnScore,&CScore);sum=MaScore+EnScore+CScore; aver=sum/3.0; printf("Thesumis%d\nTheaverageis%.1f\n",sum,aver);

i++; //循环变量i的值加1

} return0; }4.1引例

顺序结构、选择结构和循环结构是用于结构化程序设计的三种基本结构。按照结构化程序设计的观点,任何复杂问题都可用这三种结构编程实现,它们是各种复杂程序设计的基础。4.2循环控制结构与循环语句

C语言提供while、do-while、for三种循环语句来实现循环结构。循环语句在给定条件成立的情况下,重复执行某个程序段,这个被重复执行的程序段称为循环体。

4.2循环控制结构与循环语句

1.while循环

while循环属于当型循环,即当某个给定的条件成立时执行循环体,否则终止循环体的执行。

while语句的一般形式为:

while(表达式)循环体

4.2循环控制结构与循环语句

while循环的执行过程如下:(1)计算循环条件表达式的值;(2)如果循环条件表达式的值为“真”(非0),则执行循环体的语句序列,并返回步骤(1);否则,转(3);(3)循环结束。

例4.1用while语句实现了循环输出,实现的语句为:

i=1; while(i<=30)

{

printf("InputMathscore,Englishscore,Computerscore:\n");scanf("%d%d%d",&MaScore,&EnScore,&CScore)sum=MaScore+EnScore+CScore; aver=sum/3.0; printf("Thesumis%d\nTheaverageis%.1f\n",sum,aver); i++;

}4.2循环控制结构与循环语句

2.do-while循环do-while循环属于直到型循环,先执行循环体,再检查给定的条件是否成立,若成立,继续执行循环体,否则,循环结束。do-while循环的一般形式为:

do

循环体

while(表达式);

4.2循环控制结构与循环语句

do-while的执行过程如下:(1)执行循环体中的语句;(2)计算循环条件表达式的值;(3)如果循环条件表达式的值为“真”(非0),则转(1),否则,转(4);(4)循环结束。用

do-while语句实现例4.1中的循环输出,实现的语句为:

i=1; do {printf("InputMathscore,Englishscore,Computerscore:\n");scanf("%d%d%d",&MaScore,&EnScore,&CScore)sum=MaScore+EnScore+CScore; aver=sum/3.0; printf("Thesumis%d\nTheaverageis%.1f\n",sum,aver);

i++;

}while(i<=30);while和do---while循环的比较#include<stdio.h> intmain(void) { inti; i=1;

while(i<=100) { i=i+1; } printf(”%d\n”,i); return0; }#include<stdio.h> intmain(void) { inti; i=1;

do { i=i+1; }while(i<=100);

printf(”%d\n”,i);

return0; }while和do---while循环的比较#include<stdio.h> intmain(void) { inti; i=101;

while(i<=100) { i=i+1; } printf(”%d\n”,i); return0; }#include<stdio.h> intmain(void) { inti; i=101;

do { i=i+1; }while(i<=100);

printf(”%d\n”,i);

return0; }while和do---while循环的比较比较两种循环的运行结果: 第(1)个程序运行后输出为:101

第(2)个程序运行后输出为:102习题3-4用户输入一元二次方程的系数a、b、c,编程,判断该方程在实数范围内是否有根,并输出其实数根。习题3-5编写一个商场购物打折的程序。计算方法如下:

x x<1000x*0.9 1000≤x<2000y=x*0.8 2000≤x<4000x*0.7 4000≤x<6000x*0.6 x≥6000

要求:(1)用if语句编写程序。 (2)用switch语句编写程序。4.2循环控制结构与循环语句 i=1; while(i<=100){

i++; } i=1; do{

i++; }while(i<=100);4.2循环控制结构与循环语句 i=101; while(i<=100){

i++; } i=101; do{

i++; }while(i<=100);4.2循环控制结构与循环语句for(i=1;i<=100;i++){}

i=1; while(i<=100){

i++; }4.2循环控制结构与循环语句3.for循环

for语句的一般形式为for(表达式1;表达式2;表达式3)

语句设置初始条件,只执行一次。可以为零个、一个或多个变量设置初值执行4.2循环控制结构与循环语句3.for循环

for语句的一般形式为for(表达式1;表达式2;表达式3)

语句循环条件表达式,用来判定是否继续循环。在每次执行循环体前先执行此表达式,决定是否继续执行循环4.2循环控制结构与循环语句3.for循环

for语句的一般形式为for(表达式1;表达式2;表达式3)

语句作为循环的调整器,例如使循环变量增值,它是在执行完循环体后才进行的注意 当循环体只有一条语句时,可以不使用花括号,则for语句的范围直到for后面第一个分号处 for(i=1;i<=30;i++){

printf("%d\n",i);}注意 当循环体只有一条语句时,可以不使用花括号,则for语句的范围直到for后面第一个分号处 for(i=1;i<=30;i++) printf("%d\n",i); printf("%d\n",i);注意 当循环体只有一条语句时,可以不使用花括号,则for语句的范围直到for后面第一个分号处 for(i=1;i<=30;i++);

printf("%d\n",i); printf("%d\n",i);注意 for循环的三个表达式之间的分隔符是分号,有且仅有两个分号,既不能多,也不能少。for(s=0,i=1;i<=100;i++) {s=2*i+1; }逗号表达式intx=3,y;y=(x+3,x-=5,x+6);注意 for循环的三个表达式均可以省略,但两个分号不可少。i=1;for(;i<=100;i++) { printf("%d\t%d\n",i,i*i);

}4.3几种循环的比较【例4.2】编程求累加之和,从键盘输入n,计算=1+2+3+……+n的和,并输出和。【问题分析】S0=0S1=S0+1S2=S1+2….S99=S98+99S100=S99+100Si=Si-1+iS=S+iints=0,i,n;scanf(“%d”,&n);for(i=1;i<=n;i++){

s=s+i;}4.3几种循环的比较【例4.2】编程求累加之和,从键盘输入n,计算=1+2+3+……+n的和,并输出和。ints=0,i,n;scanf(“%d”,&n);for(i=1;i<=n;i++){

s=s+i;}ints=0,i=1,n;scanf(“%d”,&n);while(i<=n){

s=s+i; i=i+1;}4.3几种循环的比较【例4.2】编程求累加之和,从键盘输入n,计算=1+2+3+……+n的和,并输出和。ints=0,i,n;scanf(“%d”,&n);for(i=1;i<=n;i++){

s=s+i;}ints=0,i=1,n;scanf(“%d”,&n);do{

s=s+i; i=i+1;}while(i<=n);思考:1、求1+3+5+…+992、求2+4+6+…+1003、求50+51+…+1004、求ints=0,i,n;scanf(“%d”,&n);for(i=1;i<=n;i++){

s=s+i;}4.3几种循环的比较(1)循环变量初始化:while、do-while在循环前指定;for循环可以在表达式1中指定。 (2)循环判断条件:while、do-while在while后面的括号内指定循环条件;for循环在表达式2中指定循环条件。 (3)循环变量的改变:为了使循环能正常结束,while和do-while应在循环体中包含使循环趋于结束的语句;for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式3中。因此,for语句的功能更强,凡用while循环能完成的,用for循环都能实现。 (4)while、for先判循环条件,后执行;do-while先执行,后判断循环条件。 (5)while、do-while、for循环均可用break语句跳出循环,用continue提前结束本次循环体的执行,而进入下一次循环【例4.3】编程求累乘之积,从键盘输入n,计算n!,并输出。【问题分析】这是一个累乘问题,需要先后将n个数相乘,如果用ti表示前i项之积,那么有如下公式:t0=1t1=t0*1t2=t1*2 =>ti=ti-1*i=> t=t*i…tn=tn-1*n

inti,n;longintt=1;

printf(“请输入n的值:\n”);scanf(“%d”,&n);

for(i=1;i<=n;i++){

t=t*i;}【例4.4】编程,用“欧几里德”算法求两个自然数m和n的最大公约数。【问题分析】“欧几里德”算法又称“辗转相除法”,是求两个自然数的最大公约数的经典算法。它先将m除以n求余数r,并判断余数r是否为0,如果余数r为0,则n就是最大公约数,否则,就辗转赋值(m=n,n=r),再重复相除求余并判断,直到余数r为0为止。例如:mnr(m%n)判断条件(m%n!=0)第1次2496 成立第2次963 成立第3次630 不成立(终止)则3为所求得的最大公约数。

do { r=m%n; m=n;

n=r;

}while(r!=0);

printf("最大公约数为:%d\n",?);

do { r=m%n; m=n;

n=r;

}while(r!=0);

printf("最大公约数为:%d\n",m);

while(n!=0) { r=m%n; m=n;

n=r;

}

printf("最大公约数为:%d\n",m);

while(n!=0) { r=m%n; m=n;

n=r;

}

printf("最大公约数为:%d\n",m);

while(1)

{ r=m%n;

if(r==0)break; m=n; n=r;

} printf("最大公约数为:%d\n",n);

while(1)

{ r=m%n;

if(r==0)break; m=n; n=r;

} printf("最大公约数为:%d\n",n);

4.4循环的嵌套一个循环体内又包含另一个完整的循环结构,称为循环的嵌套内嵌的循环中还可以嵌套循环,这就是多层循环3种循环(while循环、do…while循环和for循环)可以互相嵌套【例4.5】编程,根据输入的边长n(即字符*的个数),输出下列字符图形。如n=5时: ***** ***** ***** ***** ***** for(i=1;i<=n;i++)

{ for(j=1;j<=n;j++)

printf("*"); printf(“\n”);

}

例:

输出以下4*5的矩阵。12345246810369121548121620for(i=1;i<=4;i++){ for(j=1;j<=5;j++)printf(“*"); printf("\n"); }

for(i=1;i<=4;i++){ for(j=1;j<=5;j++)printf(“%d“,i*j); printf("\n"); }

for(i=1;i<=4;i++){ for(j=1;j<=5;j++)printf(“%d“,i*j); printf("\n"); }

for(i=1;i<=4;i++){ for(j=1;j<=5;j++)printf(“%d\t“,i*j); printf("\n"); }

for(i=1;i<=4;i++){ for(j=1;j<=5;j++)printf(“*"); printf("\n");

}

for(i=1;i<=4;i++){ for(j=1;j<=i;j++)printf(“*"); printf("\n");

}

【例4.6】编程,用穷举法解决百钱买百鸡问题:一百个铜钱买了一百只鸡,其中公鸡一只5钱、母鸡一只3钱,小鸡一钱3只,问一百只鸡中公鸡、母鸡、小鸡各多少?【问题分析】这是一个古典数学问题,设一百只鸡中公鸡、母鸡、小鸡分别为x,y,z,则可以得到:

5x+3y+z/3=100x+y+z=100

【例4.6】编程,用穷举法解决百钱买百鸡问题:一百个铜钱买了一百只鸡,其中公鸡一只5钱、母鸡一只3钱,小鸡一钱3只,问一百只鸡中公鸡、母鸡、小鸡各多少?【问题分析】这里x,y,z为正整数,且z是3的倍数;由于鸡和钱的总数都是100,可以确定x,y,z的取值范围:

(1)x的取值范围为1~20(一百钱最多买20只公鸡)

(2)y的取值范围为1~33(一百钱最多买33只母鸡)

(3)z的取值范围为3~99,步长为3(小鸡一买就是3只,且小鸡的数量不能超过总数100)对于这个问题我们可以用穷举的方法,遍历x,y,z的所有可能组合,只要满足“百钱,百鸡”的条件,即可得到问题的解。for(x=1;x<=20;x++){

for(y=1;y<=33;y++)

{

for(z=3;z<=99;z+=3)

{

if((5*x+3*y+z/3==100)

&&(x+y+z==100))printf("公鸡只数:%d,母鸡只数:%d,小鸡只数:%d\n",x,y,z);

}

}}

for(x=1;x<=20;x++){

for(y=1;y<=33;y++)

{

z=100-x-y;

if((5*x+3*y+z/3==100)

&&(z%3==0))printf("公鸡只数:%d,母鸡只数:%d,小鸡只数:%d\n",x,y,z);

}}

4.5流程控制语句

4.5.1用break语句提前终止循环4.5.2用continue语句提前结束本次循环用break语句提前终止循环break语句可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句用break语句提前终止循环【例4.7】某大学生生病,急需手术费8万元,现面向全院2000个学生募捐,当总数达到8万元时就结束,统计此时捐款的人数,以及平均每人捐款的数目。

【问题分析】捐款过程可以用循环来处理,但循环的实际次数事先不能确定,但最多循环2000次,在循环中累计捐款总数,并用if语句检查是否达到8万元,如果达到,就用break终止循环,不再累加,并计算人均捐款数。for(i=1,total=0;i<=2000;i++){ printf("pleaseenteramount:");scanf("%f",&amount);total=total+amount;if(total>=80000)break;

}

if(i>2000) aver=total/2000;elseaver=total/i;printf("num=%d\naver=

%10.2f\n",i,aver);

用continue语句提前结束本次循环有时并不希望终止整个循环的操作,而只希望提前结束本次循环,而接着执行下次循环。这时可以用continue语句用continue语句提前结束本次循环【例4.8】输出1-100之间不能被3整除的数。【问题分析】此题需要对1-100之间的每一个整数检查,如果不能被3整除,就将此数输出,提前进入下一个的检查。如果能被3整除,就不输出此数。无论是否输出此数,都要接着检查下一个数(直到100为止)。 for(n=1;n<=100;n++){ if(n%3==0) {

continue; } printf("%4d",n);

}

for(n=1;n<=100;n++){ if(n%3==0) {

break; } printf("%4d",n);

}

break语句和continue语句的区别continue语句只结束本次循环,而不是终止整个循环的执行break语句结束整个循环过程,不再判断执行循环的条件是否成立4.6循环程序举例【例4.9】编程,从键盘输入n,计算1!+2!+3!+……+n!的值,并输出。【问题分析】此题可结合例4.2(累加求和)和例4.3(累乘求积)的程序,用嵌套循环来实现。其中,外层循环控制变量i的值从1变化到n,以计算从1到n的各个阶乘值的累加求和,而内层循环控制变量j的值从1变化到i,以计算从1到i的累乘结果即阶乘i!。 longs=0,t;

for(i=1;i<=n;i++)

{

t=1; for(j=1;j<=i;j++) { t=t*j;

}

s=s+t;

} longs=0,t=1; for(i=1;i<=n;i++) {

t=t*i;

s=s+t; }【程序分析】在这段程序中,我们根据累加和的前项和后项的关系,利用前项来计算后项,即将累加项表示为“t=t*i;”,因为t只在循环之前初始化过,在第i次循环中,赋值号右侧的t中保留的是上一次累乘的结果,即(i-1)!,再用(i-1)!*i得到的就是i!了。程序只用了单重循环,大大减少了循环的次数,提高了效率。循环体语句“s=s+t;”中s是累加和,t是累加项,就是每次要累加的项。编写累加求和的关键在于寻找累加项的构成规律。(1)当累加的项较为复杂或者前后项之间无关时,需要单独计算每个累加项。(2)而当累加项的前项与后项之间有关时,我们可以根据累加项的后项与前项之间的关系,通过前项来计算后项。如例4.9改进的程序代码就利用了累加项的后项和前项的关系。若ti表示第i项,ti-1表示第i-1项,后项与前项存在如下比例关系:【例4.10】编程,求【问题分析】累加项为,可用数学库函数pow(x,i)来求xi,再除以i就可直接得到累加项的值。 s=0; for(i=1;i<=n;i++) {

t=pow(x,i)/i; s=s+t; } doubles=1,t=1;

i=1; while(fabs(t)>=1e-6)

{

t=t*(-x/i);

s=s+t;

i++; }

intf1=1,f2=1,f,i; printf("%12d%12d",f1,f2); for(i=3;i<=20;i++) { f=f1+f2; printf("%12d",f); if(i%4==0) printf("\n"); f1=f2; f2=f; } 可以改进: intf1=1,f2=1,i; for(i=1;i<=10;i++) { printf("%12d%12d",f1,f2); if(i%2==0)

printf("\n"); f1=f1+f2;

f2=f2+f1; }

【例4.13】编程,输入一个大于3的整数n,判定它是否为素数(prime,又称质数)【问题分析】素数除了1和本身之外,不能被任何数整除。要判断n是否为素数,可采用的算法:使n依次除以i,i=2,3,……,(n-1),用循环实现,在这个循环中,如果n能被当前的i整除,则n不是素数,不需要再判断n是否能被i+1整除了,立即结束循环,此时i<n;如果n不能被当前的i整除,则将i自增1,判断n是否能被下一个i整除。当i的值超过了n-1,表示在[2,n-1]范围内没有找到一个数能整除n,则n为素数。 for(i=2;i<n;i++) { if(n%i==0) break; } if(i<n) printf("%d不是素数\n",n); else printf("%d是素数\n",n);【程序改进】在判断n是否能被i整除时,不必将i的范围设为[2,n-1],只需判断[2,]范围内的整数i是否能整除n即可。例如判断23是否为素数,只要判断23是否能被2,3,4整除,若2,3,4都不能整除23,那么23一定是一个素数。这样就大大减少了循环的次数,提高了执行效率。 for(i=2;i<=sqrt(n);i++) { if(n%i==0) break; } if(i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论