从K& R的“C编程语言”中理解关于char和int类型的段落的困惑

时间:2013-12-30 15:43:44

标签: c types kernighan-and-ritchie

关于第1章:Kernighan和Ritchie的教程介绍中的这段经文:C编程语言(我已经加粗了我需要澄清的具体部分,并在下面详细说明):

  

鉴于getchar和putchar,您可以编写大量有用的代码,而无需了解有关输入和输出的更多信息。最简单的示例是一个程序,一次将其输入复制到其输出一个字符:   读一个角色   while(字符不是文件结束指示符)   输出刚读过的字符读取一个字符   将其转换为C给出:

#include <stdio.h>
/* copy input to output; 1st version */ main()
{
       int c;
       c = getchar();
       while (c != EOF) {
           putchar(c);
           c = getchar();
       }
}
  

关系运算符!=表示“不等于”。   键盘或屏幕上似乎是一个字符,当然,就像其他一切一样,内部存储就像一个位模式。 char类型专门用于存储此类字符数据,但可以使用任何整数类型。我们使用int是一个微妙但重要的原因。

     

问题在于区分输入结束和有效数据。解决方案是当没有更多输入时,getchar返回一个独特的值,这个值不能与任何真实字符混淆。对于“文件结束”,该值称为EOF。我们必须声明c是一个足够大的类型,以保存getchar返回的任何值。我们不能使用char,因为除了任何可能的char之外,c必须足够大以容纳EOF。因此我们使用int。

我的理解是Char是一种Int,但它只是更小(与Int16,Int32,Int64在其他语言中相同,但可以表示数字的大小)。

我知道每个字符都可以用Char类型的整数表示,那么为什么EOF值不能表示为Char?是因为Char类型中的每个整数都已被考虑,甚至还有一个数字对于数据类型来说太大了吗?

对我的知识的任何解释或更正将不胜感激。

8 个答案:

答案 0 :(得分:8)

  

是因为Char类型中的每个整数都已被考虑,甚至还有一个数字对于数据类型来说太大了吗?

是的,这是完全正确的。更具体一点,整个想法是将EOF定义为可以与getchar可能从文件中检索的任何值区分开的值。由于您可以将char的任何可能值写入文件,因此您还可以从文件中读取char的任何可能值。要使EOF正确执行其工作,必须与可能已写入/读取文件的任何值不同。要做到这一点,它必须是一个不适合char

的值

答案 1 :(得分:1)

C标准确保getchar()的返回值是有效字符或不同代码。 EOF,不是有效字符的代码。 EOF扩展为整数常量表达式,类型为int,可能具有负值。

答案 2 :(得分:1)

问题是“C”标准没有指定是否签名“char”。因此,虽然现代实现可能会提供“签名”和“未签名”字符;早期标准实际上已经改变(至少两次)。该标准也确实(自1989年以来),无论EOF有什么价值;这是消极的。

答案 3 :(得分:0)

EOF实际上意味着缺少角色,因此它不能是一个普通的角色。虽然可以选择从char范围中挑出一个值来标记此特定值,但是具有超出范围的值允许在charchar的任何平台中管理256个唯一有效字符。 8位。为了能够保持超出范围的值,该函数必须使用整数类型,该整数类型可以表示{{1}}中的所有值以及至少一个值。

答案 4 :(得分:0)

char类型可以是有符号或无符号的,具体取决于实现,但EOF通常定义为-1。如果char是无符号的,则它不能表示值-1,因此getchar()被定义为返回int,当不合格时,它始终是有符号的,因此可以表示所有可能的值char 代表-1(EOF)。

分享并享受。

答案 5 :(得分:0)

  

我的理解是Char是一种Int,但它只是更小的

是的。

  

我知道每个字符都可以用Char类型的整数表示,那么为什么EOF值不能表示为Char?是因为Char类型中的每个整数都已被考虑,甚至还有一个数字对于数据类型来说太大了吗?

是的。

答案 6 :(得分:0)

如果查看getchar的手册页,可以阅读,

  

getchar()等同于getc(stdin)

     

getc()等效于fgetc(),但它可以实现为   一个不止一次评估流的宏。

     

fgetc()从流中读取下一个字符并将其返回为   一个无符号的char转换为int,或者文件结尾或错误的EOF。

概要decalares

SYNOPSIS
   #include <stdio.h>

   int fgetc(FILE *stream);

因此,c应声明为int。

答案 7 :(得分:0)

  1. 通过使EOF超出可能的字符范围,示例代码将成功复制任何(“二进制”)数据。 EOF不可能是数据中间的有效值。

  2. 最好的C语言书是Harbison和Steele,C: A Reference Manual。我已经全部使用过了。