第5章循环结构程序设计O什么是循环呢?先来看一个现实中的问题。已知某班40名学生五门课程的成绩,要求计算每名学生的总分和平均分。要处理一名学生的数据,只需要几条语句就能完成。而要处理40名学生的数据,有两种方法可以选择。第一种方法,是将这几条语句重写40遍,显然不太合适;第二种方法,是将这几条语句只写1遍,但是重复执行40次,这种方法实际上就是循环。循环是指在满足一定条件时反复执行某个程序段的过程。如何构成循环呢?其实,利用第4章讲过的goto语句,就能够实现循环结构。【例5.1】用goto语句构成的循环。源程序:#include <stdio.h>出版int main (void)1int i=l;Ll:printf("od,",i);i=i+1;goto Ll;return o;程序中反复执行的部分,称为循环体。显然,本例的循环体是从printf语句开始的三条语句。当这个程序运行时,将会依次输出1,2,3,4,5,6,7,8,9,10等。这个循环什久时候结束呢?永远也不会结束。因为这个循环是一个无条件循环,所以它是一个无限循环,或者称为“死循环”。如何才能让这个循环变成有限循环呢?只需要通过f语句给这个循环添加循环条件即可,从而得到如下的源程序。【例5.2】用if语句和goto语句构成的循环。源程序:#include<stdio.h>int main(void)(int i=l;L:if(i<=5)(printf("gd,",i);1=i+1;goto Ll;return o;
程序运行结果:1,2,3,4,5尽管利用if语句和goto语句可以实现循环结构,但是由于这种循环程序的结构性不好,在编程实践中几乎不会采用这种方式编写循环程序。在C语言中,提供了三种专门的循环语句来实现循环结构,即while语句,for语句和do-while语句。5.1while循环用while语句构成的循环,称为while循环。5.1.1while语句while语句的一般形式为while(表达式)单条语句其中,while之后的表达式称为循环的条件,通常为关系表达式或逻辑表达式,也可以是任意的结果类型为整型、实型、字符型、枚举型和指针型的表达式。而且,只要表达式的值非0,就看作真;只要表达式的值为0,就看作假。后面的单条语句就是要反复执行的部分称为循环体。while语句的执行流程如图5.1所示,即首先判断表达式的值是真是假,若表达式的值为真(非0),则执行一次循环体,并自动返回;若表达式的值为假(0),则结束循环,转而执行循环体之后的语句。表达式【例5.3】while循环示例。非源程序:循环体#include<stdio.h>int main (void)(int i=l;+while(i<=5)(printf("sd,",i);图5.1while语句的i=i+l;执行流程第return 0;5程序运行结果:章1,2,3,4,5,循5.1.2while循环程序举例环结【例5.4】编写程序,求1+2+3+…+100。构编程思路:程该问题实质上是求等差数列之和,完全可以利用等差数列的求和公式来求解,不过在序本例中采用累加运算的方法来求此数列之和。累加运算,就是通过不断积累的方式逐步求设得最终的结果,这种方法具有更好的通用性。计55
(1)首先定义变量sum用于存储累加和,并将sum赋值为0:(2)将1累加到sum中,即sum=sum+1(此时sum的值为1);(3)将2累加到sum中,即sum=sum+2(此时sum的值为1+2)(4)将3累加到sum中,即sum=sum+3(此时sum的值为1+2+3);(5)以此类推,直至将100累加到sum中,即sum=sum+100(此时sum的值为1+2+3+...+100)。可见,每一次累加都是在上一次累加的基础上进行的。上述100条赋值语句可以归纳为如下的循环体:sum=sum+i;i=i+l;其中,i的取值为1~100。故可推导出如下的while循环:sum=0;i=1;while(i<=100)(sum=sum+i;i=i+l;完整的源程序:学出版#include<stdio.h>int main(void)(int sum,i;sum=0;i=l;while(i<=100)(sum=sum+i;1=i+1;printf("sum=%dln",sum)return U;程序运行结果:sum=5050【例5.5】编写程序实现输入20个实数,计算它们的和。编程思路:该问题仍然可以采用累加运算的方式求和。由于数据个数较多,不适合让每个数据占C用一个变量来存储,可以只定义一个变量来存储新输人的数据。语(1)定义三个变量:x保存新输人的一个数,sum保存累加和,i保存已输入并累加数言据的个数。然后对变量sum和i进行初始化:程序sum=0;设i=0;(2)首先写出处理一个数据的语句:计新/*输人一个数*scanf("%f",&x);思/*累加到sum中*/sum=sum+x;路i=i+1;/*数据计数*/56
(3)若要处理20个数,只需将以上语句循环执行20次即可。此处可用数据个数i控制循环,由于变量i是在累加一个数之后进行加1计数的,当i等于20时,已经将第20个数累加到sum中,此时应当结束循环,故循环条件应为i<20。while(i<20)/*输人一个数*/(scanf("%f",&x);/*累加到sum中*sum=sum+x;i=i+l;/*数据计数*/L完整的源程序:#include<stdio.h>int main(void)(float X,sum;int i;sum=0;版社i=0;while(i<20)1*输人一个数*(scanf("%f",&x);/*累加到sum中*/sum=sum+x;/*数据计数*/i=i+1;1printf("sum-&fIn",sum);return 0;可见,在构造循环程序时,可以按照从具体到一般的原则,首先归纳出循环体,然后嵌套上循环语句即可。【例5.6】编写程序求n!。编程思路:该程序仍可采用累积运算的方法求解。只是要注意存放累乘结果的变量的初值应为1。源程序:#include <stdio.h>int main(void)/*不能用!作为变量名*(long f;int i,n;scanf("&d",&n);第f=1;5i=l;章while(i<=n)(f=f*i;循i=i+1;环A结printf("f=gldln",f);构return 0;程序设计57
5.2自增自减运算符与复合赋值运算符在循环结构程序中,自增自减运算符和复合赋值运算符是两类经常使用的运算符。5.2.1自增自减运算符自增自减运算符是C语言中两个很独特,也很容易令人困惑的运算符。其基本功能是使变量的值加1或减1。1.自增运算符++其基本功能是使变量的值加1,又分为前自增和后自增两种。前自增表达式的一般形式为++变量反社例如,++i。后自增表达式的一般形式为变量++例如,i++。从基本功能上说,i++和++i均与赋值表达式i-i+1相当。2.自减运算符--其基本功能是使变量的值减1,又分为前自减和后自减两种。前自减表达式的一般形式为--变量例如,一-i。后自减表达式的一般形式为变量--例如,i-一。从基本功能上说,i--和--i均与赋值表达式i=i-1相当。3.前自增(减)与后自增(减)的区别前自增与后自增、前自减与后自减到底有什么区别呢?首先,来明确前自增(减)与后自增(减)什么时候有区别,什么时候没有区别;然后,再来分析两者的区别。(1)当前自增(减)表达式与后自增(减)表达式单独使用时,是没有区别的;只有c语当其作为另一个表达式的一部分时,才有区别。例如,语句计+:与语句++i;是完全等价的,言而表达式j-i++与表达式j=++i则是完全不同的。程(2)对于前自增,表达式++i的值是i加1之后的值(可称为先加1后引用,即先将变序量的值加1,然后引用加1之后的这个值)。设例如,若有i=3;j=++i,则j=4,i=4。可见,此处的j=++i相当于j=(i=i+1)。计再如,若有i=3;printf("%dln"++i);,则程序运行结果为4。新思(3)对于后自增,表达式++的值是i加1之前的值(可称为先引用后加1,即先引用路变量的值,再将变量的值加1)。58