第5章 C语言循环结构_第1页
第5章 C语言循环结构_第2页
第5章 C语言循环结构_第3页
第5章 C语言循环结构_第4页
第5章 C语言循环结构_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

第5章循环结构程序设计循环结构概述

goto语句及用goto语句构成循环三种循环while、do-while、for

循环的嵌套几种循环的比较Break语句和continue语句应用举例5.0

循环结构导入在程序设计中含有循环结构的问题是大量存在的

对输入的10个整数求和,怎么编程?

对输入的100个整数求和,怎么编程?以上问题可以引出一个概念“循环”,简单而言:循环就是不断反复地执行同一段程序。C语言可实现的循环:用goto

和if构成循环while语句do~while语句for语句不提倡当型循环——先判断后执行直到型循环——先执行后判断多功能goto语句及用goto语句构成循环一般形式:语句标号:语句

….…..

goto

语句标号;1.功能是无条件转到语句标号处。2.用途:与if语句一起构成循环结构;从循环体中跳到循环体外。3.因为滥用goto语句会破坏结构化,所以应限制使用。说明:语句标号:1.用于定义程序中的某个位置。2.用标识符表示,开头不能是数字。如:goto3t;错误

gotot3;正确3.只能加在可执行语句前面。goto语句及用goto语句构成循环用if语句和goto语句构成循环例1

计算#include<stdio.h>main(){inti,sum=0;i=1;loop:if(i<=100){sum+=i; i++;

gotoloop;}

printf("%d",sum);}sum=sum+1=1sum=sum+2=3sum=sum+3=6sum=sum+4=10……sum=sum+100=5050循环初值循环终值循环变量增值循环条件循环体分析:这是一个累加求和的问题sum=1+2+3+…+100

用while语句实现当型循环表达式循环体当表达式的值为真(非0)时,执行其中的内嵌语句(循环体),然后回过头来再判断表达式的值,如此重复;当表达式为假(0)时结束循环。5.1while语句一般形式:while(表达式)

循环体语句表达式循环体假(0)真(非0)执行过程:先判断表达式,后执行循环体。循环控制表达式循环控制变量循环体注意:

循环体有可能一次也不执行。循环前,必须给循环控制变量赋初值。若循环体包含一条以上的语句,应以复合语句形式出现。循环体中,必须有改变循环控制变量值的语句(使循环趋向结束的语句)。

无限循环:while(1)循环体;循环体为空如:

while((c=getchar())!='A');从键盘输入字符直到输入A为止等价于:c=getchar();while(c!='A')c=getchar();5.1while语句一般形式:while(表达式)

循环体语句例如:k=1;s=0;while(k<=100){s=s+k;k++;}分析:累加求和的问题

s=1+2+3+…+100s=0s=s+1s=s+2s=s+3……和的新值s=s+k和的当前值求和项当前值例1用while语句计算#include<stdio.h>main(){intk,s;s=0;k=1;while(k<=100){s=s+k;k++;}

printf("s=%d",s);}注意:s、k的初值及位置s=0,k=1当k≤100

s=s+kk=k+1用do-while语句实现直到型循环执行循环体,当表达式的值为真(非0)时,再次执行循环体,如此重复;当表达式为假(0)时结束循环。5.2do-while语句一般形式:do

循环体语句while(表达式);表达式循环体假(0)真(非0)执行过程:先执行循环体,后判断表达式。循环体至少执行一次。do-while语句可转化成while语句。表达式循环体;不可省略!切记!!例1用do-while语句计算#include<stdio.h>main(){intk,s;s=0;k=1;

while(k<=100){s=s+k;k++;}

printf("s=%d",s);}#include<stdio.h>main(){intk,s;s=0;k=1;

do{s=s+k;k++;}while(k<=100);

printf("s=%d",s);}s=0,k=1s=s+kk=k+1

当k<=100先判后做先做后判适合于循环次数确定或不定5.3for语句一般形式:执行过程:for(表达式1;表达式2;表达式3)

循环体语句求解表达式1循环体语句求解表达式3下一语句表达式2真(非0)假(0)说明:表达式1在进入循环之前求解(循环变量赋初值)for语句可转化成while语句。5.3for语句最简单的应用形式:for(循环变量赋初值;循环条件;循环变量增值)

循环体语句例如:for(i=1;i<=100;i++)sum+=i;一般形式:for(表达式1;表达式2;表达式3)

