在C中,字符串是char(char *
)数组,字符通常存储在char
中。我注意到libC中的一些函数将作为参数整数而不是char。
例如,让我们使用toupper()
和tolower()
两个都使用int
的函数。该手册页说:
如果c不是无符号字符值或EOF,则表示这些行为 函数未定义。
我的猜测是int
,toupper
和tolower
能够处理unsigned char
和EOF
。但实际上EOF
实际上(有没有关于它的值的规则?)是一个可以用char
存储的值,因为这些函数不会将EOF
转换成某些东西否则,我想知道为什么toupper
不会简单地将char作为参数。
在任何情况下,为什么我们需要接受不属于某个角色的东西(例如EOF)?有人可以给我一个相关的用例吗?
这与fputc
或putchar
类似,但也会将int
转换为unsigned char
。
我正在寻找这种选择的确切动机。我想要被说服,我不想回答我不知道有人有一天会问我。
答案 0 :(得分:9)
C11 7.4
标题
<ctype.h>
声明了几个对分类和映射有用的函数 字符。在所有情况下,参数都是一个int,其值应为 可表示为无符号字符或等于该值 宏观EOF。如果参数具有任何其他值,则行为为 未定义。
C11 7.21.1
EOF
扩展为整数常量表达式,类型为int和a 负值,......
C标准明确规定 EOF始终为负值的int。此外,默认char
类型的签名是实现定义的,因此它可能是无符号的,无法存储负值:
C11 6.2.5
如果基本执行字符集的成员存储在char中 对象,其值保证为非负。如果有的话 字符存储在char对象中,结果值为 实现定义但应在值的范围内 可以用那种类型表示。
答案 1 :(得分: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;
}
然后,具有EOF值的 ch
可用于isalpha()
,tolower()
等各种函数。
此样式导致putchar(EOF)
出现问题,我怀疑它与putchar(255)
的问题相同。
由于各种原因,这种方法今天不鼓励。以下各种型号是优选的。
int GetDecimal() {
int ch;
while (((ch = getchar()) != EOF)) && isdigit(ch)) {
...
}
...
}
答案 2 :(得分:1)
如果c不是无符号字符值或EOF,则这些函数的行为是未定义的。
但是EOF
在C中是负int
,而某些平台(在ARM!中)char
与unsigned char
相同。