我正在学习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而且不能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);
时,它没有问题。奇怪的是我尝试了更多:
-1 -1 -1
并且输出为%c, c
且没有显示任何字符(实际上根据nbs(no-break space)
的ASCII表,此处应显示char
但它不可见)。
那么在没有编译器错误的情况下如何EOF
分配EOF
呢?
此外,鉴于-1
是b
,内存中e
和FF
上面都分配了EOF
?不应该是编译器如何区分nbs
和EOF 0xFFFFFFFF
......?
更新:
最有可能char 0xFF
被投放到(c = getchar()) != EOF
,但在0xFF
中,LHS 0xFFFFFFFF
在比较之前被提升为c
,因此类型为{{1} }}可以是int
或char
。
在这种情况下,EOF
恰好是0xFFFFFFFF
,但理论上EOF
可以是需要超过8位才能正确表示的任何值,最左边的字节不一定是{{1}那么FFFFFF
方法就会失败。
参考: K&amp; R C编程语言2e
答案 0 :(得分:2)
此代码有效,因为您使用的是已签名的 char
。如果你看ASCII table,你会发现两件事:首先,只有127个值。 127取7位表示,最高位是符号位。其次,EOF
不在此表中,因此操作系统可以根据需要自由定义它。
编译器允许从char
到int
的分配,因为您要从较小的类型分配到较大的类型。 int
保证能够代表char
可以代表的任何值。
另请注意,0xFF
在解释为unsigned char
时等于255,在解释为signed char
时等于-1:
0b11111111
但是,当表示为32位整数时,它看起来非常不同:
255 : 0b00000000000000000000000011111111
-127: 0b11111111111111111111111110000001
答案 1 :(得分:1)
EOF
和0xFF
不一样。所以编译器必须区分它们。如果你看到man page for getchar()
,你就知道它会在文件末尾或错误时将读取的字符作为无符号字符串转换为int或EOF。
您的while((c = getchar()) != EOF)
已扩展为
((unsigned int)c != (unsigned int)EOF)