You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何这段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"的执行流程例子:

  1. 第一次循环:c读取到空格,进入if分支,输出空格,标记last_was_space为1;
  2. 第二次循环:c读取到'o',进入else分支,输出'o',标记重置为0;
  3. 后续循环依次读取'n'、'e'、空格、空格、't'等,每次循环的c都是新读取的字符,自然不再是之前的空格。

澄清作用域的误解

你担心的作用域问题在这里并不存在:只有当变量定义在if、循环等代码块内部时(比如if (c == ' ') { int temp; }),才会有局部作用域,离开块就无法访问。而你的代码中c定义在main开头,属于函数级变量,整个main函数内的所有分支、循环都能访问同一个c,不存在变量被销毁或无法访问的情况。

内容的提问来源于stack exchange,提问作者harlandski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:12:09