ANSI C:为啥字符函数接受 int 参数而不是 char 参数?
Posted
技术标签:
【中文标题】ANSI C:为啥字符函数接受 int 参数而不是 char 参数?【英文标题】:ANSI C: Why character functions accept int argument instead of char argument?ANSI C:为什么字符函数接受 int 参数而不是 char 参数? 【发布时间】:2012-02-16 07:39:34 【问题描述】:为什么字符函数接受 int 参数而不是 char 参数?
<ctype.h>
int isalnum(int c);
int isalpha(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int tolower(int c);
int toupper(int c);
【问题讨论】:
我怀疑答案类似于给定的here。在 C 中,字符文字的类型为int
。
@Cody:这两个决定可能是相关的,因为在 C 中对字符进行“计算”的正确数据类型是 int
。但是与这些函数的参数具有相同类型的文字并不像看起来那么简单。你可以写isalnum('a')
,但不能保证你能写isalnum(CHAR_MIN)
,或者在你的实现中对应于CHAR_MIN
的任何字符文字,因为它可能是负数。为了与这些函数正确匹配,字符文字确实需要类型 unsigned
,但将它们转换为 char
可能会很糟糕。
【参考方案1】:
字符和整数在 C 中紧密结合。
当您从输入流中接收到一个字符时,它必须能够表示每个字符加上文件结束符号。
这意味着 char
类型不够大,因此他们使用更宽的类型。
C99 基本原理文档指出:
由于这些函数通常主要用作宏,因此它们的域仅限于可以用 unsigned char 表示的小的正整数,加上 EOF 的值。 EOF 传统上是 -1,但可以是任何负整数,因此可以与任何有效字符代码区分开来。因此,这些宏可以通过使用参数作为一个小属性数组的索引来有效地实现。
标准本身是这样说的:
标题
<ctype.h>
声明了几个对分类和映射有用的函数 人物。在所有情况下,参数都是一个 int,其值应为 可表示为无符号字符或应等于宏 EOF 的值。如果 参数有任何其他值,行为未定义。
【讨论】:
“下一个最大的类型”实际上是short
。但是,当这些被发明出来时,short
将被提升为 int
,就像 char
一样。
@JerryCoffin 你什么意思?每当在表达式中使用时,所有 short 仍会提升为 int。
@AmirSaniyan: while ((mychar = tolower(getchar()) != EOF) /* do stuff */ 从技术上讲,非 ascii 值返回未定义的值,但什么时候有“这种行为是未定义的”曾经阻止过任何人依赖它吗?
@Jerry: 更重要的是,当这些被发明时,short
在许多地方与char
的大小相同。尽管标准没有明确要求它,int
几乎在任何地方都大于char
。如果它们的大小相同,则实现者将需要一个特殊的“保留”负值,它不是执行字符集中的代码点,并且永远不能从任何类型的输入(包括例如二进制文件流)中读取,并将其用作EOF。我不确定这是否合法,因为这意味着char
的值无法写入文件并读回。
@SteveJessop:哪个编译器的 char 和 short 大小相同?我很确定 AT&T 编译器和 Whitesmiths 都没有。我记得有很多非常早期的编译器(例如 BDS C)根本没有 short
,但没有一个与 char
大小相同。【参考方案2】:
最初发明 C 时,没有对函数参数进行编译时检查。如果一个名为foo(bar,boz)
,bar
和boz
的类型为int
,编译器会将两个int
值压入堆栈,调用foo
,并希望得到两个@987654327 @ 值。由于在计算表达式时小于int
的整数类型被提升为int
,所以在原型发明之前编写的C 函数不能传递任何更小的整数类型。
【讨论】:
【参考方案3】:除了正常的字符值之外,它们还必须接受 EOF。它们也早于函数原型的发明。那时,没有办法将char
传递给函数——它总是首先被提升为int
。
【讨论】:
【参考方案4】:是的,它可以容纳始终为非字符值的 EOF,尽管 EOF 的确切值可能因不同的系统而异,但它永远不会与任何字符代码相同。
【讨论】:
以上是关于ANSI C:为啥字符函数接受 int 参数而不是 char 参数?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Hex() 函数返回一个字符串而不是一个 int hex?