,和函数返回 int getc
,因为它们能够处理二进制数据,以及提供错误或数据结束条件的带内信号。fgetc
getchar
除了在某些具有异常字节大小的嵌入式平台上,该类型int
能够将所有字节值表示0
为UCHAR_MAX
正值。此外,它可以表示负值,例如常量的值EOF
。
该类型unsigned char
只能将值表示0
为UCHAR_MAX
,因此函数将无法使用返回值作为指示无法读取另一个数据字节的方式。该值EOF
很方便,因为可以将其视为输入符号;例如,它可以包含在switch
处理各种字符的语句中。
还有一点,因为在 C 的设计中,值short
和char
类型(有符号或无符号)在表达式中求值时会进行提升。
在经典 C 中,在引入原型之前,当您将 a 传递char
给函数时,它实际上是一个int
被传递的值。具体来说:
int func(c)
char c;
{
/* ... */
}
这种旧式定义没有引入有关参数类型的信息。当我们将其称为func(c)
, where c
has typechar
时,表达式c
会受到通常的提升,并成为 type 的值int
。这正是上述函数定义所期望的类型。type 的参数char
实际上作为 type 的值传递int
。如果我们为上述函数编写一个 ISO C 原型声明,它必须是,你猜怎么着:
int func(int); /* not int func(char) */
另一个遗留问题是字符常量'A'
实际上有 typeint
而不是char
. 值得注意的是,这在 C++ 中发生了变化,因为 C++ 具有重载函数。鉴于重载:
void f(int);
void f(char);
我们想f(3)
叫前者,f('A')
又叫后者。
所以重点是C语言的设计者基本上认为char
是面向表示一个紧凑的存储位置,以及最小的可寻址内存单元。但就处理器中的数据操作而言,他们认为这些值是字大小的int
值:字符处理本质上是基于int
.
这是 C 的低级方面之一。在字节寻址机器上的机器语言中,我们通常将字节视为存储单元,当我们将字节加载到寄存器中以使用它们时,它们会占用一个完整的寄存器,所以变成 32 位值(或者你有什么)。这反映在 C 中的提升概念中。