Ste*_*e D 20 c string int char
strchrC标准库中的函数在char字符串中查找a ,但其签名需要int搜索字符.在我发现的这两个实现中,实现将其转换int为char:
char *strchr(const char *s, int c) {
while (*s != (char)c)
if (!*s++)
return 0;
return (char *)s;
}
char *strchr(const char *s, int c) {
while (*s && *s != (char)c)
s++;
if (*s == c)
return (char *)s;
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么?为什么不把a char作为参数呢?
AnT*_*AnT 37
其原因纯粹是历史性的.请注意,在C语言(K&R C)的旧时代,没有函数原型这样的东西.strchr这些时间的函数将被声明为
char *strchr();
Run Code Online (Sandbox Code Playgroud)
并以K&R风格定义为
char *strchr(s, c)
char *s;
char c;
{
/* whatever */
}
Run Code Online (Sandbox Code Playgroud)
但是,在C语言中(在K&R C和现代语言中)如果声明函数没有原型(如上所示),则在每个函数调用中传递的参数都会受到所谓的默认参数提升.在默认参数促销下,任何小于int(或unsigned int)的整数类型总是转换为int(或unsigned int).即,当参数未声明时,无论何时将char值作为参数传递,该值都会隐式转换为int,并实际上作为一个物理传递int.同样如此short.(顺便说一句,默认float转换为double促销参数).如果在函数内部,参数实际上被声明为a char(如上面的K&R样式定义),它将被隐式转换回char类型并用作char函数内部.这就是它在K&R时代的工作方式,这实际上是它在现代C中的工作方式,当函数没有原型或使用可变参数时.
现在,提示现代C,它具有函数原型并使用现代风格的函数定义语法.为了保留和重现"传统"功能strchr,如上所述,我们别无选择,只能声明参数strchr为a int并将其显式转换char为函数内部.这正是您在引用的代码中观察到的内容.这strchr与标准中描述的功能完全相同.
此外,如果您有一个已编译的遗留库,其中strchrK&R样式定义如上所示,并且您决定为该库提供现代原型,那么适当的声明strchr将是
char *strchr(const char *s, int c);
Run Code Online (Sandbox Code Playgroud)
因为int上面的遗留实现期望实际接收的内容c.用char参数声明它是不正确的.
出于这个原因,你永远不会看到"传统"的标准库函数期望类型的参数char,short或者float.所有这些函数都将使用类型int或参数声明double.
标准保证的基本原理是char指针和void *指针共享相同的表示和对齐要求.依靠此保证,您可以声明malloc为 - void *返回函数,然后将此声明与malloc实际返回的标准库的预编译旧版本一起使用char *.
参考:C99基本原理,版本5.10
7.1.4库函数的使用
/ - /
所有库原型都是根据"加宽"类型指定的:以前声明为char的参数现在写为int.这确保了可以在范围内使用或不使用原型来调用大多数库函数,从而保持与C89之前代码的向后兼容性
| 归档时间: |
|
| 查看次数: |
5280 次 |
| 最近记录: |