为啥函数 `memchr()` 使用 `int` 作为 `char` 类型的参数?
Posted
技术标签:
【中文标题】为啥函数 `memchr()` 使用 `int` 作为 `char` 类型的参数?【英文标题】:Why does the function `memchr()` use `int` for the argument of `char` type?为什么函数 `memchr()` 使用 `int` 作为 `char` 类型的参数? 【发布时间】:2013-04-03 21:39:52 【问题描述】:以下函数使用int
作为第二个参数类型,
memchr(const void *buf, int ch, size_t count);
虽然它用于character
类型。为什么函数定义为使用int
作为char
类型的参数?这有什么特别的原因吗?
【问题讨论】:
您可能还想阅读这基本上是相同的问题。 ***.com/questions/5919735/… 【参考方案1】:之所以如此,是因为这是一个非常“古老”的标准函数,从 C 语言演化的早期就存在。
旧版本的 C 没有函数原型之类的东西。函数要么未声明,要么使用“未知”参数列表声明,例如
void *memchr(); /* non-prototype declaration */
在调用此类函数时,所有参数都会自动进行参数提升,这意味着此类函数从未收到char
或short
类型的参数值。这样的参数总是被调用者隐式提升为类型int
,而函数本身实际上收到了int
。 (在现代 C 中,对于如上所示声明的函数,即没有原型,这仍然是正确的。)
当 C 语言最终发展到引入 prototype 函数声明的地步时,将新声明与标准函数的旧行为和已编译的旧库保持一致非常重要。
这就是为什么您永远不会在遗留函数声明的参数列表中看到char
或short
这样的类型的原因。出于同样的原因,您也不会在此处看到类型 float
。
这也意味着,如果出于某种原因您必须为某些以 K&R 样式定义的现有遗留函数提供原型声明,您必须记住在原型中指定 promoted 参数类型。例如。对于定义为的函数
int some_KandR_function(a, b, c)
char a;
short b;
float c;
正确的原型原型声明实际上是
int some_KandR_function(int a, int b, double c);
但不是
int some_KandR_function(char a, short b, float c); // <- Incorrect!
【讨论】:
【参考方案2】:因为char
、signed char
和unsigned char
是三种不同的类型。在特定的实现中,您不知道char
是签名的还是未签名的。
除了在稀有系统中(参见 Keith 的注释),int
类型包含这三种类型可以具有的所有值。
【讨论】:
在大多数系统上。如果sizeof (int) == 1
(暗示CHAR_BIT >= 16
),那么int
可能无法保存unsigned char
类型的所有值。这样的系统很少见。
@pmg 这就是我用 EOF 完成“char、signed char 和 unsigned char”的原因。【参考方案3】:
所有处理字符的标准函数都可以。我认为部分原因是历史原因(在某些 C 的预标准版本中,函数不能采用 char
或 unsigned char
参数,就像 varargs 参数不能具有字符类型一样),部分原因是为了保持所有的一致性这样的功能。
有一些字符处理函数可以使用 int
以允许 EOF 的可能性,但 memchr
不是其中之一。
【讨论】:
您真的是指“EOL”吗?【参考方案4】:C 从不将小于 int 的参数传递给函数。将函数参数定义为 char 或 short 始终提升为 int,定义 unsigned char 或 unsigned short 参数始终提升为 unsigned int。 如果 unsigned 与 signed char 是问题,他们会使用短(我不记得短是 1 字节长的单个平台)。 当然,使用 int 可以处理 unsigned 与 signed char 的可能性,因为 memchr 只是比较相等性。
【讨论】:
以上是关于为啥函数 `memchr()` 使用 `int` 作为 `char` 类型的参数?的主要内容,如果未能解决你的问题,请参考以下文章
size_t——为什么支持size_t,何时使用size_t?