有如下代码:
//char c;//错误
int c; /* 正确。应该使用 int 型变量接收 fgetc 的返回值 */
while ( (c = getchar()) != EOF )
{
putchar(c);
}
getchar 等函数的返回值类型都是 int 型,当这些函数读取出错或者读完文件后,会返回 EOF.EOF 是一个宏,标准规定它的值必须是一个 int 型的负数常量。通常编译器都会把 EOF 定义为 -1.getchar返回的int赋值给char c的时候会发生截断,和EOF比较时又会升级为int,可能会发生如下错误:
- 某些合法的字符被“截断”了以后,恰好等于-1,导致程序在复制的过程中发生了中断。
- 前面的C不可能取值为EOF,导致程序产生了一个死循环。
还有一种情况,就是编译器对C语言的实现不够规范,尽管可能会产生第一种所说的“截断”和第二种中找不到“EOF”的情况,而且编译器也同时将值赋值给了C,但是,编译器里面却把getchar()返回的值与EOF进行比较了,反而导致结果是正确的。
疑问
上面是网上以及很多权威书籍(The C programming language、C陷阱与缺陷)上的说法。
但是,如果
- getchar()返回的是不是都是ASCII(编码范围为0-127)?如果是的话,上面1中的“截断”也不会有什么影响了,因为高位全是0。如果不是的话(比如汉字能用getchar读取么?),那是会出现“截断”导致程序过早退出。
- EOF除了-1(stdio.h中声明为-1),是否还可能是其它负值?
但是为了保险起见,还是推荐声明int c。因为这样是肯定没有错误的。