The C Programming Language Second edition K&R 第 1 章 1.5.1 中的示例,

Example in Chapter 1, 1.5.1, of The C Programming Language Second edittion K&R,

int c;

while ((c = getchar()) != EOF)
    putchar(c);

"This value is called EOF, for "end of file". We must declare c to be a type big enough to hold EOF in addition to any possible char. Therefore we use int."

如有错误请指正:

当我在上面的程序中用 char 替换 int 时,它似乎按预期工作,但经过一些研究我发现它不是因为变量 c无法存储 -1 又名 EOF(尽管使用 char)。

我 运行 无论如何都试图让它崩溃,我试着输入负数,比如 -1 但它没有用。我相信这是因为它被解释为 2 个不同的字符 -1。我试了一下ÿ根据http://ascii-code.com/是ascii值255对应的字符, 那么上面的程序(使用 char 而不是 int)对于什么输入会崩溃?

(供参考,我使用的是 64 位软呢帽 Linux)

C char 中未指定有符号或无符号可能会崩溃的原因。它可以在您的机器上运行良好,但在其他机器上可能会失败。 还有 getchar() 函数 return int 值,所以你应该使用 int 变量来得到这个 returning 值。

之前在其他答案中已经解释过,但有时找到重复比给出答案更难。

普通 char 类型可以是有符号或无符号的。

函数 getchar() returns EOF 或 ... 获取该字符作为 unsigned char 转换为 int... (引用 fgetc() 的标准,但它也适用于 getchar())。

如果你有一个无符号的普通 char 类型,那么赋值将生成一个值 0..255 然后将其提升为 int 以与 EOF 进行比较,并且由于 [=值 0..255 中的 40=] 是负数,测试将始终失败 — 并且循环不会停止,直到您通过其他方式(中断、重启等)终止程序。

如果你有一个带符号的普通 char 类型,那么赋值将同时处理一个有效字符(通常是 ÿ — U+00FF,带分音符的拉丁文小写字母 Y,如果你使用的是单字节代码集(例如 ISO 8859-15)和 EOF 作为标记 EOF,因此循环可能会在某些文件上过早终止。

因此,根据机器,循环:

char c;

while ((c = getchar()) != EOF)
    ;

可能是无限循环,也可能在某些数据文件的 EOF 之前终止。两者都不是正确的行为——而且这两种行为都不是崩溃。 (问题中的代码不会崩溃。)将 c 的类型更改为 int 可以可靠且可移植地解决这两个问题。

请注意,如果您使用的是 UTF-8 语言环境,则不会生成十六进制 0xFF 字节;这不是 UTF-8 中的有效字节(U+00FF 在 UTF-8 中被编码为两个字节 0xC3 0xBF)。