C语言之妙:scanf 的双重作用


C语言之妙:scanf 的双重作用

文章插图
 
我们尝试用scanf做累加运算:
/* summing.c -- sums integers entered interactively */#include <stdio.h>int main(void){long num;long sum = 0L;/* initialize sum to zero*/int status;printf("Please enter an integer to be summed ");printf("(q to quit): ");status = scanf("%ld", &num);while (status == 1) /* == means "is equal to"*/{sum = sum + num;printf("Please enter next integer (q to quit): ");status = scanf("%ld", &num);}printf("nThose integers sum to %ld.n", sum);return 0;}该程序使用long类型以存储更大的整数 。尽管C编译器会把0自动转换为合适的类型 , 但是为了保持程序的一致性 , 我们把sum初始化为0L(long类型的0) , 而不是0(int类型的0) 。该程序的运行示例如下:
Please enter an integer to be summed (q to quit): 44
Please enter next integer (q to quit): 33
Please enter next integer (q to quit): 88
Please enter next integer (q to quit): 121
Please enter next integer (q to quit): q
Those integers sum to 286.
分布解析先看while循环 , 该循环的测试条件是如下表达式:
status == 1运算符是C的相等运算符(equality-operator) , 该表达式判断status是否等于1 。不要把status == 1 与 status = 1混淆 , 后者是把1赋给status 。根据测试条件status == 1 , 只要status等于1 , 循环就会重复 。每次循环 , num的当前值都被加到sum上 , 这样sum的值始终是当前整数之和 。当status的值不为1时 , 循环结束 。然后程序打印sum的最终值 。
要让程序正常运行 , 每次循环都要获取num的一个新值 , 并重置status 。程序利用scanf()的两个不同的特性来完成 。首先 , 使用scanf()读取num的一个新值;然后 , 检查scanf()的返回值判断是否成功获取值 。第4章中介绍过 , scanf()返回成功读取项的数量 。如果scanf()成功读取一个整数 , 就把该数存入num并返回1 , 随后返回值将被赋给status(注意 , 用户输入的值存储在num中 , 不是status中) 。
这样做同时更新了num和status的值 , while循环进入下一次迭代 。如果用户输入的不是数字(如 , q) , scanf()会读取失败并返回0 。此时 , status的值就是0 , 循环结束 。因为输入的字符q不是数字 , 所以它会被放回输入队列中(实际上 , 不仅仅是q , 任何非数值的数据都会导致循环终止 , 但是提示用户输入q退出程序比提示用户输入一个非数字字符要简单) 。
如果scanf()在转换值之前出了问题(例如 , 检测到文件结尾或遇到硬件问题) , 会返回一个特殊值EOF(其值通常被定义为-1) 。这个值也会引起循环终止 。如何告诉循环何时停止?该程序利用scanf()的双重特性避免了在循环中交互输入时的这个棘手的问题 。例如 , 假设scanf()没有返回值 , 那么每次循环只会改变num的值 。虽然可以使用num的值来结束循环 , 比如把num > 0(num大于0)或num != 0(num不等于0)作为测试条件 , 但是这样用户就不能输入某些值 , 如-3或0 。也可以在循环中添加代码 , 例如每次循环时询问用户“是否继续循环?<y/n>” , 然后判断用户是否输入y 。这个方法有些笨拙 , 而且还减慢了输入的速度 。使用scanf()的返回值 , 轻松地避免了这些问题 。
伪码现在 , 我们来看看该程序的结构 。总结如下:
initialize sum to 0prompt userread inputwhile the input is an integer,add the input to sum,prompt user,then read next inputafter input completes, print sum顺带一提 , 这叫作伪代码(pseudocode) , 是一种用简单的句子表示程序思路的方法 , 它与计算机语言的形式相对应 。伪代码有助于设计程序的逻辑 。确定程序的逻辑无误之后 , 再把伪代码翻译成实际的编程代码 。使用伪代码的好处之一是 , 可以把注意力集中在程序的组织和逻辑上 , 不用在设计程序时还要分心如何用编程语言来表达自己的想法 。例如 , 可以用缩进来代表一块代码 , 不用考虑C的语法要用花括号把这部分代码括起来 。


推荐阅读