为何这段K&R练习1.9的代码中必须显式调用putchar(' ')?
解答:练习1.9中
putchar(' ')的作用及变量逻辑解析 首先明确练习1.9的核心需求:将输入中的连续多个空格替换为单个空格,非空格字符正常输出,单个空格也需保留。
为什么必须加入putchar(' ')?
咱们拆解正确代码的执行逻辑(对应你提到的Lvictor解决方案):
#include <stdio.h> int main() { int c; int last_was_space = 0; // 标记上一个输出的是否为空格 while ((c = getchar()) != EOF) { if (c == ' ') { if (!last_was_space) { putchar(' '); // 你困惑的这行代码 last_was_space = 1; } } else { putchar(c); last_was_space = 0; } } return 0; }
- 当读取到第一个空格时,
last_was_space为0(表示之前没输出过连续空格),此时必须用putchar(' ')输出这个空格,否则这个唯一需要保留的空格会被直接跳过; - 后续遇到连续空格时,因为
last_was_space已经被设为1,会跳过输出,避免重复空格。
如果去掉这行代码,第一次遇到空格时只会标记last_was_space为1,但根本不输出空格;后续连续空格也会被跳过,最终所有空格都被过滤,完全不符合需求。
关于“退出if语句后c的值不再是空格”的疑问
这和变量作用域无关,是程序的循环执行逻辑导致的:
c是定义在main函数开头的变量,在整个函数范围内都有效,不存在作用域导致的变量失效问题;- 每次循环都会执行
c = getchar(),也就是每次循环都会读取一个新的字符覆盖掉c原来的值。
举个输入" one two"的执行流程例子:
- 第一次循环:
c读取到空格,进入if分支,输出空格,标记last_was_space为1; - 第二次循环:
c读取到'o',进入else分支,输出'o',标记重置为0; - 后续循环依次读取
'n'、'e'、空格、空格、't'等,每次循环的c都是新读取的字符,自然不再是之前的空格。
澄清作用域的误解
你担心的作用域问题在这里并不存在:只有当变量定义在if、循环等代码块内部时(比如if (c == ' ') { int temp; }),才会有局部作用域,离开块就无法访问。而你的代码中c定义在main开头,属于函数级变量,整个main函数内的所有分支、循环都能访问同一个c,不存在变量被销毁或无法访问的情况。
内容的提问来源于stack exchange,提问作者harlandski
相关产品推荐
相关产品推荐

