程序设计和C语言案例 (5).ppt
C程序设计基础知识编程实践算法理解科学思维20195 5 5 5循环结构程序设计第第第第章章章章目 录5.1为什么要循环控制5.2用while语句实现循环5.3用dowhile语句实现循环5.4用for语句实现循环5.5循环的嵌套5.6几种循环的比较5.7改变循环执行的状态5.8循环程序举例为什么要循环控制循环结构5.15.1 为什么需要循环控制是否重复书写代码即可实现?输入全班人的每个人5门课的成绩统计每个人的平均成绩查询出不及格的人应用中的需求延迟符在编程时未知重复次数则无法以重复书写代码实现。维护重复代码工作量巨大。使用循环语句实现。5.1 为什么需要循环结构scanf(%f,%f,%f,%f,%f,&score1,&score2,&score3,&score4,&score5);/输入一个学生5门课的成绩aver=(score1+score2+score3+score4+score5)/5;/求该学生平均成绩printf(aver=%7.2f,aver);/输出该学生平均成绩要向计算机输入全班50个学生的成绩;(重复50次相同的输入操作)分别统计全班50个学生的平均成绩;(重复50次相同的计算操作)程序要求1个人的处理代码i=1;/设整型变量i初值为1while(i=50)/当i的值小于或等于50时执行花括号内的语句scanf(%f,%f,%f,%f,%f,&score1,&score2,&score3,&score4,&score5);aver=(score1+score2+score3+score4+score5)/5;printf(aver=%7.2f,aver);i+;/每执行完一次循环使i的值加1循环处理50个人的代码用while语句实现循环循环结构举例5.25.2 用while语句实现循环控制While语句格式:语句格式:while(表达式)语句延迟符while语句说明:只要当循环条件表达式为真(即给定的条件成立),就执行循环体语句。“语句”就是被重复执行的部分,称为循环体。循环体可以是一个单语句,可以是用括起来的多条语句的复合语句。执行循环体的次数是由循环条件控制的,这个循环条件就是上面一般形式中的“表达式”,它也称为循环条件表达式。当此表达式的值为“真”(非0值)时,就执行循环体语句;为“假”(0)时,就不执行循环体语句,转去执行循环语句的下一句。表达式语句YN特点:while循环的特点是先判断条件表达式,后执行循环体语句。5.2 用while语句实现循环控制举例例5.1连续求和流程图流程图i100sum=sum+ii=i+1真假sum=0i=15.2 用while语句实现循环控制举例代码#includeintmain()inti=1,sum=0;/定义变量i的初值为1,sum的初值为0while(i100,条件表达式i=100的值为假,不执行循环体/循环体开始sum=sum+i;/第1次累加后,sum的值为1i+;/加完后,i的值加1,为下次累加做准备/循环体结束printf(sum=%dn,sum);/输出1+2+3+100的累加和return0;延迟符1.循环体如果包含一个以上的语句,应该用花括号括起来,作为复合语句出现。2.不要忽略给i和sum赋初值,否则它们的值是不可预测的,结果显然不正确。3.在循环体中应有使循环趋向于结束的语句。如本例中的“i+;”语句。如果无此语句,则i的值始终不改变,循环永远不结束。用dowhile语句实现循环循环结构举例5.35.3 用dowhile语句实现循环do.while语句格式:语句格式:do语句while(表达式)延迟符dowhile语句说明:执行循环体后,进行条件表达式的判断,如果为真再次执行循环体,否则执行循环语句下一句。由于先执行循环体,再进行条件判断,因此此循环方式最少执行一次循环体。特点:先执行循环体,后判断条件表达式。表达式语句YN5.3 用while语句实现循环控制举例例5.2连续求和流程图流程图i100sum=sum+ii=i+1真假sum=0i=15.3 用while语句实现循环控制举例代码#includeintmain()inti=1,sum=0;dosum=sum+i;i+;while(i=100);printf(sum=%dn,sum);return0;延迟符1.在一般情况下,用while语句和用dowhile语句处理同一问题时,若二者的循环体部分是一样的,那么结果也一样。2.但是如果while后面的表达式一开始就为假(0值)时,两种循环的结果是不同的。5.3 用while语句实现循环控制举例例5.3while和do.while比较代码/while语句实现#includeintmain()inti,sum=0;printf(pleaseenteri,i=?);scanf(%d,&i);while(i=10)sum=sum+i;i+;printf(sum=%dn,sum);return0;/dowhile语句实现#includeintmain()inti,sum=0;printf(pleaseenteri,i=?);scanf(%d,&i);dosum=sum+i;i+;while(i=10);printf(sum=%dn,sum);return0;用for语句实现循环循环结构举例5.45.4 用for语句实现循环for语句格式:语句格式:for(表达式1;表达式2;表达式3)语句延迟符for语句更为灵活,不仅可以用于循环次数已经确定的情况,还可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替while语句。表达式1:设置初始条件,只执行一次。可以为零个、一个或多个变量设置初值。表达式2:是循环条件表达式,用来判定是否继续循环。在每次执行循环体前先执行此表达式,决定是否继续执行循环。表达式3:作为循环的调整,例如使循环变量增值,它是在执行完循环体后才进行的。求解表达式1表达式2语句求解表达式3真假for语句的下一语句5.4 用for语句实现循环for语句格式:语句格式:for(表达式1;表达式2;表达式3)语句for语句的语句的执行过程执行过程如下如下:1.求解表达式1。2.求解表达式2,若此条件表达式的值为真(非0),则执行for语句中的循环体,然后执行第(3)步。若为假(0),则结束循环,转到第(5)步。3.求解表达式3。4.转回步骤(2)继续执行。5.注意:在执行完循环体后,循环变量的值“超过”循环终值,循环结束。6.循环结束,执行for语句下面的一个语句。否继续执行循环。求解表达式1表达式2语句求解表达式3真假for语句的下一语句5.4 用for语句实现循环for语句格式:语句格式:for(表达式1;表达式2;表达式3)语句延迟符for语句语句的的注意注意事项事项:1.表达式1可以省略,即不设置初值,但其后的分号不能省。例如:for(;i=100;i+)。由于省略了表达式1,没有对循环变量赋初值,为了正常执行循环,应在for语句之前给循环变量赋初值。2.表达式2也可以省略,即不用表达式2来作为循环条件表达式,不设置和检查循环的条件。此时循环无终止地进行下去,也就是认为表达式2始终为真。3.表达式3也可以省略,但此时程序设计者应另外设法保证循环能正常结束。4.3个表达式都可省略,即不设初值,不判断条件(认为表达式2为真值),循环变量也不增值,无终止地执行循环体语句,这是死循环,显然这是没有实用价值的。5.表达式1可以是设置循环变量初值的赋值表达式,也可是与循环变量无关的其它表达式。表达式3也可是与循环控制无关的表达式。但不论怎样写for语句,都必须使循环能正常执行。6.表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式,即包含一个以上的简单表达式,中间用逗号间隔。7.表达式2一般是关系或逻辑表达式,也可以是数值或字符表达式,只要值非零,就会执行循环体。8.for语句的循环体可为空语句,把本来要在循环体内处理的内容放在表达式3中,作用是一样的。可见for语句功能强,可以在表达式中完成本来应在循环体内完成的操作。9.C99允许在允许在for语句语句的表达式的表达式1中中定义变量并赋初值定义变量并赋初值。例:for(inti=1;i100;i+)sum=sum+i;5.4 用for语句实现循环举例#includeintmain()inti,sum;sum=0;for(i=1;i=100;i+)sum=sum+i;printf(sum=%dn,sum);return0;延迟符#includeintmain()inti,sum;for(i=1,sum=0;i=100;i+)sum=sum+i;printf(sum=%dn,sum);return0;#includeintmain()inti,sum;for(i=1,sum=0;i=100;sum=sum+i,i+);printf(sum=%dn,sum);return0;for语句实现连续求和代码循环的嵌套循环结构举例5.55.5 循环的嵌套一个循环内部又包括一个完整的循环称为循环的嵌套,内部循环中还有循环,称为多层循环。延迟符01内层循环02内层循环03内层循环04内层循环05内层循环06内层循环几种循环的比较3种循环循环变量5.65.6 几种循环的比较三种循环语句各有不同。延迟符1.三种循环都可以用来处理同一问题,一般情况下它们可以互相代替。2.在while循环和dowhile循环中,只在while后面的括号内指定循环条件,因此为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句(如i+,或i=i+1等)。for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式3中。因此for语句的功能更强,凡用while循环能完成的,用for循环都能实现。3.用while和dowhile循环时,循环变量初始化的操作应在while和dowhile语句之前完成。而for语句可以在表达式1中实现循环变量的初始化。4.while循环、dowhile循环和for循环都可以用break语句跳出循环,用continue语句结束本次循环。改变循环执行的状态breakcontinue5.75.7 改变循环的执行状态02 0201 01continue在循环体执行的过程中,某些情况下需要循环体部分执行完成就跳出循环,某些情况下需要直接跳转到下一次循环,在这样的情况下,需要用到break语句和continue语句。break5.7.1 用break语句提前终止循环延迟符格式:格式:break;作用:使流程跳到循环体之外,接着执行循环体下面的语句。注意:break语句只能用于循环语句和switch语句之中,而不能单独使用。代码#include#defineSUM100000/指定符号常量SUM代表10万intmain()floatamount,aver,total;inti;for(i=1,total=0;i=SUM)break;aver=total/i;printf(num=%dnaver=%10.2fn,i,aver);return0;例5.4捐款计算在1000名学生中举行慈善募捐,当总额达到10万元时就结束,统计捐款人数以及平均每人捐款的数目。for语句指定执行循环体1000次。每次循环中,输入一个捐款数,并累加到total中。循环体内的if语句,在每一次累加捐款数amount后,立 即 检 查 累 加 和 total是 否 达 到 或 超 过 SUM(即100000),若超过就执行break语句,流程跳转到循环体的花括号外,提前结束循环。5.7.2 用continue语句提前结束本次循环延迟符格式:格式:continue;作用:结束本次循环,即跳过循环体中下面尚未执行的语句,转到循环体结束点之前,接着执行for语句中的“表达式3”,然后进行下一次是否执行循环的判定。代码#includeintmain()intn;for(n=100;n=200;n+)if(n%3=0)continue;printf(%d,n);printf(n);return0;例5.5循环输出要求输出100200之间的不能被3整除的数。当n能被3整除时,执行continue语句,流程跳转到表示循环体结束的右花括号的前面(注意不是右花括号的后面),从而跳过printf(%d,n)语句;结束本次循环,然后进行循环变量的增值(n+),只要n=200,就会接着执行下一次循环。5.7.3 break语句和continue语句的区别break;break;while(表达式1)语句1if(表达式2)break;语句2continue;continue;while(表达式1)语句1if(表达式2)continue;语句2continue语句只结束本次循环,而非终止整个循环。break语句结束整个循环,不再判断执行循环的条件是否成立。break表达式表达式1 1语句语句1 1表达式表达式2 2语句语句2 2whilewhile循环的循环的下一语句下一语句假真真假continue表达式表达式1 1语句语句1 1表达式表达式2 2语句语句2 2whilewhile循环的循环的下一语句下一语句假真真假5.7.3 break语句和continue语句的区别举例例5.6.1break应用打印九九口诀表。代码#includeintmain()inti,j;for(i=1;i=9;i+)for(j=1;ji)break;printf(%d*%d=%dt,j,i,i*j);printf(n);return0;思考:如果条件为if(j=i),程序应该怎么写?和现有写法的区别在哪里?5.7.3 break语句和continue语句的区别举例例5.6.2continue应用产生5个人4门课程的模拟成绩(随机数)并输出,如果成绩不及格在成绩后标识-N。代码#include#include/标准库函数文件,此程序srand,rand函数#include/时间库函数文件,此程序time函数intmain()inti,j,k;srand(time(NULL);/初始化随机数种子for(i=1;i=5;i+)/循环每个人printf(t%d,i);/人员顺序号for(j=1;j=60)continue;/成绩及格,处理下一成绩printf(-N);/不及格处理printf(n);/每个人一行return0;在本程序中,不及格处理只有一句,用if语句的else子句完成非常方便;但如果不及格处理的语句很多,使用continue子句则可简化一层嵌套。5.7.3 break语句和continue语句的区别举例#include/标准库函数文件,此程序srand,rand函数函数名称:rand函数原型:intrand(void);函数功能:产生0到32767间的随机整数(0到0 x7fff之间)函数返回:随机整数函数名称:srand函数原型:voidsrand(unsignedseed)功能:产生随机数的起始发生数据,和rand函数配合使用函数返回:void定义,无返回值#include/时间库函数文件,此程序time函数函数名称:time函数原型:time_ttime(time_t*time);/返回值为time_t类型函数功能:产生1970/1/1到现在的秒数函数返回:秒数说明:time函数有两中用法,如果里面带参数,返回值则放在参数里面,否则直接返回time值。这种秒数是以数据类型time_t表示的,可以用%ld打印出来。循环程序举例举例1举例25.85.8 循环程序举例例5.7计算应用解题解题思路思路1.每项的分子都是1。2.后一项的分母是前一项的分母加2。3.第1项的符号为正,从第2项起,每一项的符号与前一项的符号相反。4.在每求出一项后,检查它的绝对值是否大于或等于10-6。sign=1,pi=0,n=1,term=1当|term|10-6pi=pi+termn=n+2sign=-signterm=sign/npi=pi*4输出pi5.7.3 break语句和continue语句的区别举例代码#include#include/程序中用到数学函数fabs,应包含头文件math.hintmain()intsign=1;/sign用来表示数值的符号doublepi=0.0;/pi开始代表多项式的值,最后代表的值doublen=1.0,term=1.0;/n代表分母,term代表当前项的值while(fabs(term)=1e-6)/检查当前项term的绝对值是否大于或等于10-6(10-运行慢)pi=pi+term;/把当前项term累加到pi中n=n+2;/n+2是下一项的分母sign=-sign;/sign代表符号,下一项的符号与上一项符号相反term=sign/n;/求出下一项的值termpi=pi*4;/多项式的和pi乘以4,才是的近似值printf(pi=%10.8fn,pi);/输出的近似值return0;5.8 循环程序举例例5.8斐波那契数列解题解题思路思路1.第一个数f1、第二个数f2:初始值f1=1,f2=1。2.输出f1、f2。3.循环次数38次:输出f3f404.循环体内:计算当前的数f3,输出f3。现有f1、f2、f3。将当前第一个数和第二个数后移,为下次循环计算f4作准备。5.8 循环程序举例代码:方法1/一次输出1个数,2个初始值直接输出,其余循环38次,共40个数#includeintmain()intf1=1,f2=1,f3,i;printf(%10d%10d,f1,f2);for(i=3;i=40;i+)/循环变量初始值从3开始,逢5换行f3=f1+f2;/计算当前数printf(%10d,f3);/输出当前数f1=f2;/当前位置后移,赋值下次第一个数,并存放在f1中f2=f3;/赋值下次第二个数,并存放在f2中if(i%5=0)printf(n);/逢5个数换行return0;f1=1,f2=1输出f1,f2for i=1 to 38f3=f1+f2输出f3f1=f2f2=f35.8 循环程序举例代码:方法2/一次输出2个数,循环20次,输出40个数#includeintmain()intf1=1,f2=1;inti;for(i=1;i=20;i+)/每个输出2个数,只需循环20次printf(%12d%12d,f1,f2);/输出已知的两个数if(i%2=0)printf(n);/2次输出换一行,一行4个数f1=f1+f2;/计算出下次第一个数,并存放在f1中f2=f2+f1;/计算出下次第两个数,并存放在f2中return0;f1=1,f2=1for i=1 to 20输出f1,f2f1=f1+f2f2=f2+f15.8 循环程序举例例5.9判别素数输入一个大于3的整数n,判定它是否为素数(prime,质数)。素数:只能被1和自己整除的数为素数。解题解题思路思路1.接收数据到变量n中。2.编制循环变量从2到n-1的循环。3.循环体内:测试n是否能被循环变量整除;如果能整除,不是素数,跳出循环。4.循环体外:根据循环变量的值判断是否是中途跳出,中途跳出则不是素数,否则是素数。输入ni=2for i=2 to n-1是否执行break结束循环i=i+1是否输出n不是素数输出n是素数5.8 循环程序举例代码:方法1#includeintmain()intn,i;printf(pleaseenteraintegernumber,n=?);scanf(%d,&n);for(i=2;in;i+)if(n%i=0)break;/能被整除跳出循环if(in)printf(%disnotaprimenumber.n,n);elseprintf(%disaprimenumber.n,n);return0;若n能被2(n-1)之间的一个整数整除,则执行break语句,提前结束循环,流程跳转到循环体之外。此时in。如果n不能被2(n-1)之间任何的一个整数整除,则不会执行break语句,循环变量i一直增值到n,然后由循环结束判定in条件不成立,结束循环。这是正常结束的循环,其循环变量的值越过循环变量终值(本例中循环变量终值为n-1)。因此,在循环结束后检查循环变量i的值,就能判定循环是提前结束还是正常结束的。从而判定n是否为素数。5.8 循环程序举例代码:方法2#include#includeintmain()intn,i,k;printf(pleaseenteraintegernumber,n=?);scanf(%d,&n);k=sqrt(n);for(i=2;i=k;i+)if(n%i=0)break;if(i=k)printf(%disnotaprimenumber.n,n);elseprintf(%disaprimenumber.n,n);return0;5.8 循环程序举例代码:方法3/通过变量f的值来判断是否是素数#include#includeintmain()inti,n,f;printf(inputn=?);scanf(%d,&n);for(f=1,i=2;i=(int)sqrt(n);i+)if(n%i=0)f=0;break;if(f=1)printf(%disprime.n,n);elseprintf(%disnotaprime.n,n);return0;for语句的各种用法:/将变量f加入终止条件判断提升效率for(f=1,i=2;i=(int)sqrt(n)&f;i+)if(n%i=0)f=0;/不使用break也能出正确结果,但效率低for(f=1,i=2;i=(int)sqrt(n);i+)if(n%i=0)f=0;5.8 循环程序举例例5.10求素数求101200间的全部素数。解题解题思路思路1.此程序需要使用循环嵌套来完成题目要求。2.外部循环:n从101200,遍历101200中每个数值。3.内部循环:测试本次的n是否是素数。4.内部循环:i从从2到n-1的循环。5.外部循环:是素数输出,并计数;如果个数能被10整除,换行。5.8 循环程序举例代码:方法#include#includeintmain()intn,k,i,m=0;for(n=101;n=200;n=n+2)/n从101变化到200,对每个奇数n进行判定k=(int)sqrt(n);/将开方结果转为整型赋值给kfor(i=2;i=k;i+)if(n%i=0)break;/如果n被i整除,终止内循环,此时i=k+1)/若i=k+1,表示n未曾被整除printf(%d,n);/应确定n是素数m=m+1;/m中为现有素数个数if(m%10=0)printf(n);/m累计到10的倍数,换行printf(n);return0;蓝色代码是例9中求一个数是否是素数,本例增加外部循环,遍历101200每一个数进行逐个求是否是素数。5.8 循环程序举例例5.11翻译密码为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。例如,可以按以下规律将电文变成密码:将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变成B,Y变成C,Z变成D。解题解题思路思路1.判断哪些字符不需要改变(非字母),哪些字符需要改变(字母)。2.通过改变字符c的ASCII值的方式将其变为指定的字母。AV或av:c=c+4;WZ或wz:c=c+4-26。输入一个字符给c当c不是换行符是否是否c=c-22c=c+4输出c的字符值输入一个字符给cc是字母c在WZ或wz间5.8 循环程序举例代码:方法#includeintmain()charc;c=getchar();/输入一个字符给字符变量cwhile(c!=n)/检查c的值是否为换行符n,如果是结束;否则循环处理接收cif(c=a&c=A&c=W&c=w&c=z)c=c-22;/如果是26个字母中最后4个字母之一就使c+4-26elsec=c+4;/如果是前面22个字母之一,就使c加4,即变成其后第4个字母printf(%c,c);/输出已改变的字符c=getchar();/再输入下一个字符给字符变量cprintf(n);return0;提问:为什么不是每输入一个字符,就输出一个加密后的结果字符?5.8 循环程序举例getchar函数运行说明getchar的返回值为int型,它的接收数据运行过程如下:1.当程序调用getchar时,程序进入等待输入状态,用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止(回车字符也放在缓冲区中)。2.当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符,getchar函数的返回值是用户输入字符的ASCII码(如出错返回-1),同时将用户输入的字符显示到屏幕。3.如果用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取。4.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键。PPT模板下载: 谢谢观看THANK YOU本章内容结束