1、第5章 循环结构程序设计,5.1 为什么需要循环控制5.2 用while语句实现循环5.3 用do-while语句实现循环5.4 用for 语句实现循环5.5 循环的嵌套5.6 几种循环的比较5.7 改变循环执行的状态5.8 循环程序举例,5.1为什么需要循环控制,在日常生活中或是在程序所处理的问题中常常遇到需要重复处理的问题要向计算机输入全班50个学生的成绩分别统计全班50个学生的平均成绩求30个整数之和教师检查30个学生的成绩是否及格,5.1为什么需要循环控制,例如:全班有50个学生,统计各学生三门课的平均成绩。,scanf(“%f,%f,%f”,输入学生1的三门课成绩,并计算平均值后输出
2、,scanf(“%f,%f,%f”,输入学生2的三门课成绩,并计算平均值后输出,要对50个学生进行相同操作,重复50次,大多数的应用程序都会包含循环结构循环结构和顺序结构、选择结构是结构化程序设计的三种基本结构,它们是各种复杂程序的基本构造单元,5.2用while语句实现循环,全班有50个学生,统计各学生三门课的平均成绩。,i=1,i0,输入一个学生成绩,求一个学生平均成绩,输出一个学生平均成绩,i增1,Y,N,用while循环结构实现,while(i=50) scanf ; aver= ; printf ; i+;,while语句的一般形式如下: while (表达式) 语句,循环体,whi
3、le语句的一般形式如下: while (表达式) 语句,“真”时执行循环体语句“假”时不执行,循环条件表达式,while循环的特点是:先判断条件表达式,后执行循环体语句,例5.1求1+2+3+100,即解题思路:这是累加问题,需要先后将100个数相加要重复100次加法运算,可用循环实现后一个数是前一个数加1而得加完上一个数i后,使i加1可得到下一个数,#include int main() int i=1,sum=0; while (i=100) sum=sum+i; i+; printf(sum=%dn,sum); return 0;,复合语句,不能少,#include int main()
4、 int i=1,sum=0; while (i=100) sum=sum+i; i+; printf(sum=%dn,sum); return 0;,不能丢,否则循环永不结束,5.3用do-while语句实现循环,do-while语句的特点:先无条件地执行循环体,然后判断循环条件是否成立do-while语句的一般形式为: do 语句 while (表达式);,表达式,Y,N,循环体语句,5.3用do-while语句实现循环,例5.2 用dowhile语句求: 1+2+3+100,即,5.3用do-while语句实现循环,解题思路:,i 100,Y,N,sum=sum+ii=i+1,sum=0
5、i=1,i=1; sum=0; do sum=sum+i; i+; while(i=100);,#include int main() int i=1,sum=0; do sum=sum+i; i+; while(i=100); printf(sum=%dn,sum); return 0;,例5.3 while和do-while循环的比较。,int i,sum=0;printf(“i=?”);scanf(“%d”,int i,sum=0;printf(“i=?”);scanf(“%d”,当while后面的表达式的第一次的值为“真”时,两种循环得到的结果相同;否则不相同,5.4用for 语句实现
6、循环,for语句不仅可以用于循环次数已经确定的情况,还可以用于循环次数不确定而只给出循环结束条件的情况for语句完全可以代替while语句,printf(%d , i );,i+,i=100,i=1,5.4用for 语句实现循环,for (i=1;i=100;i+) printf(%d , i ); ,i 100,Y,N,i=i+1,i=1,输出i,5.4用for 语句实现循环,for语句的一般形式为 for(表达式1;表达式2;表达式3) 语句,设置初始条件,只执行一次。可以为零个、一个或多个变量设置初值执行,5.4用for 语句实现循环,for语句的一般形式为 for(表达式1;表达式2;
7、表达式3) 语句,循环条件表达式,用来判定是否继续循环。在每次执行循环体前先执行此表达式,决定是否继续执行循环,5.4用for 语句实现循环,for语句的一般形式为 for(表达式1;表达式2;表达式3) 语句,作为循环的调整器,例如使循环变量增值,它是在执行完循环体后才进行的,5.4用for 语句实现循环,for语句的执行过程:(1) 先求解表达式1(2) 求解表达式2,若其值为真,执行循环体,然后执行下面第(3)步。若为假,则结束循环,转到第(5)步(3) 求解表达式3(4) 转回上面步骤(2)继续执行(5) 循环结束,执行for语句下面的一个语句,5.4用for 语句实现循环,for(i
8、=1;i=100;i+) sum=sum+i;等价于i=1;while(i=100) sum=sum+i; i+;,用for语句更简单、方便,5.4用for 语句实现循环,for(表达式1;表达式2;表达式3) 语句,一个或两个或三个表达式均可以省略,5.4用for 语句实现循环,for (sum=0 ; i=100; i+) sum=sum+i;,与循环变量无关合法,5.4用for 语句实现循环,for(sum=0,i=1 ; i=100; i+) sum=sum+i;,逗号表达式合法,for(i=0,j=100 ; i=j; i+,j- ) k=i+j;,5.4用for 语句实现循环,fo
9、r(i=0; (c=getchar()!=n; i+=c) ;,合法,for( ; (c=getchar()!=n; ) printf(%c,c);,5.5循环的嵌套,一个循环体内又包含另一个完整的循环结构,称为循环的嵌套内嵌的循环中还可以嵌套循环,这就是多层循环3种循环(while循环、dowhile循环和for循环)可以互相嵌套,5.6几种循环的比较,(1)一般情况下,3种循环可以互相代替(2) 在while和do-while循环中,循环体应包含使循环趋于结束的语句。(3) 用while和do-while循环时,循环变量初始化的操作应在while和do-while语句之前完成。而for语句
10、可以在表达式1中实现循环变量的初始化。,5.7 改变循环执行的状态,5.7.1 用break语句提前终止循环5.7.2 用continue语句提前结束本次循环5.7.3 break语句和continue语句的区别,5.7.1 用break语句提前终止循环,break语句可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句,5.7.1 用break语句提前终止循环,例5.4 在全系1000学生中,征集慈善募捐,当总数达到10万元时就结束,统计此时捐款的人数,以及平均每人捐款的数目。,5.7.1 用break语句提前终止循环,编程思路:循环次数不确定,但最多循环1000次在循环体中
11、累计捐款总数用if语句检查是否达到10万元如果达到就不再继续执行循环,终止累加计算人均捐款数,5.7.1 用break语句提前终止循环,编程思路:变量amount,用来存放捐款数变量total,用来存放累加后的总捐款数变量aver,用来存放人均捐款数定义符号常量SUM代表100000,#include #define SUM 100000int main() float amount,aver,total; int i; for (i=1,total=0;i=SUM) break; aver=total / i ; printf(“num=%dnaver=%10.2fn“ ,i,aver);
12、return 0;,指定符号常量SUM代表100000,#include #define SUM 100000int main() float amount,aver,total; int i; for (i=1,total=0;i=SUM) break; aver=total / i ; printf(“num=%dnaver=%10.2fn“ ,i,aver); return 0;,应该执行1000次,#include #define SUM 100000int main() float amount,aver,total; int i; for (i=1,total=0;i=SUM) b
13、reak; aver=total / i ; printf(“num=%dnaver=%10.2fn“ ,i,aver); return 0;,达到10万,提前结束循环,#include #define SUM 100000int main() float amount,aver,total; int i; for (i=1,total=0;i=SUM) break; aver=total / i ; printf(“num=%dnaver=%10.2fn“ ,i,aver); return 0;,实际捐款人数,#include #define SUM 100000int main() flo
14、at amount,aver,total; int i; for (i=1,total=0;i=SUM) break; aver=total / i ; printf(“num=%dnaver=%10.2fn“ ,i,aver); return 0;,只能用于循环语句和switch语句之中,而不能单独使用,5.7.2 用continue语句提前结束本次循环,有时并不希望终止整个循环的操作,而只希望提前结束本次循环,而接着执行下次循环。这时可以用continue语句,5.7.2 用continue语句提前结束本次循环,例5.5 要求输出100200之间的不能被3整除的数。编程思路:对100到20
15、0之间的每一个整数进行检查如果不能被3整除,输出,否则不输出无论是否输出此数,都要接着检查下一个数(直到200为止)。,N,n=100,n200,Y,n能被3整除,N,n=n+1,输出n,Y,for(n=100;n=200;n+) if (n%3=0) continue; printf(%d ,n); ,5.7.3 break语句和continue语句的区别,continue语句只结束本次循环,而不是终止整个循环的执行break语句结束整个循环过程,不再判断执行循环的条件是否成立,N,表达式1,Y,表达式2,N,Y,N,表达式1,Y,表达式2,N,Y,break语句,continue语句,强行
16、退出循环,只结束本次循环,例5.6 输出以下4*5的矩阵。 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20,解题思路:可以用循环的嵌套来处理此问题用外循环来输出一行数据用内循环来输出一列数据按矩阵的格式(每行5个数据)输出,#include int main() int i,j,n=0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,累计输出数据的个数,控制一行内输出5个数据,#include i
17、nt main() int i,j,n=0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,双重循环,#include int main() int i,j,n=0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,控制输出4行,#include int main() int i,j,n=
18、0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,控制每行中输出5个数据,#include int main() int i,j,n=0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,i=1时,j由1变到5i*j的值是1,2,3,4,5,#include int main() int
19、 i,j,n=0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,i=2时,j也由1变到5i*j的值是2,4,6,8,10,如何修改程序,不输出第一行的空行?,#include int main() int i,j,n=0; for (i=1;i=4;i+) for (j=1;j=5;j+,n+) if (n%5=0) printf (“n”); printf (%dt,i*j); printf(n); return 0;,if (i=3
20、,遇到第3行第1列,终止内循环,#include int main() int i,j,n=0; for (i=1;i=4;i+) for (j=1;j=1e-6) pi=pi+term; n=n+2; sign=-sign; term=sign/n; pi=pi*4; printf(pi=%10.8fn,pi); return 0;,求绝对值的函数,只保证前5位小数是准确的,#include #include int main() int sign=1; double pi=0,n=1,term=1; while(fabs(term)=1e-6) pi=pi+term; n=n+2; sig
21、n=-sign; term=sign/n; pi=pi*4; printf(pi=%10.8fn,pi); return 0;,改为1e-8,例5.8 求费波那西(Fibonacci)数列的前40个数。这个数列有如下特点:第1、2两个数为1、1。从第3个数开始,该数是其前面两个数之和。即:,这是一个有趣的古典数学问题:有一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假设所有兔子都不死,问每个月的兔子总数为多少?,#include int main() int f1=1,f2=1,f3; int i; printf(%12dn%12dn,f1,f2);
22、for(i=1; i=38; i+) f3=f1+f2; printf(%12dn,f3); f1=f2; f2=f3; return 0;,代码可改进,#include int main() int f1=1,f2=1; int i; for(i=1; i=a & c=A & c=W ,解题思路:问题的关键有两个: (2) 怎样使c改变为所指定的字母?办法是改变它的ASCII值例如字符变量c的原值是大写字母A,想使c的值改变为E,只需执行“c=c+4”即可,因为A的ASCII值为65,而E 的ASCII值为69,二者相差4,char c;c=getchar(); while(c!=n) if(c=a ,可以改进程序,char c;while(c=getchar()!=n) if(c=A ,不能少,