繁体   English   中英

为什么strrchr()返回`char *`而不是`const char *`?

[英]Why strrchr() returns `char*` instead of `const char*`?

函数char* strrchr(const char *str, int ch)返回strconst char * )中的指针( char* ),其中ch的最后一个出现位置。

所以我们可以编写以下代码而不进行任何转换:

#include <string.h>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";
    char *ptr = strrchr (CONSTSTR, '/');
    *ptr++ = 'B';
    *ptr++ = 'A';
    *ptr++ = 'D';
}

返回char*而不是const char*什么好处?

编辑:
正如Shafik Yaghmour指出的那样, strchr实现如何运作有很好的答案

由于我的代码是在C ++中,我将使用<cstring>而不是<string.h> 谢谢你的回答;-)

然而, Mike Seymour的答案最适合这个问题。 我甚至在下面添加了一个更详细的答案来清楚地说明,因为strrchr()是一个C函数(不允许重载),声明适合const非const字符串。 因为可以使用非const字符串调用strrchr() ,所以返回的字符串也应该是非const

您正在查看C标准库( <string.h> )中的遗留函数。 C ++库( <cstring> )引入了适当的const和非const重载 ,因此您应该尽可能使用它。

在C中,函数必须像这样,或强迫用户在许多情况下使用狡猾的强制转换:

  • 如果它采用非const指针,则无法搜索const字符串;
  • 如果它返回一个const指针,则无法使用它来修改非const字符串。

在C ++中,您应该包含<cstring>而不是不推荐使用的C-only标头。 这将给你两个const-correct重载,这在C中无法完成:

const char* strchr(const char* s, int c);
      char* strchr(      char* s, int c);

const char *str表示strrchr保证不修改str

返回const char *表示strrchr禁止修改返回的值。

<string.h>中的strrchr()是一个C函数。 由于C不允许函数重载,因此strrchr()被设计为适合const非const字符串。

char* strrchr( const char *str, int ch );

可以使用非const字符串调用strrchr() ,因此返回的字符串也应该是非const,如以下示例中所述。

没有编译错误的const上下文:

#include <string.h>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";
    const char *basename = strrchr (CONSTSTR, '/');
    // basename points to "foobar.txt"
}

没有编译错误的非const上下文:

#include <string.h>
int main()
{
    char nonconst[] = "foo/bar/foobar.txt";
    char *basename = strrchr (nonconst, '/');
    basename[0] = 'G';
    basename[3] = 'D';
    // basename points to "GooDar.txt"
}

使用不当也没有编译错误:

#include <string.h>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";
    char *nonconst = strrchr (CONSTSTR, '/');
    *nonconst++ = 'B';
    *nonconst++ = 'A';  // drawback of the unique declaration: 
    *nonconst++ = 'D';  // no compilation error
}

在C ++中,有两个重载函数

const char* strrchr( const char* str, int ch );  //1st
      char* strrchr(       char* str, int ch );  //2nd

const上下文使用第一个:

#include <cstring>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";
    const char *basename = std::strrchr (CONSTSTR, '/');
    // basename points to "foobar.txt"
}

非const上下文使用第二个:

#include <cstring>
int main()
{
    char nonconst[] = "foo/bar/foobar.txt";
    char *basename = std::strrchr (nonconst, '/');
    basename[0] = 'G';
    basename[3] = 'D';
    // basename points to "GooDar.txt"
}

不良用法应该产生编译错误:

#include <cstring>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";

    char *nonconst = std::strrchr (CONSTSTR, '/');
// Visual C++ v10 (2010)
// error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'

    *nonconst++ = 'B';
    *nonconst++ = 'A';
    *nonconst++ = 'D';
}

但是最后一个示例使用g++ -Wall file.cpp不会产生任何编译错误。 使用GCC版本4.1.2(RedHat)4.7.2(MinGW)进行测试

为什么要禁止代码修改返回的变量? 请注意, const char *不是char * const ,你可以在任何情况下修改字符,但是你不能控制返回的值本身,这没有多大意义,因为你可能想要改变它并根据您的目的在不同位置编辑基础字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM