关于C中int,char和EOF的混淆

时间:2015-09-22 15:28:08

标签: c char int eof

我正在学习K& R的经典C编程手册第2版,这是第17页的一个例子:

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

在书中说明int c用于保留EOF,结果证明是-1在我的Windows机器中使用GCC而且不能charchar c代表。但是,当我尝试int a = EOF; char b = EOF; char e = -1; printf("%d %d %d %c %c %c \n", a, b, e, a, b, e); 时,它没有问题。奇怪的是我尝试了更多:

-1 -1 -1

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

那么在没有编译器错误的情况下如何EOF分配EOF呢?

此外,鉴于-1b,内存中eFF上面都分配了EOF?不应该是编译器如何区分nbsEOF 0xFFFFFFFF ......?

更新

最有可能char 0xFF被投放到(c = getchar()) != EOF,但在0xFF中,LHS 0xFFFFFFFF在比较之前被提升为c,因此类型为{{1} }}可以是intchar

在这种情况下,EOF恰好是0xFFFFFFFF,但理论上EOF可以是需要超过8位才能正确表示的任何值,最左边的字节不一定是{{1}那么FFFFFF方法就会失败。

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

enter image description here

2 个答案:

答案 0 :(得分:2)

此代码有效,因为您使用的是已签名的 char。如果你看ASCII table,你会发现两件事:首先,只有127个值。 127取7位表示,最高位是符号位。其次,EOF不在此表中,因此操作系统可以根据需要自由定义它。

编译器允许从charint的分配,因为您要从较小的类型分配到较大的类型。 int保证能够代表char可以代表的任何值。

另请注意,0xFF在解释为unsigned char时等于255,在解释为signed char时等于-1:

0b11111111

但是,当表示为32位整数时,它看起来非常不同:

255 : 0b00000000000000000000000011111111
-127: 0b11111111111111111111111110000001

答案 1 :(得分:1)

EOF0xFF不一样。所以编译器必须区分它们。如果你看到man page for getchar(),你就知道它会在文件末尾或错误时将读取的字符作为无符号字符串转换为int或EOF。

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

((unsigned int)c != (unsigned int)EOF)