为什么需要循环控制
要向计算机输入全班50个学生的成绩(重复50次相同的输入操作)
分别统计全班50个学生的平均成绩(重复50次相同的计算操作)
重复书写不太现实,工作量大,程序冗长且重复,但是如果使用循环操作,只需要一段代码就可以完成。
大多数的应用程序都会包含循环结构。循环结构和顺序结构、选择结构是结构化设计的3种基恩解构,他们是各种复杂程序的基本构成单元。
用while语句实现循环
while(表达式)语句
while语句可简单地记为:只要当循环条件表达式为真(即给定的条件成立),就执行循环体语句。
语句就是循环体,循环体可以是一个简单的语句,可以是复合语句。
执行循环体的次数是由循环条件控制的,这个循环条件就是上面一般形式中的“表达式”,它也称为循环条件表达式。当此表达式的值为“真”(以非0值表示)时,就执行循环体语句;为“假”(以0表示)时,就不执行循环体语句。
可简单记为:只要当循环条件表达式为真(即给定条件成立),就执行循环体语句
注意
while循环的特点是先判断条件表达式,后执行循环体语句。
求1+2+3+……+100
解题思路:
因为这个题目是一个累加的问题,需要先后将100个数相加,要重复进行100次加法运算,所以可以使用循环结构。因为每次相加的后一个数都是前一个数递增1的结果,所以不需要每次通过键盘键入加数,只需要设置变量,每次循环使变量自增1。
流程图如下:
程序如下:
#include <stdio.h>
int main() {
int i = 1, sum = 0; //定义变量i的初始值为1,sum的初始值为0
while (i <= 100) { //当i>100,条件表达式不成立,不执行循环
sum += i; //累加
i++; //自增
}
printf("sum=%d\n", sum);//输出累加和
return 0;
}
程序分析:
循环体如果包含一个以上的语句,应该用花括号括起来,作为复合语句出现
不要忽略给i和sum赋值,否则他们的值是不可以预测的,结果显然不正确
在循环体中应有使循环趋向于结束的语句,例如“i++”,否则会进入死循环
用do……while语句实现循环
除了while语句以外,C语言还提供了do……while语句来实现循环结构。
do
语句
while(表达式);
注意:
do……while语句的特点是,先无条件地执行循环体,然后判断循环条件是否成立。这里和while循环不一样,do……while循环至少进行一次循环。
求1+2+3+……+100
流程图:
代码:
#include <stdio.h>
int main() {
int i = 1, sum = 0;
do{
sum += i;
i++;
} while (i <= 100);
printf("sum=%d\n", sum);
return 0;
}
在一般情况下,用while语句和用do……while语句处理同一问题时,若二者的循环体部分是一样的,那么结果也一样。但是如果while后面的表达式一开始就为0时,两种循环的结果是不一样的,因为这个时候while循环直接不执行,而do……while循环会执行一次。
while和do……while循环的比较
(1)while后面的表达式为1
(2)while后面的表达式为0
(1)
(2)
由上图可知,当输入的值满足while循环的条件的时候,二者结果相同,但是如果不满足,则不同。
用for语句实现循环
for(表达式1;表达式2;表达式3)
语句
除了可以用while语句和do……while语句实现循环外,C语言还提供了for语句实现循环,而且for语句更为灵活,不仅可以用于循环次数已经确定的情况,还可以用于循环次数不确定而只给出循环结束条件的情况。
在for循环中,表达式1是设置初始条件,只执行一次。可以没有,也可以为1个或者多个变量设置初始值。如果没有表达式1,那一定要在for循环开始之前对变量进行初值设置。
表达式2是循环条件表达式,用来判定是否继续循环。在每次执行循环体前先执行此表达式,决定是否继续执行循环。
表达式3作为循环的调整,例如使循环变量增值,它是在执行完循环体后才进行的。
注意:
while循环的特点是先判断条件表达式,后执行循环体语句。
最常用的for语句形式是:
for(循环变量赋初值;循环条件;循环变量增至)
语句
对应的while循环为:
循环变量赋初值;
while 循环条件{
语句
循环变量增值
}
for语句的执行过程如下:
求解循环变量初值->求解循环条件,如果为1,则执行循环体,然后执行下一步,如果为0,则结束循环,执行for语句后面一个语句->求解循环变量初值->重复求解循环条件并进行判断
注意:
表达式1可以省略,即不设置初值,但表达式1后的分号不能省略,并在for循环之前给循环变量赋以初值。
表达式2也可以省略,此时循环无终止地进行下去,进入死循环。
表达式3也可以省略,但是此时程序设计者应另外设法保证循环能正常结束。
表达式1和3可以使简单的表达式,也可以是由逗号隔开的表达式。
表达式2一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值为非零,就执行循环体。
for语句的循环体可为空语句,把本来要在循环体内处理的内容放在表达式3中,作用是一样的。
循环的嵌套
一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多层循环。3种循环可以互相嵌套。
几种循环比较
3种循环都可以用来处理同一问题,一般情况下他们可以相互替代。
在while循环和do……while循环中,只在while后面的括号内指定循环条件,因此为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句,如i++或i=i+1
for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体的操作全放到表达式3中,因此for语句的功能更强,凡是使用while循环能完成的,for循环都可以以完成。
用while和do……while循环时,循环变量初始化的操作应在while和do……while语句之前完成。而for语句可以在表达式1实现循环变量的初始化。
while循环,do……while循环和for循环都可以用break语句跳出循环,用continue语句结束本次循环。
改变循环执行的状态
用break语句提前终止循环
在全系1000名学生中举行慈善募捐,当总数达到10万元的时候就结束,统计此时捐款的人数以及平均每人捐款的数目。
解题思路:
在本题中,因为实际循环的次数事先并不能确定,但最多有1000个人捐款,在循环体中累计捐款总数,并用if语句检查是否达到10万元,如果达到就不再继续执行循环,终于累加,并计算人均捐款数。
代码:
#include <stdio.h>
#define SUM 100000 //指定符号常量SUM代表10万元
int main() {
float amount, aver, total;
int i;
for (i = 1, total = 0; i <= 1000; i++) {
printf("Please enter amount:");
scanf("%f", &amount);
total += amount;
if (total >= SUM)
break;
}
aver = total / i;
printf("num=%d\naver=%10.2f\n", i, aver);
return 0;
}
程序分析:
for语句本来指定执行循环体1000次。在每一次循环中,输入一个捐款人的捐款数,然后把它累加到total中,如果没有if语句,则执行循环体1000次。现在执行循环体1000次。现在设置一个if语句,在每一次累加了捐款数amount后,立即检查累加和total是否达到或超过外,即不再继续执行剩余的几次循环,提前结束循环。
break的作用是使流程跳到循环体之外,接着执行循环体下面的语句。
注意:
break语句只能用于循环语句和switch语句之中,而不能单独使用。
用continue语句提前结束本次循环
要求输出100~200之间的不能被3整除的数
编程思路:
如果能被3整除,则继续循环,如果不能,则打印出这个数之后再进入循环。
流程图:
代码:
#include <stdio.h>
int main() {
int n;
for (n = 100; n <= 200; n++) {
if (n % 3 == 0)
continue;
printf("%d\t", n);
}
printf("\n");
return 0;
}
运行结果:
程序分析:
当n能被3整除时,执行continue语句,流程跳转到表示循环体结束的右花括号的前面,从而跳过printf函数语句,结束本次循环,然后进行循环变量的增值,只要n<=200,就会接着执行下一次循环。
continue的作用为结束本次循环,即跳过循环体中下面尚未执行的语句,转到循环体结束点之前,接着执行for语句中的表达式3,然后进行下一次是否执行循环的判定。
break语句和continue语句的区别
continue语句值结束本次循环,而不是终止整个循环的执行。而break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。
输出以下4*5的矩阵
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
解题思路:
可以使用循环嵌套来处理此问题,用外循环来输出一行数据,用内循环来输出一列数据。
编写程序:
#include <stdio.h>
int main() {
int i, j, n = 0; //n用来累计输出的数据个数
for (i = 1; i <= 4; i++) {
for (j = 1; j <= 5; j++, n++) { //控制在输出5个数据后换行
if (n % 5 == 0)
printf("\n");
printf("%d\t", i * j);
}
}
printf("\n");
return 0;
}
运行结果:
程序分析:
本程序包括一个双重循环,是for循环的嵌套。外循环变量i由1变到4,用来控制输出4行数据;内循环变量j由1变到5,用来控制输出每行中的5个数据。输出的值是i*j。
循环程序举例
用公式
求π的近似值,知道发现某一项的绝对值小于
为止(该项不累加)
解题思路:
每项的分子都是1,后一项的分母是前一项的分母加2,第一项的符号为正,后一项与前一项符号相反,在每一项求出后判断其绝对值是否大于等于
编写程序:
#include <stdio.h>
#include <math.h> //程序中用到数学函数fabs,应包含头文件math.h
int main() {
int sign = 1; //sign用来表示数值的符号
double pi = 0.0, n = 1.0, term = 1.0; //pi开始代表多项式的值,最后代表π的值,n代表分母,term代表当前项的值
while (fabs(term) >= 1e-6) { //检查当前项term的绝对值是否大于或等于10^(-6)
pi = pi + term; //把当前项term累加到pi中
n = n + 2; //n+2是下一项的分母
sign = -sign; //sign代表符号,下一项的符号与上一项的符号相反
term = sign / n; //求出下一项的值term
}
pi = pi * 4; //多项式的和pi乘以4,才是π的近似值
printf("pi=%10.8f\n", pi); //输出π的近似值
return 0;
}
运行结果: