19

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

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

如果 c 不是 unsigned char 值或 EOF,则这些函数的行为是未定义的。

我的猜测是,与 a inttoupper并且tolower能够处理unsigned charand EOF。但实际上EOF是在实践中(关于它的值有什么规则吗?)一个可以与 a 一起存储的值char,并且由于这些函数不会转换EOF为其他东西,我想知道为什么toupper不简单地将 char 作为参数.

无论如何,为什么我们需要接受不是字符的东西(例如 EOF)?有人可以给我一个相关的用例吗?

这与fputcor类似putchar,也将 aint转换为unsigned char无论如何。

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

4

3 回答 3

10

C11 7.4

标头<ctype.h>声明了几个对字符分类和映射有用的函数。在所有情况下,参数都是一个 int,其值应表示为无符号字符或应等于宏 EOF 的值。如果参数有任何其他值,则行为未定义。

C11 7.21.1

EOF

它扩展为一个整数常量表达式,类型为 int 和一个负值,...

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

C11 6.2.5

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

于 2013-07-03T16:28:24.060 回答
2

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;
}

ch使用 EOF 的值,则可以在各种函数中使用,例如isalpha(), tolower()

这种风格引起了putchar(EOF)我怀疑与putchar(255).

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

int GetDecimal() {
  int ch;
  while (((ch = getchar()) != EOF)) && isdigit(ch)) {
    ...
  }
  ...
}
于 2013-07-03T17:48:42.063 回答
1

如果 c 不是 unsigned char 值或 EOF,则这些函数的行为是未定义的。

但是在 C 语言中EOF是一个负数int,某些平台(嗨 ARM!)charunsigned char.

于 2013-07-03T16:12:17.970 回答