为什么指针不能用另一个指向const char的指针初始化?

Joh*_*son 0 c++ pointers const

这是我们在C++类简介中给出的另一个"重新发明轮子"的问题:

编写一个函数,返回字符串中第一次出现的字符序列的位置,即strstr 函数的变体.

我开始编写如下函数:

int strstr2(const char *text, const char *pattern) {
    int pos = 0;
    char *temp;
    temp = text;
}
Run Code Online (Sandbox Code Playgroud)

我以为我会记住字符串的第一个字符的地址以供将来在函数中使用,但编译器说:

"const char*"类型的值不能分配给"char*"类型的实体.

我知道一旦初始化了一个常量就不能改变它,但是为什么我不能将指向常量char的指针分配给另一个非常量指针?

我读了几个关于指针和常量的问题,看来这篇文章的接受答案的底部可能会回答我的问题,但我不是百分百肯定,因为讨论对我来说仍然处于过于先进的水平.

我的第二个问题是,解决方法是什么?如何定义指向字符串开头的指针?

谢谢.

Nat*_*ica 8

这与const-correctness有关. const char *textmeans text是指向常量的指针char.这意味着如果你尝试做类似的事情

*text = 'a'
Run Code Online (Sandbox Code Playgroud)

由于您尝试修改const对象,编译器将发出错误.如果你能做到的话

char *temp;
temp = text;
Run Code Online (Sandbox Code Playgroud)

那么你可以做到

*temp = 'a'
Run Code Online (Sandbox Code Playgroud)

即使您刚刚修改了一个const对象,也没有错误.这就是为什么C++要求你使用,const_cast如果你真的想要抛弃const(有一些用例,但它们到目前为止不是你通常想要做的).


危险,下面有龙.如果您决定使用const_cast,请非常非常小心

让我们说你必须处理一个旧的API调用只需要一个char*,但它保证它不会修改,那么你可以使用像

int wrap_api(const char *text)
{
    return api_call(const_cast<char*>(text));
}
Run Code Online (Sandbox Code Playgroud)

这将是"好的",因为api_call保证它不会修改字符串.如果另一方面api_call可以修改那么这只会是合法的,如果text指向的实际上不是常数

char foo[] = "test"
wrap_api(foo);
Run Code Online (Sandbox Code Playgroud)

如果foo被修改会是合法的但是

const char foo* = "test"
wrap_api(foo);
Run Code Online (Sandbox Code Playgroud)

如果foo被修改并且是未定义的行为,那将是不合法的.

  • 我甚至不会在这里提到`const_cast`. (4认同)