为什么用于存储getchar返回值的变量必须声明为int?

17

我是C编程语言的初学者,最近学习了getchar函数,它可以从控制台或文件中接受一个字符,边输入边立即显示出来,需要按下Enter键才能继续。

它返回读取的unsigned char。如果遇到文件结束或错误,getchar()函数会返回EOF。

我的问题是,当它返回unsigned char时,为什么它的返回值被存储在int变量中?

请帮帮我。


5
一个好的链接:EOF 的定义以及如何有效地使用它 - Grijesh Chauhan
2
可能是getchar / fgetc和putchar / fputc中int和char之间的区别?的重复问题。 - Antti Haapala -- Слава Україні
4个回答

19

正是因为存在EOF值,因为文件中的字符可以是任何可能的字符值,包括C字符串用于终止的空字符,getchar() 必须使用一个更大的整数类型来添加EOF值。

它只是恰好使用int类型来实现这个目的,但它也可以使用任何至少具有9位的类型。


2
一个文件中的字符可能具有任何可能的字符值,但从 getchar() 返回的值是字符的 unsigned char 值,而不是它的 char 值。 - chux - Reinstate Monica

4

返回类型为int,以容纳特殊值EOF。

EOF是一个宏,它扩展为具有int类型和实现相关的负值的整数常量表达式,但通常为-1。


2
请阅读此链接:链接 文中指出: 在将字符 I/O 函数的返回值转换为 char 类型并将其与 EOF 进行比较之前,请勿将其转换为 char 类型。一旦这些函数的返回值已被转换为 char 类型,则字符值可能无法与 EOF 区分。另外,如果 sizeof(int)==sizeof(char),则用于捕获返回值的 int 可能与 EOF 无法区分。有关当 sizeof(int)==sizeof(char) 时更多细节,请参见 FIO35-C. 使用 feof() 和 ferror() 检测文件结束和文件错误。有关适当使用字符类型的更多信息,请参见 STR00-C. 使用适当的类型表示字符。
此规则适用于所有字符 I/O 函数的使用。

0

getchar函数返回一个int类型的值,该值:

  • 如果函数成功,则表示流中下一个字符的字符代码,范围在unsigned char(即非负值)之内;或者

  • 如果函数失败,则表示特殊值EOF(即负值),以指示失败。

getchar函数总是返回:

  • 对于有效字符,返回一个非负数;
  • 对于失败,返回一个负数。

原因是必须能够区分有效字符和特殊值EOF(表示失败且不是有效字符)。

如果将getchar函数的int返回值存储在unsigned char中,则会丢失信息,并且将无法区分有效字符和特殊值EOF

在大多数平台上,EOF被定义为值-1,而unsigned char可以表示范围0255。 在这些平台上,以下情况适用:

函数getchar可以返回范围在-1255之间的int值,即有257个可能的值。 范围0255(共256个可能的值)用于有效字符代码,而值-1用于指示失败(EOF)。

如果您将getchar的返回值以unsigned char类型的变量保存,那么您只有256个可能的值,而不是257个。 值-1将转换为值255。 这意味着unsigned char变量无法表示值EOF,因此您将无法确定getchar返回了值EOF还是返回了有效字符代码255。 值255可以表示两种含义。
如果你将getchar的返回值存储在一个signed char类型的变量中,你会遇到类似的问题,因为signed char只能表示256个不同的值,但你需要能够表示257个不同的值。即使signed char有表示EOF值的优势,你仍然无法区分EOF和有效字符,因为值-1可以同时表示两者。它既可以表示EOF,也可以表示字符代码为255的有效字符。
因此,你应该始终首先将getchar的返回值存储在一个int类型的变量中。只有确定getchar没有返回EOF后,才可以安全地将返回值存储在unsigned charsigned char类型的变量中,因为你不再需要区分有效字符和特殊值EOF
同样的情况也适用于将 getchar 的返回值存储在 char 中。在某些平台上,char 等同于 signed char,而在其他一些平台上,char 等同于 unsigned char。ISO C 标准允许两者并存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接