K&R《C程序设计语言》习题1-9:两段代码差异及失效原因咨询
K&R《C程序设计语言》习题1-9代码问题分析
需求是编写程序将输入复制到输出,把连续一个或多个空格替换为单个空格。
可正常运行的代码
int ch, last; for (last = 0; (ch = getchar()) != EOF; last = ch) if (ch == ' ' && last == ' ') ; else putchar(ch);
无法实现需求的代码
int ch, last; last = 0; while ((ch = getchar()) != EOF) if (ch == ' ' && last == ' ') ; else putchar(ch); last = ch;
差异与失效原因
两段代码的核心差异在于**last = ch语句的执行时机和范围**:
第一段的for循环中,
last = ch是for循环的「循环后操作」部分,每次循环处理完当前字符后,都会执行这条语句把last更新为当前的ch。这样下一次循环读取新的ch时,last保存的是上一个字符的值,能正确判断当前字符和上一个字符是否都是连续空格,从而跳过重复空格。第二段的while循环中,
last = ch没有被包含在循环体内!C语言里,if-else、while这类控制结构如果不用大括号{}包裹,只会作用于紧跟的第一条语句。这里while循环只执行后面的if-else语句,而last = ch是在循环体外,只会在整个while循环结束后执行一次。这就导致整个循环过程中last始终是初始值0,永远不会等于空格,判断条件ch == ' ' && last == ' '永远不成立,所有空格都会被原样输出,完全起不到去重的作用。
要修复第二段代码,只需把while循环内的语句用大括号包裹,让last = ch成为循环的一部分:
int ch, last; last = 0; while ((ch = getchar()) != EOF) { if (ch == ' ' && last == ' ') ; else putchar(ch); last = ch; }
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

