5.1 返回整数的getchar函数

 我们首先考虑下面的例子:

  
  
  
  
  1. #include <stdio.h> 
  2.  
  3. main() 
  4.  
  5.    char c; 
  6.  
  7.    while((c = getchar()) != EOF) 
  8.  
  9.        putchar(c); 
  10.  } 

  getchar函数在一般情况下返回的是标准输入文件中的下一个字符,当没有输入时返回EOF(一个在头文件stdio.h中被定义的值,不同于任何一个字符,一般是 -1)。这个程序咋一看似乎是把标准输入复制到标准输出,实则不然。

  原因在于程序中的变量c被声明为char类型,而不是int类型。这意味着c无法容下所有可能的字符,特别是,可能无法容下EOF。

  注解: 因为编译器实现char类型的方式有时是signed char,而有时是unsigned char。

  因此,最终结果存在两种可能。一种可能是,某些合法的输入字符在被“截断”后使得c的取值与EOF相同;另一种可能是,c根本不可能取到EOF这个值。对于前一种情况,程序将在文件复制的中途终止;对于后一种情况,程序将陷入一个死循环。

  注解: 对于第一种可能,本人认为发生截断后,不会给程序带来额外的影响。因为ASCII码字符一共就127个,也就是说char类型足以表示了,所以说截断和不截断没有什么区别,但要显示的不是ASCII码表中的字符,比如中文,就另当别论了;对于第二种情况就是当编译器实现的char为unsigned char类型时,会陷入死循环。

  实际上,还可能存在第三种情况: 程序表明上似乎能够正常工作,但完全是因为巧合。尽管函数getchar的返回结果在赋给char类型的变量c时会发生“截断”操作,尽管while语句中比较运算的操作数不是函数getchar的返回值,而是被“截断”的值c,然而令人惊讶地是许多编译器对上述表达式的实现并不正确。这些编译器确实对函数getchar的返回值作了“截断”处理,并把低端部分赋给了变量c。但是,它们在比较表达式中并不是比较c与EOF,而是比较getchar函数的返回值与EOF!编译器如果采取的是这种做法,上面的例子程序看上去就能够“正常”运行了。

你可能感兴趣的:(注解,c陷阱与缺陷)