为什么strchr需要一个int才能找到char?

Ste*_*e D 20 c string int char

strchrC标准库中的函数在char字符串中查找a ,但其签名需要int搜索字符.在我发现的这两个实现中,实现将其转换intchar:

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之前代码的向后兼容性

  • @Greg A. Woods:这完全没有抓住重点。K&R C 中标准函数的无原型声明及其针对较小类型的行为是无可争议的历史事实。在 K&R(效率或其他)中这样做的原因很有趣,但与问题的上下文无关。最初问题的答案再次是,当“原型”的概念被添加到语言中时,标准函数的原型“被迫”避免较小的类型,以保留已经建立的遗留行为。就这样。 (2认同)
  • @Greg A. Woods:我从来没有说过这是一次意外。该语言的旧版本(K&R)以这种方式设计的原因肯定*确实*存在,但它们与这个问题的上下文无关。这个问题是:为什么该语言的*新*版本(带有原型和类型化参数列表的版本)也是这样?答案:它别无选择,因为它必须保持与旧版本标准库的兼容性。再次强调:现代实现没有*别无选择*。在“别无选择”的情况下,所有其他原因都是无关紧要的。 (2认同)