为什么putchar、toupper、tolower等使用int而不是char?
在C语言中,字符串是字符数组(为什么putchar、toupper、tolower等使用int而不是char?,c,putchar,tolower,toupper,C,Putchar,Tolower,Toupper,在C语言中,字符串是字符数组(char*),字符通常存储在char中。我注意到libC中的一些函数将作为参数整数而不是字符 例如,让我们以使用int的函数toupper()和tolower()为例。手册页上说: 如果c不是无符号字符值或EOF,则 函数未定义 我的猜测是,使用int,touper和tolower可以处理无符号字符和EOF。但事实上,EOF实际上是一个可以用char存储的值(关于它的值有什么规则吗?),既然这些函数不会将EOF转换成其他东西,我想知道为什么toupper不简单地将c
char*
),字符通常存储在char
中。我注意到libC中的一些函数将作为参数整数而不是字符
例如,让我们以使用int
的函数toupper()
和tolower()
为例。手册页上说:
如果c不是无符号字符值或EOF,则
函数未定义
我的猜测是,使用int
,touper
和tolower
可以处理无符号字符
和EOF
。但事实上,EOF
实际上是一个可以用char
存储的值(关于它的值有什么规则吗?),既然这些函数不会将EOF
转换成其他东西,我想知道为什么toupper
不简单地将char作为参数
在任何情况下,为什么我们需要接受不是字符的东西(比如EOF)?有人能给我提供一个相关的用例吗
这与fputc
或putchar
类似,它们也接受一个int
,该值被转换为无符号字符
我正在寻找这一选择的确切动机。我想确信,我不想回答有一天是否有人问我。如果c不是无符号字符值或EOF,这些函数的行为是未定义的
但是在C语言中,EOF
是一个负的int
,一些平台(hi-ARM!)具有char
与无符号char
相同
标题
声明了几个用于分类和映射的函数
人物。在所有情况下,参数都是int,其值应为
可表示为无符号字符,或应等于
宏EOF。如果参数有任何其他值,则行为为
未定义
C117.21.1
EOF
它扩展为整型常量表达式,类型为int和
负值
C标准明确规定,EOF始终是一个带有负值的整数。此外,默认char
类型的签名是实现定义的,因此它可能没有签名,并且不能存储负值:
C116.2.5
如果基本执行字符集的成员存储在字符中
对象,其值保证为非负。如果有的话
字符存储在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)) {
...
}
...
}
我不知道EOF
必须符合char
的任何规则,我可以向您保证char
不保证签名,这使得您关于使用char
而不是无符号char
的讨论似乎是错误的。你的意思是整个过程都是signed char
。你看过这些函数的实现吗。我认为int
参数是为了优化,因为它的字节大小非常适合处理器寄存器的大小。反过来,一个字节char
变量必须在幕后转换为int
,此操作需要一些处理器时间来处理。请阅读以下内容:关于使用示例,我有+1您的答案。但正如你所说,这是不鼓励的,那么为什么isdigit
应该接受不是字符的东西呢?@Maxime我确信isdigit()
接受-1
是历史性的。从概念上讲,不难将EOF看作另一个char
。isthis…()
函数通常使用256字节数组实现,使257字节数组也接受EOF(-1)是很简单的。因为它很简单,并且使得代码更紧凑,所以当紧凑的代码具有更高的价值时,它是一个很好的扩展。现在,随着代码维护值的不断增加,这个习惯用法已经失去了人们的青睐。是的,但在重要的地方,C标准说“unsigned char或EOF”。我的一个问题是:为什么一个将字母转换为另一个字母的函数应该接受非字母的内容?(包括EOF)另一个答案回答了您的问题(为什么像tolower()
这样的函数需要接受非字母的东西,例如EOF
)——因为在像tolower(ch=getchar())
这样的惯用情况下,ch
,它是int
,很可能是EOF
,因此,tolower
可以接受EOF
。