循环体语句for(表达式1;表达式2;表达式3)

循环体语句这个分号不能移走表达式1表达式3可以移到循环体语句的后边这个分号不能丢掉表达式2为空,则不判断循环条件,成无限循环{

表达式3;}for循环的其他形式:1.表达式1省略时,应在for前给循环变量赋初值。如:k=1;

for(;k<=3;k++)s=s+k;2.表达式2省略时,不判断循环条件,将成为“死循环”,需要在循环体中引入break语句以退出循环3.表达式3省略时,循环体内应有使循环条件改变的语句。如:for(k=1;k<=3;)

{s=s+k;

k++;}for循环的说明:4.同时省略表达式1和表达式3,只有表达式2,此时相当于while语句。如k=1;for(;k<=100;){s=s+k;k++;}k=1;while(k<=100){s=s+k;k++;}for循环的说明:5.表达式2一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值不等于0就执行循环体。如:for(k=1;k-4;k++)s=s+k;

仅当k的值等于4时终止循环。k-4是数值表达式。例1用for语句计算#include<stdio.h>main(){intk,s;s=0;k=1;

while(k<=100){s=s+k;k++;}

printf("s=%d",s);}#include<stdio.h>main(){intk,s;s=0;k=1;

do{s=s+k;k++;}while(k<=100);

printf("s=%d",s);}先判后做先做后判#include<stdio.h>main(){intk,s;s=0;for(k=1;k<=100;k++)s=s+k;

printf("s=%d",s);}5.43种循环的比较while(表达式)

循环体语句do

循环体语句while(表达式);for(表达式1;表达式2;表达式3;)

循环体语句循环控制条件也可在循环体内改变循环控制变量值关于循环的控制:循环控制变量初始化也可在for前5.43种循环的比较3.一种循环可以解决的问题,使用另外两种同样可行,只是方便程度不同。4.while循环一般用于循环次数不定的情况,for循环一般用于循环次数确定的情况(也可以用于循环次数不定的情况),do-while循环一般用于至少需要执行一次的情况。5.for循环和while循环是先判断条件是否为真,再执行循环体,因此,可出现循环一次也不执行的情况;do-while循环是先执行循环体,再判断条件是否为真,因此,循环体至少执行一次。6.while循环、do-while循环、for循环,可以用break语句跳出循环,用continue语句结束本次循环。5.43种循环的嵌套1.一个循环体内包含着另一个完整的循环结构,就称为嵌套循环。2.内嵌的循环中又可以嵌套循环,从而构成多重循环。3.三种循环可以相互嵌套。下面几种都是合法的嵌套形式:(1)while(){……

while(){……}…...}(4)while(){……

do{……}while();…….}(5)for(;;){……

while(){……}…...}(3)for(){……

for(;;){……}…….}(6)do{……

for(;;){……}…...}while();(2)do{……

do{……}while();…...}while();1.嵌套的循环控制变量不应同名,以免造成混乱。2.内循环变化快,外循环变化慢。例如:for(i=1;i<=9;i++){for(j=1;j<=i;j++)printf("%1d*%1d=%2d",i,j,i*j);

printf("\n");}3.正确确定循环体。4.循环控制变量与求解的问题挂钩。循环嵌套的说明:分析:用三重循环的循环控制变量分别表示百位数、十位数和个位数百位数i取值1~2十位数j取值0~9个位数k取值2~9n=100*i+10*j+km=100*k+10*j+i若m>2*n并m<3*n则n为满足条件的三位数例2

试找出满足下列条件的所有的三位数

①其百位数不大于2;

②若将个位与百位对换,得到的三位数是原三位数的两倍多。main(){inti,j,k,n,m,s=0;for(i=1;i<=2;i++)for(j=0;j<=9;j++)for(k=2;k<=9;k++){n=100*i+10*j+k;m=100*k+10*j+i;

if(m>2*n&&m<3*n) {s++;

printf("%d",n);if(s%10==0)printf("\n");}}}例2

试找出满足下列条件的所有的三位数

①其百位数不大于2;

