C、K&R 练习 1-6,卡住,困惑

H3G*_*ght 4 c putchar getchar

我是一名菜鸟,自学使用《C 编程语言》第二版K&R编写)进行 C 语言编程。在第 1 章第1.5.1 节文件复制中,作者非常简要地介绍了在值之间进行比较时的操作优先级,强调了使用括号的重要性,在本例中,以确保在比较之前对变量“c”进行赋值被评估。他们断言:

    c = getchar() != EOF
Run Code Online (Sandbox Code Playgroud)

相当于

    c = (getchar() != EOF)
Run Code Online (Sandbox Code Playgroud)

其中“设置为 0 或 1 会产生不良影响c,具体取决于 getchar 的调用是否遇到文件结尾”

然后作者提出练习 1-6 - 验证表达式getchar () != EOF是 0 或 1

根据作者之前的断言,这看起来几乎微不足道,所以我创建了以下代码:

#include <stdio.h>

main()
{
    int c;

    while (c = (getchar() != EOF))
        putchar(c);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我运行该程序时,如果遇到 EOF,它只会输出我在命令窗口中键入的任何字符,而不是预期的 1 或 0 字符串。

虽然我是一个菜鸟,但我认为我明白了作者试图教授的逻辑,但我无法演示这个简单的任务。在这种情况下,变量不应该c采用比较表达式求值的值,而不是恰好getchar()获取的任何字符,特别是因为括号的位置?如果c确实采用比较的值,则putchar()应该只输出 0 或 1,但按照公式,它会输出我在命令窗口中键入的内容。我究竟做错了什么?我不明白什么?难道是我的编译器的问题?我正在 x64 架构的 Windows 10 上的 Visual Studio 2017 Community 版本中进行编码。我有 Tiny C 编译器,但还没有尝试使用 TCC 从命令提示符执行。

iBu*_*Bug 6

当您运行该程序时,您看到的字符并非来自您的程序。它是控制台(或终端)的回显功能,可以显示您输入的任何字符(您甚至可以在按 Enter 之前删除它们)。您的程序仅输出ASCII 代码 0 或 1 的字符,这两者都是不可见的。

如果更改putchar(c)为,printf("%d", c)您将能够看到一系列1s。不会出现零,因为当c变为零时,循环停止并且不会被打印。

尽管您的终端可能使用其他编码,但字符'0'和的 ASCII 代码分别为 48 和 49。'1'如果要输出文字数字 0,请使用字符表示法。您也可以尝试putchar(48),但不要过多使用它(稍后您会发现非常不鼓励在程序中使用幻数)。

putchar('0');
        ^ ^
Run Code Online (Sandbox Code Playgroud)

断言

c = getchar() != EOF;
Run Code Online (Sandbox Code Playgroud)

相当于

c = (getchar() != EOF);
Run Code Online (Sandbox Code Playgroud)

是因为运算符优先级。运算符!=(不等式)比(赋值)具有更高的优先级=,因此它会在赋值之前进行评估。

最后,很少有人写出这样的文章。正确的意图是这样写:

while ( (c = getchar()) != EOF )
Run Code Online (Sandbox Code Playgroud)