【问题标题】:I am reading "The C Programming Language" (2ed) and I didn't understand a concept:我正在阅读“The C Programming Language”(第 2 版),但我不理解一个概念:
【发布时间】:2021-09-18 08:34:57
【问题描述】:

我正在阅读“C 编程语言”(第 2 版),但我没有理解一个概念。

有这段代码可以将输入复制到输出

#include <stdio.h>

main()
{
    int c;
    c = getchar();
    while (c != EOF) {
        putchar(c);
        c = getchar();
    }
}

一开始,c 被声明为int 类型变量,但如果我写了类似“测试线”的东西,输出就是预期的“测试线”。我的问题是:c 如何声明为int 类型变量,但程序存储的空间足以存储大量字符? “内部”计算机,它注册为一个字符数组?这个过程是如何工作的?

【问题讨论】:

  • c 表示单个字符。
  • 您可能对these course notes 感兴趣,写在您正在阅读的章节中。
  • 程序不会存储所有这些字符,一次只存储一个,它会输出然后忘记。
  • 您在这个程序中没有任何数组:不是char 的数组,int 的数组。那是因为根本不需要一次存储一整套字符(一个单词、一行或整个文件)。此代码一次对一个字符进行操作:输入一个,输出一个,重复。
  • 我想我现在明白了。代码不会全部存储在一个地方。它对每个字符重复该过程,从标准输入存储在这些缓冲区中,然后显示给用户。感谢您的解释

标签: arrays c integer


【解决方案1】:

假设我正在为我的朋友调酒。我面前有四个眼镜。我想在每个玻璃杯中加入 1/8 杯(1 杯)杜松子酒。但我没有 1/8 杯量杯。所以我拿了一个 1/4 杯量杯,我把它装满了一半,这样我每杯量了 1/8 杯酒。

我使用 1/4 杯的量器来测量 1/8 杯的液体是否有问题?顶部的所有空白空间怎么办?好吧,显然,它根本不会造成任何问题。

同样,如果您使用 int(可能是 16 位或 32 位变量)来保存调用 getchar() 的返回值,即使大多数从getchar 返回的字符值只有 8 位。

但是当getchar 将代码EOF(文件结尾)返回给您时,它有所作为! EOF 是一个适合 8 位的值,因为它(根据定义)不是 8 位字符值。这就是为什么使用int 变量来处理从getchar 返回的值很重要的原因,而不是看起来很明显的char

【讨论】:

  • 我不认为这是问题所在,而是整个输入“测试行”如何保存在单个变量中。
  • @WeatherVane 也许不是,但我希望它能提供一些见解。
【解决方案2】:

首先,一些背景。

字符是字符串的一个元素。一个字符是一个数字

您在屏幕上看到的字形(ab 等)只是您的终端如何解释它收到的数字(97、98 等)。

在C程序中,两者绝对没有区别

'a'
97

两者都是int 类型的整数文字,值为97。 (我在这里假设基于 ASCII 的机器。它们在基于 EBCDIC 的机器上实际上是不同的。)


现在回答你的问题。

但是程序存储的空间足以容纳很多字符?

它没有。 c 在任何给定时间仅包含一个字符。第一次通过循环,116 aka 't' 被分配给它。第二次通过循环,101 aka 'e' 被分配给它。等等

【讨论】:

  • 次要:“两者都是 int 类型的整数文字”--> C 称它们为 constants。 C 有 2 个 literalsstringcompound
  • @chux - 恢复莫妮卡,我不是说不变。您可以将常量分配给变量,但不能将文字分配给变量。常量是一个值,但文字是一段代码。当然,它们会产生常量,但这不是重点。
【解决方案3】:

如何将“c”声明为 int 类型变量,但程序存储的空间足以容纳大量字符?

显示的源代码没有存储很多字符。它一次处理一个字符。

c = getchar(); 将一个输入字符的代码放入c。然后putchar(c); 将该代码写入输出。然后程序可以忘记角色。它不再需要它,它可以得到一个新的字符代码并为此重用c

在将它们写入输出设备之前,输出流可能会在缓冲区中保存大量字符,但这是在单独的源代码中,而不是直接在显示的源代码中。它是 C 标准库的一部分。

【讨论】:

    【解决方案4】:

    但如果我写了“测试线”之类的东西,那么输出就是预期的“测试线”。

    如何将“c”声明为 int 类型变量但程序存储的空间足以容纳大量字符?

    所有输入不会同时存储在变量c 中,而是存储在输入和输出缓冲区中。变量c 一次处理一个字符。

    让我们了解事件的顺序。

    1. main() 启动并运行到getchar()

    2. getchar() 等待输入。

    3. 用户类型t,操作系统缓冲字符。

    4. 用户类型 e s ...., e 操作系统会缓冲这些字符。

    5. 用户键入Enter,操作系统缓冲字符'\n'并将缓冲区提供给stdin,以便getchar()开始使用。

    6. getchar() 返回t 并保存在c

    7. 代码继续putchar(c); 并将t 放入stdout 缓冲区中。

    8. 代码继续getchar();,返回缓冲的e并保存在c中。

    9. 代码继续到putchar(c); 并将e 放入stdout 缓冲区中。

    10. st line 重复 8 - 9 次。

    11. 代码继续getchar();,返回缓冲的\n并保存在c中。

    12. 代码继续到putchar(c); 并将\n 放入stdout 缓冲区。缓冲区现在被刷新到 OS 输出终端。输出现在可见。

    13. 返回步骤 2,直到没有可用的输入。

    【讨论】:

    • 谢谢!我不知道操作系统中的缓冲区。现在它更有意义了!
    【解决方案5】:
    • 有的叫io buf,有的叫返回值
    • 具体可以理解为getchar读取chars到io buffer,并一一返回给api用户

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多