3.1 while 与 do-while 循环
循环(loop)用于重复执行一段代码。while 循环会先判断条件(condition),只要条件成立(非 0),就执行循环体;循环体执行完后,再回到条件处重新判断。
while 的基本结构
一个稳定的 while 循环通常包含三件事:
- 初值:循环开始前,先准备循环变量。
- 条件:每一轮开始前,判断是否继续循环。
- 更新:每一轮循环中,让循环变量发生变化。
int i = 1; // 初始值
while (i <= 5) { // 条件
printf("循环中:i = %d\n", i);
i++; // 更新
}
printf("循环结束后:i = %d\n", i);运行结果:
循环中:i = 1
循环中:i = 2
循环中:i = 3
循环中:i = 4
循环中:i = 5
循环结束后:i = 6while 的特点是先判断、再执行。因此循环体可能执行多次,也可能一次都不执行。如果忘记更新循环变量,条件会永远成立,循环就会变成无限循环。
累加与平均值
循环经常和累加变量一起使用。下面的程序读取 5 个人的身高,并计算平均值。
#include <stdio.h>
int main(void) {
int num_people = 5;
double total = 0;
int i = 1;
while (i <= num_people) {
double height;
printf("请输入第 %d 个人的身高:", i);
scanf("%lf", &height);
total += height;
i++;
}
double average = total / num_people;
printf("平均身高:%.2f\n", average);
return 0;
}一次可能的运行过程:
请输入第 1 个人的身高:160.8
请输入第 2 个人的身高:175.2
请输入第 3 个人的身高:171.2
请输入第 4 个人的身高:181.3
请输入第 5 个人的身高:164
平均身高:170.50total += height 的意思是把本次输入的身高加到累计总和里。循环结束后,total 保存的是所有身高之和。
循环直到条件改变
while 适合处理“循环次数不一定一开始就知道”的任务。例如,计算一个整数有多少位。
int num;
scanf("%d", &num);
if (num < 0) {
num = -num;
}
int digits;
if (num == 0) {
digits = 1;
} else {
digits = 0;
while (num != 0) {
num /= 10;
digits++;
}
}
printf("位数:%d\n", digits);一次可能的运行结果:
请输入一个整数:123
位数:3这里额外处理了 0。如果直接写 while (num != 0),输入 0 时循环一次也不会执行,位数会被错误地算成 0。
猜数字游戏
还有一种常见场景是:程序不知道用户需要尝试多少次。猜数字游戏就是一个典型例子。程序先随机生成答案,然后不断读取用户输入;如果猜大了就提示“太大”,猜小了就提示“太小”,猜中后用 break 结束循环。
rand() 用来生成随机数,它来自标准库 <stdlib.h>;srand(time(NULL)) 用当前时间作为随机种子,time 来自 <time.h>。rand() % 100 + 1 会得到 1 到 100 之间的随机整数。标准库会在第 6 章系统介绍。#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
int answer = rand() % 100 + 1;
int cnt = 0;
int num;
while (1) {
printf("请猜一个数字:");
scanf("%d", &num);
cnt++;
if (num > answer) {
printf("太大\n");
} else if (num < answer) {
printf("太小\n");
} else {
break;
}
}
printf("猜对了!你一共猜了 %d 次。\n", cnt);
return 0;
}这里的 while (1) 会制造一个条件永远成立的无限循环(infinite loop)。它不会自动结束,必须依靠循环体内部的 break 在猜中时主动跳出。
do-while
C 还提供 do-while 循环。它把条件放在循环体后面,所以会先执行一次循环体,再判断条件,因此至少执行一轮。注意末尾 while (条件); 后面有一个分号,很容易漏掉。
int num;
do {
printf("请输入一个正数:");
scanf("%d", &num);
} while (num <= 0);
printf("你输入的正数是:%d\n", num);无论用户第一次输入什么,循环体都会先执行一次(先问一次);只有当输入不满足 num <= 0(即输入了正数)时才结束。它特别适合菜单、输入验证等“至少要问一次”的场景。
| 循环 | 先判断条件吗? | 最少执行次数 |
|---|---|---|
while | 是 | 0 次 |
do-while | 否,先执行循环体 | 1 次 |