关于C中的int,char和EOF的困惑

mzo*_*zoz 5 c int char eof

我正在学习K&R的经典C编程书第二版,这是第17页的示例:

#include <stdio.h>
/* copy input to output*/
main()
{
    int c; 
    // char c works as well!!
    while ((c = getchar()) != EOF)
        putchar(c);
}
Run Code Online (Sandbox Code Playgroud)

它在int c用于保存的书中已有说明,该书EOF原来-1在我的Windows计算机中带有GCC,不能用表示char。但是,当我尝试时char c它没有问题。奇怪的是我尝试了更多:

int  a = EOF;
char b = EOF;
char e = -1;
printf("%d %d %d %c %c %c \n", a, b, e, a, b, e);
Run Code Online (Sandbox Code Playgroud)

并且输出-1 -1 -1不显示任何字符(实际上根据ASCII表,%c, c此处应该nbs(no-break space)显示但不可见)。

那么如何char分配EOF却没有任何编译器错误呢?

此外,鉴于EOF-1,都be上述分配FF在存储器?否则编译器如何区分EOFnbs...?

更新

最有可能EOF 0xFFFFFFFF被转换为,char 0xFF但在(c = getchar()) != EOFLHS 0xFF中int 0xFFFFFFFF在比较之前被提升为int,因此类型c可以是intchar

在这种情况下,EOF碰巧是,0xFFFFFFFF但理论上EOF可以是任何需要8位以上的值才能正确表示的情况(不一定是最左边的字节),FFFFFF因此char c方法将失败。

参考:K&R C编程语言2e

在此处输入图片说明

Wed*_*shi 5

EOF并且0xFF不一样。所以编译器必须区分它们。如果您查看 的手册页getchar(),您就会知道它会将读取为无符号字符的字符返回到文件末尾或错误时转换为 int 或 EOF 的字符。

while((c = getchar()) != EOF)的扩展为

((unsigned int)c != (unsigned int)EOF)
Run Code Online (Sandbox Code Playgroud)