实现循环除掉使用for语句,还有while语句与do-while语句也可以实现循环。
1、while语句
while (表达式)
循环体语句;
其流程图如下:

while语句可以理解为:当(表达式)成立的时候,执行循环体。
(1)while语句中的表达式可以是任意合法的表达式,循环体语句只能是一条语句(用大括号括起来的复合语句属于一条语句)。
(2)while语句只有一个表达式和一条循环体语句,循环条件和循环体是循环的两个核心要素。
(3)循环一般包括4个部分:初始化、条件控制、重复的操作以及通过改变循环变量的值最终改变循环条件的真假性。for语句直接包含了这4个部分,while语句需while语句前执行初始化,在循环体语句中改变循环变量。
(4)for语句和while语句本质上是相同的,任何for语句和while语句都能相互改写。while语句变成成for语句只需要表达式1和表达式3为空语句就与while语句完全等价了,当然也有其他改写方式。下面为for语句改写的while语句:
表达式1;
while (表达式2) {
for的循环体语句;
表达式3;
}
一般来说,如果明确知道了循环次数,使用for语句简单明了,其他情况下一般使用while语句。
例1:求 π π π的近似值
使用格雷戈里公式求π的近似值,要求精确到最后一项的绝 对值小于给定精度eps。 π 4 = 1 − 1 3 + 1 5 − 1 7 + ⋯ \frac{\pi}{4} = 1-\frac{1}{3}+\frac{1}{5}-\frac{1}{7}+ \cdots 4π=1−31+51−71+⋯
#include <stdio.h>
#include <math.h> /*程序中调用绝对值函数fabs(),需包含math.h*/
int main(void)
{
int denominator, flag, i;
double eps, item, pi; /*pi用于存放累加和*/
printf("Enter eps:"); /*提示输入精度eps*/
scanf("%lf", &eps);
/*循环初始化*/
i = 1; /*i表示当前的项数*/
flag = 1; /*flag表示第i项的符号,初始为正*/
denominator = 1; /*denominator表示第i项的分母,初始值为1*/
item = 1.0; /*item中存放第i项的值,初值取1*/
pi = 0; /*置累加和pi的初值为0*/
while (fabs(item) >= eps){ /*当|item|>=eps时,执行循环*/
pi = pi+item; /*累加第i项的值*/
i++; /*项数增1,为下一次循环做准备*/
flag = -flag; /*改变符号,为下一次循环做准备*/
denominator = denominator+2; /*分母递增2,为下一次循环做准备*/
item = flag*1.0/denominator; /*计算第i项的值,为下一次循环做准备*/
}
pi = pi+item; /*加上最后一项的值*/
pi = pi*4; /*循环计算的结果是pi/4*/
printf("pi = %.4f\n", pi);
printf("i = %d\n", i); /*此处i的值为最后一项的项数*/
return 0;
}
运行结果:
Enter eps:0.00001
pi = 3.1416
i = 50001
本题没有明确给定循环次数,只是要求了精度,所以选择while语句更为合适。本题要达到要求的精度,只需要注意这个交错级数的特点,只要这一项的精度小于所给的精度,那么结果就会符合要求。即只要 ∣ i t e m ∣ < e p s |item| < eps ∣item∣<eps即满足题目的要求。循环前的初始化要注意,这里的item赋初值为1,因为后面每一项都比1小,若赋值为0,输出的结果都为0,就会出现错误。
例2:统计学生平均成绩与不及格人数
从键盘输入一批学生的成绩,计算平均成绩,并统计不及格学生的人数。以负数作为结束标志。
#include <stdio.h>
int main(void)
{
int count, num; /*num记录输入的个数,count记录不及格人数*/
double score, total; /*分别存放成绩、成绩之和*/
num = 0;
total = 0;
count = 0;
printf("Enter scores:");
scanf("%lf", &score);
/*当输入数据score大于等于0时,执行循环*/
while (score >=0 ){
total = total+score; /*累加成绩*/
num++; /*计数*/
if (score < 60){
count++;
}
scanf("%lf", &score); /*读入一个新数据,为下次循环做准备*/
}
if (num != 0){
printf("Average is %.2f\n", total/num);
printf("Number of failure is %d\n", count);
} else {
printf("Average is 0\n");
}
return 0;
}
Enter scores:88 99 67 87 90 100 90 -4
Average is 88.71
Number of failure is 0
本程序选择了一个异常数据作为循环结束的条件,这个是伪数据,不会在最终结果中体现。
2、do-while语句
for语句和while语句都是在循环前先判断条件,只有条件满足才会执行循环,如果刚开始条件就不满足,那么循环一次都不会执行。而do-while语句是先执行循环体,再判断循环条件,do-while语句无论循环条件的值如何,至少执行一次循环体。其一般形式为:
do {
循环体语句
} while (表达式);
其流程图如下:

do-while语句与while语句除掉执行循环体与判断循环条件的先后顺序不同外,其他没有什么不同。即循环初始化要在do-while语句之前做,改变循环条件要在循环体语句做。
do-while语句适用于先循环、后判断的情况,如果有些需要至少执行一次的循环,那么do-while语句较合适。
注: (1)do-while语句的大括号不能省略
(2)do-while语句后的分号不能省略
例1:统计整数的位数
从键盘读入一个整数,统计该数的位数。例如,输入12534,输出5,;输入-99,输出2;输入0,输出1。
#include <stdio.h>
int main(void){
int count, number, t_number; /*count记录整数number的位数*/
count = 0;
printf("Enter a number:");
scanf("%d", &number);
t_number = number; /*保护输入数据number的值不被改变*/
if (number < 0){ /*将输入的负数转换为整数*/
t_number = -t_number;
}
do {
count++; /*位数加1*/
t_number = t_number/10; /*整除后减少一位个位数,组成一个新数*/
} while (t_number != 0); /*判断循环条件*/
printf("It contains %d digits.\n", count);
return 0;
}
Enter a number:12534
It contains 5 digits.
Enter a number:-99
It contains 2 digits.
Enter a number:0
It contains 1 digits.
这个程序至少要执行一次循环,因为输入的整数至少是1位数。本例中若输入的负数不转换为正数,那么结果也是相同的,因为整数的除法是相同的,且大于-10的整数除以10也为0。
例2:逆序输出一个整数
输入一个整数,将其逆序输出。例如,输入12345,输出54321。
#include <stdio.h>
int main(void)
{
int number;
printf("Enter a number:"); /*输入提示*/
scanf("%d", &number);
do {
printf("%d", number%10);
number = number/10;
} while (number != 0);
return 0;
}
Enter a number:12345
54321
Enter a number:500
005
本例程仅适用于正整数的逆序输出。若要实现负数,则将其想转换成正整数在进行处理。
整数的拆分与组合: C语言中对于整数的拆分和组合所使用的就是除(/
)和取余(%
)运算符。如一个数对10取余,则得到0~9的数,而如果要去掉最末一位数,仅需要对除以10。例:12345/10
的结果是1234
,12345%10
的结果是5
,通过循环使用/
与%
可以满足整数的拆分和组合需求。
参考 C语言程序设计(第4版)/何钦铭,颜晖
例题及课后习题参考程序https://gitee.com/sgxgitee/mooc-c