C++ std::字符串获取(char*)而不是(const char*)

C++ std::字符串获取(char*)而不是(const char*),c++,string,pointers,std,C++,String,Pointers,Std,std::string.c_str()返回一个(const char*)值。我在谷歌上搜索,发现我可以做到以下几点: std::string myString = "Hello World"; char *buf = &myString[0]; 这怎么可能&myString[0]是一个类型为std::string的对象,那么它如何工作呢?它与。[]运算符的优先级高于运算符的地址&,因此运算符的地址作用于字符串运算符[]函数返回的字符引用。您错了&myString[0]不是类型std::

std::string.c_str()
返回一个(const char*)值。我在谷歌上搜索,发现我可以做到以下几点:

std::string myString = "Hello World";
char *buf = &myString[0];

这怎么可能
&myString[0]
是一个类型为
std::string
的对象,那么它如何工作呢?

它与。
[]
运算符的优先级高于运算符的地址
&
,因此运算符的地址作用于字符串
运算符[]
函数返回的字符引用。

您错了
&myString[0]
不是类型
std::string
,而是类型
char*


[]
运算符具有更高的优先级,并返回对
字符的引用,其地址(
&
运算符)的类型为
char*
std::string
类型具有一个
运算符[]
,该运算符允许对字符串中的每个字符进行索引。表达式
myString[0]
是对字符串第一个字符的(可修改)引用。如果您获取该数组的地址,您将获得指向数组中第一个字符的指针。

运算符
[]
()重载返回对索引处字符的引用。您使用的是这种字符引用的地址,这很好

因此,
myString[0]
返回类型不是
std::string
,而是
char&

没有理由这样做。你可以直接做-

myString[0] = 'h';

std::string方法
c_str()
操作符[]
是两种不同的方法,它们返回两种不同的类型

方法c_str()确实返回一个
常量char*

const char* c_str() const;
但是,方法运算符[]返回对字符的引用。当你得到它的地址时,你就得到了一个字符的地址

       char& operator[] (size_t pos);
 const char& operator[] (size_t pos) const;
&myString[0]
是类型为
std::string

不,不是
myString[0]
是对字符串的第一个字符的引用
&myString[0]
是指向该字符的指针。运算符优先级意味着
&(myString[0])
而不是
(&myString)[0]


注意,通过这种方式访问,不能保证字符串将以零结尾;因此,如果在期望以零结尾的字符串的C风格函数中使用它,那么您将依赖于未定义的行为。

const
const
重载
std::string::operator[](size\u type pos)
,而非const版本返回
字符和
,因此您可以执行以下操作

std::string s("Hello");
s[0] = 'Y';

请注意,由于
s[0]
返回
char&
,因此
&s[0]
是元素
s[0]
的地址。您可以将该地址分配给
字符*
。这取决于您是否滥用此指针

“不保证字符串以零结尾”在C++03中为真,但C++11有保证。@TonyD:不,C++11不保证连续存储的字符后面有零;只是
str[size]
将引用一个零值,并且
c_str()
的结果将被终止。@MikeSeymour:我想知道为什么规范会让它变得如此复杂。仅保存一个字节?请参见21.4.7.1:
const charT*c_str()const noexcept;常量图表*数据()常量noexcept;返回:一个指针p,使得[0,size()]中每个i的p+i==&运算符[](i)。
-so
&p[i]
引用以NUL结尾的字符串(根据
c_str()
的要求)。(你可能想读一下)@TonyD:的确,
c_str()
需要返回指向连续终止数组的指针(如我所说)。但是
运算符[]
只需要为小于
size()的索引提供对连续数组的引用即可;见21.4.5/2 amd 21.4.1/5。在有人调用
c_str()
+1谈论优先级之前,一个适当的反常实现可能会一直处于未终止状态。这是一个不同的角度来看待语法。