[C陷阱]getchar的返回值是int而不是char

有如下代码:

//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. 某些合法的字符被“截断”了以后,恰好等于-1,导致程序在复制的过程中发生了中断。
  2. 前面的C不可能取值为EOF,导致程序产生了一个死循环。
还有一种情况,就是编译器对C语言的实现不够规范,尽管可能会产生第一种所说的“截断”和第二种中找不到“EOF”的情况,而且编译器也同时将值赋值给了C,但是,编译器里面却把getchar()返回的值与EOF进行比较了,反而导致结果是正确的。

疑问

上面是网上以及很多权威书籍(The C programming language、C陷阱与缺陷)上的说法。

但是,如果

  1. getchar()返回的是不是都是ASCII(编码范围为0-127)?如果是的话,上面1中的“截断”也不会有什么影响了,因为高位全是0。如果不是的话(比如汉字能用getchar读取么?),那是会出现“截断”导致程序过早退出。
  2. EOF除了-1(stdio.h中声明为-1),是否还可能是其它负值?
那么我们显式声明signed char c(不显式声明的话会根据具体的编译器而认为c是signed或unsigned),其取值范围为[-128,127],恰好可以存下所有的ASCII码和EOF。那么我们显式声明signed char c不就可以了?


但是为了保险起见,还是推荐声明int c。因为这样是肯定没有错误的。

你可能感兴趣的:(c,语言,编译器)