第 6 章 C 控制语句:循环
6·1 再谈 while 循环
明确一件事,在C中,只有0被视为假,所有非零值都是真
在第五章有过对 while 循环的简单叙述,可以去看看书
以下是 while 循环的应用实例,我加了一些注释以便复习和阅读:
#include <stdio.h>
int main(void) {
long num;
long sum = 0L; //初始化为0
int status; //判断器
printf("Please enter an integer to be summed");
printf("(q to quit):");
status = scanf_s("%ld", &num);
/*
注意:
printf 的返回值是 ==打印字符的个数== ,如果输出错误,则返回一个负数;
scanf 的返回值是 ==成功读取的项数== ,如果没有读取任何项,或读取错误,则返回 0 ;
*/
while (status == 1) {
/*
用上面 scanf_s 的返回值作为判断条件
要求输入数字,所以输入 q 的时候会返回0
*/
sum = sum + num;
printf("Please enter next integer (q to quit):");
status = scanf_s("%ld", &num);
}
printf("Those integer sum to %ld.\n", sum);
return 0;
}
结果:
Please enter an integer to be summed(q to quit):12
Please enter next integer (q to quit):33
Please enter next integer (q to quit):21
Please enter next integer (q to quit):1
Please enter next integer (q to quit):0
Please enter next integer (q to quit):q
Those integer sum to 67.
-
关于 “告诉循环何时停止”:
在本程序中我们应用了 scanf()的返回值 的特性 避免 了在循环中交互输入时的棘手问题
例如:
如果使用 num 的值来结束循环,比如:
num > 0
或num != 0
作为测试条件,但是这样会导致不能输入某些值(-1,0 …)如果在每次循环结束的时候都询问用户 “ 是否结束循环?(Y / N)”,然后对用户输入的值进行判断,那未免太麻烦
综上,使用 scanf()的返回值是一个好选择
-
因为 while 循环是 入口循环 ,程序在进入循环体之前必须获取输入的数据并检查 status 的值,所以 while 前面必须要有一个 scanf_s()。要让循环继续进行,再循环内必须有一个读取数据的语句,如此程序才能获取下一个 status 的值,所以在 while 循环 末尾 还要有一个 scanf_s()。它为下一次 迭代 做了准备,以下用为代码作为 while 循环的标准格式:
获取第一个测试数据
当测试为真
处理值
获取下一个测试值
- 另一种思路:
status = scanf_s("%ld", &num);
while (status == 1){
//循环的行为
status = scanf_s("%ld", &num);
}
可以用下面的方式替换:
while (scanf_s("%ld", &num) == 1){
//循环的行为
}
这种方式同时使用了 scanf_s()的两种特性:
1. 如果函数调用成功,scanf_s()会把一个值存入 num,然后返回 1 用于控制循环
2. 每次迭代都会判断循环条件,每次都要输入新的值 num 来判断
以下是相应的伪代码:
当获取值和判断都成功
处理该值
6·2 while 语句
以下是 while 语句的实现方式:
6·2·1 终止 while 循环
(没有学到 break 和 if 的时候)
在构建 while 循环时,必须让 测试表达式的值有所变化,表达式最终要为假,才会退出循环
在开篇的那种方式就是其中一种
以下是另一种方式,即设定一个计数器:
int index;
index = -1;
while(++index<5){
//先对 index 累加,然后比较,最后执行 while 的循环语句
printf("Hello.\n");
}
//结果是打印五个 Hello
6·2·2 何时终止循环
明确一点:只有在 对测试条件求值 时,才决定是终止还是继续循环
#include <stdio.h>
int main(void) {
int index;
index = -1;
while (index < 5) {
printf("Time: %2d.\n", index);
index++;
//先求值,后检验
}
printf("Now, the time is: %2d.\n", index);
//最后一次循环结束时 index 被更新为 5,未通过检测,执行下一条语句
return 0;
}
结果:
Time: -1.
Time: 0.
Time: 1.
Time: 2.
Time: 3.
Time: 4.
Now, the time is: 5.
补充:关于 _Bool 类型
注意:使用该类型时,关键是“如何命名是的其含义明显”
#include <stdio.h>
int main(int argc, const char * argv[]) {
long num;
long sum = 0L;
_Bool input_is_good; // _Bool 类型,其值仅为 0 或者 1
/*
当 #include <stdbool.h> 后
可以用 bool 代替 _Bool
同时把 true,false 定义为 1 和 0 的符号常量
这样可以将程序与C++兼容
注意:若系统不支持_Bool类型,可以将其改为int
*/
printf("请输入一个整数(q to quit):");
input_is_good = (scanf("%ld", &num) == 1); // _Bool 的使用方式
while (input_is_good) {
sum += num;
printf("下一个(q to quit):");
input_is_good = (scanf("%ld", &num) == 1);
}
printf("结果为:%ld\n", sum);
return 0;
}