②若将个位与百位对换,得到的三位数是原三位数的两倍多。分析:用一重循环的循环控制变量i表示原来的三位数i=101~299百位数n1=i/100十位数n2=(i-n1*100)/10个位数n3=i-100*n1-10*n2m=100*n3+10*n2+n1若m>2*i并m<3*i则i为满足条件的三位数main(){inti,n1,n2,n3,m,s=0;for(i=101;i<=299;i++){n1=i/100;n2=(i-n1*100)/10;n3=i-100*n1-10*n2;m=100*n3+10*n2+n1;

if(m>2*i&&m<3*i){s++;

printf("%d",i);if(s%10==0)printf("\n");}}}5.5break语句和continue语句break语句:break;功能:跳出switch结构;在循环语句中,终止并跳出循环体。说明:break只能终止并跳出最近一层的结构。break不能用于循环语句和switch语句之外的任何其它语句之中。例3

计算r=1到r=10的圆面积,直到面积大于100时停止。#definePI3.1415main(){

intr;floatarea;for(r=1;r<=10;r++){area=PI*r*r;

if(area>100)break;

printf("r=%d,area=%.2f\n",r,area);}}运行结果:r=1,area=3.14r=2,area=12.57r=3,area=28.27r=4,area=50.26r=5,area=78.545.5break语句和continue语句continue语句:continue;功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断。说明:continue仅用于循环语句中。例4

把100~200之间不能被3整除的数输出。main(){

intn;for(n=100;n<=200;n++){if(n%3==0)continue;

printf("%d",n);}}结束本次循环,循环体的剩余语句被忽略,执行表达式3,进入下一循环。continue总是作if的内嵌语句。此法更佳if(n%3)printf("%d",n);5.6应用举例例5用以下公式计算л的值,直到最后一项的绝对值小于1e-6为止。分析:

分子s:1,-1,1,-1…

分母n:1,3,5,7,...1.每项的分母,等于前一项分母加2,用n=n+2实现,n的初值为1。2.每项的符号交替变化,用s=-s实现,s的初值为+1(第一项为正)。3.根据上述,每一项的值t=s/n,第一项的值为1。t=1,pi=0,n=1.0,s=1当|t|1e-6pi=pi+tn=n+2s=-st=s/npi=pi*4输出pi5.6应用举例例5用以下公式计算л的值,直到最后一项的绝对值小于1e-6为止。t=1,pi=0,n=1.0,s=1当|t|1e-6pi=pi+tn=n+2s=-st=s/npi=pi*4输出pi#include<math.h>main(){ints=1;floatn,t,pi;t=1.0;n=1.0;pi=0.0;while(fabs(t)>=1e-6){pi=pi+t;n=n+2;s=-s;t=s/n;}pi=pi*4;

printf("pi=%10.6f\n",pi);}例6求Fibonacci数列:1,1,2,3,5,8,…的前40项。递推公式:分析:1.每次计算并输出两项f1,f2

,共进行20次循环;2.输出f1,f2后,计算得到新的f1,f2:

f1=f1+f2f2=f2+f1--------迭代算法3.此数列增长很快,输出宜用长整型(%ld),每行输出四个数,即每输出4个数后输出一个换行符(\n)。f1=1,f2=1fori=1to20输出f1,f2f1=f1+f2f2=f2+f1例6求Fibonacci数列:1,1,2,3,5,8,…的前40项。递推公式:f1=1,f2=1fori=1to20输出f1,f2f1=f1+f2f2=f2+f1main(){longintf1,f2;

inti;f1=1;f2=1;for(i=1;i<=20;i++){printf("%12ld%12ld",f1,f2);if(i%2==0)printf("\n");

f1=f1+f2;f2=f2+f1;}}例6求Fibonacci数列:1,1,2,3,5,8,…的前40项。递推公式:1534233159710946750255142293524578241578171855377258417711121393832040570288739088169213896104181286571964181346269922746563245986321144987676546368317811217830914930352102334155例7搬砖问题:36块砖36人搬,男搬4女搬3、小孩两个抬1砖,要求一次全搬完,问男、女、小孩各若干?分析:设男人、女人、小孩人数各为men,women,children,则可得如下方程:

4*men+3*women+children/2=36men+women+children=36下面考虑如何寻找另外的约束条件:按常识,men、women、children都应为正整数,且它们的取值范围分别应为:

men:0~8(假设36块砖全由men搬,最多需8人)

women:0~11(假设36块砖全由women搬,最多需11人)

children:0~36(假设36块砖全由children搬,最多为36人)穷举算法例7搬砖问题:36块砖36人搬,男搬4女搬3、小孩两个抬1砖,要求一次全搬完,问男、女、小孩各若干?本题的细化过程如下:首先从1开始,列举men的各个可能值,在每个men值下找满足两个方程的一组解。算法如下:for(men=1;men<=8;men++){s1:找满足两个方程的解的women,childrens2:输出一组解}下面进一步用细化法来表现S1:for(women=1;women<=11;women++)

{s1.1找满足方程的一个childrens1.2输出一组解}例7搬砖问题:36块砖36人搬,男搬4女搬3、小孩两个抬1砖,要求一次全搬完,问男、女、小孩各若干?由于每个men与每个women都可以按下式

children=36-men-women求出一个children。因此,只要该children满足另一个方程

4*men+3*women+childs/2=36便可以得到一组满足题意的解men、women、children。故S1.1与S1.2可以写为:

children=36-men-women;if(4*men+3*women+children/2==36)

printf("%d%d%d\n",men,women,children);例7搬砖问题:36块砖36人搬,男搬4女搬3、小孩两个抬1砖,要求一次全搬完,问男、女、小孩各若干?main(){intmen,women,children;

printf("\nmen***women***children\n");

for(men=1;men<=8;men++){for(women=1;women<=11;women++)

{children=36-men-women;if(4*men+3*women+children/2==36){printf("%d******",men);

printf("%d******",women);

printf("%d******\n",children);}}}}例7搬砖问题:36块砖36人搬,男搬4女搬3、小孩两个抬1砖,要求一次全搬完,问男、女、小孩各若干?运行结果men***women***children1******6******29******(这是一组错误解)3******3******30******原因:丢失重要条件:children应该能够被2整除。修改如下:

if(4*men+3*women+children/2.0==36)

if(children%2==0&&4*men+3*women+children/2==36)

例7判断正整数m是否为素数。什么是素数----只能被自身和1整除的自然数。判断方法----让m依次被2,3,4,…,

除,如果m能被其中的任何一个整数整除,则不是素数。#include<math.h>main(){intm,i,k;

printf("\nInputm:\n");

scanf("%d",&m);k=sqrt(m);for(i=2;i<=k;i++)if(m%i==0)break;if(i>k)printf("%disaprime\n",m);elseprintf("%disnotaprime\n",m);}读入mk=sqrt(m)for(i=2;i<=k;i++)m被i整除真假用break结束循环i>k真假输出:m是素数输出:m不是素数定义变量m,i,k例8求100~200之间的全部素数。在上题的基础上,外层增加一个嵌套的for循环即可。用n作素数个数的计数,以控制每行输出10个数。#include<math.h>main(){intm,i,k;

printf("\nInputm:\n");

scanf("%d",&m);k=sqrt(m);for(i=2;i<=k;i++)if(m%i==0)break;if(i>k)printf("%disaprime\n",m);elseprintf("%disnotaprime\n",m);}

增加intn=0;

for(m=101;m<=200;m+=2)

删除此行

删除此行#include<math.h>main(){intm,i,k,n=0;for(m=101;m<=200;m+=2){k=sqrt(m);for(i=2;i<=k;i++)if(m%i==0)break;

if(i>k){printf("%4d",m);n=n+1;if(n%10==0)printf("\n");}

}}

改最后2行main(){introw;

for(row=1;row<=5;row++)

printf("********\n");}分析:1.图形每行的起始位置相同。2.每行的字符数相同。3.用一重循环控制输出行数即可。分析:1.每行的起始位置不同,空格数递减1。2.每行的字符数相同。3.用二重循环实现:

外循环控制输出行数;内循环控制输出的空格数。introw,col;替换为例9打印图形。{for(col=1;col<=5-row;col++)

printf("");

printf("********\n");}替换为main(){introw,col;

for(row=1;row<=5;row++)

{for(col=1;col<=5-row;col++)printf("");

printf("********\n");}}分析:1.每行的起始位置不同,空格数:5-row2.每行的字符数不同,字符数:2*row-13.用二重循环实现:

外循环控制输出行数;

两个并列内循环控制输出每行的空格数和字符数例9打印图形。请思考:若起始位置为20,程序如何修改?main(){introw,col;

for(row=1;row<=5;row++)

{for(col=1;col<=5-row;col++)printf("");for(col=1;col<=2*row-1;col++)pr

温馨提示

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

评论

0/150

提交评论