7

该函数在( ) 中char* strrchr(const char *str, int ch)返回一个指针 ( ),其中最后一次出现。char*strconst 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*return而不是return 有什么好处const char*

编辑:
正如Shafik Yaghmour指出的那样, strchr implementation 如何工作有很好的答案?

由于我的代码是 C++,所以我将<cstring>使用<string.h>. 感谢您的回答;-)

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

4

5 回答 5

13

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

于 2013-05-31T15:10:49.940 回答
7

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

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

在 C++ 中,您应该包含<cstring>而不是已弃用的仅 C 标头。这将为您提供两个 const 正确的重载,这在 C 中无法完成:

const char* strchr(const char* s, int c);
      char* strchr(      char* s, int c);
于 2013-05-31T15:24:06.373 回答
3

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

返回的const char *意思是strrchr禁止你修改返回的值。

于 2013-05-31T15:10:25.753 回答
2

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

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

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

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

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

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

#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 context 使用第一个:

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

非常量上下文使用第二个:

#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)进行测试。

于 2013-06-04T09:23:47.303 回答
0

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

于 2013-05-31T15:12:31.153 回答