《C语言程序设计教程》HuanghuaiUniversityDepartmentofComputerScience主讲:傅丰黄淮学院计算机科学系高等教育出版社谭浩强张基温等编著第三章C程序的流程设计•§1算法•§2C语句概述•§3选择结构程序设计–§3.1双分支结构(if-else)–§3.1~3.2多分支结构(elseif、switch)•§4循环结构程序设计2学时2学时本节4学时§4循环结构程序一、while和do-while语句while(条件)循环体;do循环体;while(条件);1、若循环体为多条语句,应用{}括起来构成复合语句。2、循环体中应有使循环结束的语句,否则会出现死循环。说明循环结构while()…语句do…while()语句for()…语句当(条件)成立时循环体当(条件)成立时循环体条件为真(非0即真)时,执行循环体;然后再判断条件,为真时再执行循环体,直到条件为假时结束循环语句,执行后续语句。先执行循环体,再判断条件。为真则执行循环体,然后再判断条件,为真时再执行循环体,直到条件为假时结束循环,执行后续语句。先判断后执行先执行后判断条件循环体NY条件循环体NYP98习题10:main(){intn=0;while(n++=1)printf(“%d\t”,n);printf(“%d\n”,n);}n=0+1n=1+12=1不成立输出n的值输出n的值输出n的值n1230=1成立n=2+11=1成立n=00123循环体为多个语句时要用{}括起来应在条件表达式或循环体中改变条件表达式的值,否则会出现死循环。2次输出n的值P98习题10用do-while实现的对比:main(){intn=0;doprintf(“%d\t”,n);while(n++=1);printf(“%d\n”,n);}n=0+1n=1+12=1不成立输出n的值输出n的值输出n的值n0130=1成立n=2+11=1成立n=0012323次P83例14~16:main(){intnumber=0;while(number=1){number++;printf(“%d\n”,number);}}main(){intnumber=0;while(number++=1)printf(“*%d\n”,number);printf(“**%d\n”,number);}#include“stdio.h”main(){intc;while((c=getchar())!=EOF)putchar(c);}main(){intc;c=getchar();while(c!=EOF);{putchar(c);c=getchar();}}eehh^z*1*2**312EOF为符号常数,在stdio.h中定义:#defineEOF–1(当键盘输入^Z或遇到文件结束标志时,其值为-1)141516类似P98习题10(1)1+3+5+…+99(2)2+4+6+…+100(3)1-2+3-4+…+99-100(4)(5)#include“stdio.h”voidwait_a_char(charc){charch;while((ch=getchar())!=c);return();}P83例17:口令检查函数将循环体合并到了条件表达式中P12例6:求1+2+3+…+10n131211!1!31!211nmain(){ints=0,i=1;while(i=10){s=s+i;i=i+1;}printf(“s=%d\n”,s);}课后练习main(){ints=0,i=1;do{s=s+i;i=i+1;}while(i=10);printf(“s=%d\n”,s);}P85例18:搬砖问题。main(){intx=0,y,z;while(x=8){y=0;while(y=11){z=36-x-y;if(4*x+3*y+z/2==36){printf(“men:%d”,x);printf(“women:%d”,y);printf(“children:%d\n”,z);}y++;}x++;}}36块砖,36人搬;男搬4,女搬3,两个小孩抬一砖。要求一次搬完,问男、女、小孩各若干?穷举法设男、女、小孩各为x、y、z人,则:4x+3y+z/2=36x+y+z=36可得:0≤x90≤y122≤z≤36算法分析:在某一范围内逐个验证是否满足要求的方法称为穷举法P99习题7:百马百担问题P99习题6:换零钱问题P99习题8:客票问题P99习题9:验证欧拉公式类似问题:若问有几种解决方法,则应如何修改程序?用变量k作为计数器,在if语句中增加“k++;”语句P87例19:爱因斯坦阶梯问题。设有一阶梯,每步跨2阶,最后余1阶;每步跨3阶,最后余2阶;每步跨5阶,最后余4阶;每步跨6阶,最后余5阶;每步跨7阶,正好到阶梯顶。问共有多少阶梯?穷举法设共有x个台阶,则:①x%2==1②x%3==2③x%5==4④x%6==5⑤x%7==0算法分析:X是奇数X是7的倍数X:7,7+7,7+7+7,7+7+7+7,7+7+7+7+7…X:7,7+14,7+14+14…哪个X满足②③④?要逐个验证当②③④中有一者不满足时,便验证X的下一个值是否满足main(){intx=7;while(x%3==2&&x%5==4&&x%6==5)x+=14;printf(“flightofstairs=%d\n”,x);}当②③④中有一者不满足时,便验证X的下一个值是否满足运行结果:flightofstairs=119(x%3!=2||x%5!=4||x%6!=5)X取第一个值7当②③④中有一者不满足时X取下一个值X+14输出X的值P87例19(续):程序中有无错误?P87例20:欧几里德算法求非负整数u和v的最大公因数迭代法不断由旧值递推出新值的方法辗转相除(设u=24,v=15):11524159intgcd(intu,intv){intr;r=u%v;while(r!=0){u=v;v=r;r=u%v;}return(v);}u=24v=15r=u%v=9u=v=15v=r=9r=u%v=6u=v=9v=r=6r=u%v=3u=v=6v=r=3r=u%v=01915961696323660u=v=3v=r=0r=0时,v为所求v=0时,u为所求intgcd(intu,intv){intr;while(v!=0){r=u%v;u=v;v=r;}return(u);}①②③④①②③④r=u%v当(r!=0)时v为所求u=vv=rr=u%vP80例11:人口增长问题。main(){floatm=12;intn=1;while(n=10){m=m*(1+0.02);n=n+1;}printf(“%f\n”,m);}按年2%的增长速度,现有12亿人,则10年后将有多少人?算法分析:迭代法设现有人口为m=12亿,则:1年后人口:m(1+2%)m2年后人口:m(1+2%)m3年后人口:m(1+2%)m……10年后人口:m(1+2%)m因此:初值:m=12迭代公式:m=m(1+2%)终止条件:10年课后作业及上机任务教材P98习题:11、13(4)(6)~(9)、2(3)(5)上机调试P98习题10、12编写并调试本节例题(1)1+3+5+…+99(2)2+4+6+…+100(3)1-2+3-4+…+99-100(4)(5)n131211!1!31!211n课后练习for(初始表达式;条件表达式;修正表达式)循环体;二、for语句①③②⑤④Y条件表达式修正表达式NY初始表达式循环体Ns=0;for(i=1;i=10;i++)s=s+i;s=0;i=1;for(;i=10;i++)s=s+i;初始表达式;while(条件表达式){循环体;修正表达式;}执行过程for(s=0,i=1;i=10;){s=s+i;i++}s=0;i=1;while(i=10){s=s+i;i++;}1、省略初始表达式时,分号不能省。2、省略修正表达式时,循环体内应有改变条件表达式的值的语句。说明:形状形状main(){inti,j;for(i=1;i=9;i++)printf(“%4d”,i);printf(“\n”);for(i=1;i=9;i++)printf(“%c”,‘-’);printf(“\n”);for(i=1;i=9;i++){for(j=1;j=9;j++)printf(“%4d”,i*j);printf(“\n”);}}P91例22:打印九九乘法表形状1234567891234567892468101214161836912……打印表头9个数字打印虚线打印表体……for(i=1;i=9;i++){for(j=1;j=i;j++)printf(“%4d”,i*j);printf(“\n”);}打印表体for(i=1;i=9;i++){for(j=0;j=i-1;j++)printf(“%4c”,‘’);for(j=i;j=9;j++)printf(“%4d”,i*j);printf(“\n”);}打印表体打印空格判断一个正整数n3是否为素数main(){intn,m,yes=1;scanf(“%d”,&n);for(m=2;mn-1;m++)if(n%m==0){yes=0;break;}if(yes==1)printf(“yes\n”);elseprintf(“no\n”);}P93例23:验证素数素数是除了1和它自身外,再也找不到能被它整除的数。即:若n不能被2到n-1中所有整数整除,则n为素数。已证明只要从2判断到n/2或即可。算法分析:n也可用m=n-1求100~200间的全部素数课后练习:也可用n/2或sqrt(n)P80例12:兔子繁殖问题(Fibonacci提出的)P94例24:打印Fibonacci数列前n项main(){intn,m;longf1=1,f2=1,f3;scanf(“%d”,&n);printf(“%ld%ld”,f1,f2);for(m=3;m=n;m++){f3=f1+f2;f1=f2;f2=f3;printf(“%d”,f3);}printf(“\n”);}设有一对新生兔子,从第3个月开始,每个月都生一对兔子。按此规律,若所有兔子都不死,问一年后共有多少对兔子?迭代法算法分析:月:123456781--1—1—1—1—1—1--111--11—1--111—1—1--111--11—1—1—1—111--11—1—11兔:1123581321f1f211f3=f1+f22f1f2f3=f1+f23f1f2f3=f1+f25f1f2f3=…初始条件终止条件迭代公式思考:f1=f2和f2=f3能否对换位置?不main(){intx,y,z;for(x=0;x20;x++)for(y=0;y33;y++){z=100-x-y;if(5*x+3*y+z/3==100){printf(“x=%d”,x);printf(“y=%d”,y);printf(“z=%d\n”,z);}}}补充例题:百钱百鸡问题P85例18:搬砖问题P99习题7:百马百担问题P99习题6:换零钱问题P99习题8:准备客票问题P99习题9:验证欧拉公式穷举法类似问题:每只公鸡5元,每只母鸡3元,三只小鸡1元。用100元钱买100只鸡,问公、母、小鸡各买多少只?设公、母、小鸡各为x、y、z只,则:5x+3y+z/3=100x+y+z=100可得:0≤x200≤y333≤z≤100算法分析:补充举例:打印图形。1234567891011*************************算法分析:第1行:1个空格,5个*号,换行第2行:2个空格,5个*号,换行第3行:3个空格,5个*号,换行第4行:4个空格,5个*号,换行第5行:5个空格,5个*号,换行第i(1~5)行:i个空格,5个*号,换行mai