为什么putchar,toupper,tolower等采用int而不是char?

在C中,字符串是char( char * )的数组,字符通常存储在char 。 我注意到libC中的一些函数是作为参数整数而不是char。

例如,让我们使用函数toupper()tolower()都使用int 。 手册页说:

如果c不是无符号字符值或EOF,则这些函数的行为是不确定的。

我的猜测是,使用inttouppertolower能够处理unsigned charEOF 。 但事实上EOF在实践中(有没有关于它的价值的规则?)一个可以用char存储的值,并且由于这些函数不会将EOF转换成其他东西,我想知道为什么toupper不会简单地采取一个char作为参数。

在任何情况下,为什么我们需要接受不是字符的东西(例如EOF)? 有人能为我提供相关的用例吗?

这与fputcputchar类似,它也采用转换为unsigned char

我正在寻找这种选择的确切动机。 我想要被说服,我不想回答,我不知道有一天有人问我。

C11 7.4

头文件声明了几个对字符分类和映射有用的函数。 在所有情况下,参数都是一个int,其值应表示为unsigned char或者等于宏EOF的值。 如果参数具有任何其他值,则行为未定义。

C11 7.21.1

EOF

它扩展为整数常量表达式,类型为int且为负值,…

C标准明确指出EOF始终是具有负值的int 。 此外,默认char类型的签名是实现定义的,因此它可能是无符号的,不能存储负值:

C11 6.2.5

如果基本执行字符集的成员存储在char对象中,则其值保证为非负值。 如果任何其他字符存储在char对象中,则结果值是实现定义的,但应在可以在该类型中表示的值的范围内。

BITD编码方法包括:

 /* example */ int GetDecimal() { int sum = 0; int ch; while (isdigit(ch = getchar())) { /* isdigit(EOF) return 0 */ sum *= 10; sum += ch - '0'; } ungetc(ch, stdin); /* If c is EOF, operation fails and the input stream is unchanged. */ return sum; } 

具有EOF值的ch可以用于各种函数,如isalpha()tolower()

这种风格引起了putchar(EOF) ,我怀疑它和putchar(255)

由于各种原因, 今天不鼓励使用该方法。 以下各种型号是优选的。

 int GetDecimal() { int ch; while (((ch = getchar()) != EOF)) && isdigit(ch)) { ... } ... } 

如果c不是无符号字符值或EOF,则这些函数的行为是不确定的。

但是EOF在C中是负的int ,而某些平台(hi ARM!)的charunsigned char相同。