以这种方式在c ++中操作字符串是可以的:
string s = "Sting";
s[2] = 'a';
Run Code Online (Sandbox Code Playgroud)
它工作正常(并打印'Stang'),但这样做是否安全?
如果是,这是否意味着它们是可变的?
Die*_*ühl 14
C++字符串文字,即类似的东西"literal"是不可变的,尽管C++ 03允许将指向这样一个文字的指针分配给char*(这个特权已被弃用并被C++ 11删除).尝试更改字符串文字的字符是未定义的行为:
char* s = "literal"; // OK with C++03; illegal with C++11 and later
s[0] = 'x'; // undefined behavior
Run Code Online (Sandbox Code Playgroud)
std::string假设它们未被声明为C++ 对象,它们肯定是可变的std::string const.如果您认为char对象序列彼此独立,则可以分配给单个对象.但是,字符串实际上包含编码为UTF-8字节的Unicode是很常见的.如果是这种情况,则更改字符串的任何元素可能会破坏正确的编码,例如,因为连续字节被其他内容替换.
所以,是的,字符串是可变的,但从语义的角度来看,分配给单个元素可能并不安全.
字符串文字本身就像Java中一样是不可变的。
字符串文字存储在内存的只读部分中。
例如,如果您执行以下操作,则会出现段错误:
char *ptr = (char *) "hello";
ptr[0] = 'a'; //segfault! you can't change something that's immutable
Run Code Online (Sandbox Code Playgroud)
然而!您可以使用修改字符串s[2] = 'a',除非使用const关键字声明了该字符串,
这样做的原因是=字符串的运算符被重载,将字符串文字作为参数,然后遍历字符串文字,将每个字符复制到可变char数组中。
因此,如果您要比较Java和C中的字符串文字,它们在不可变时具有相同的行为。Java和C中的字符串对象在可变时也具有相同的行为。
这是显示字符串具有副本的事实的示例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char *ptr = "hello";
string s = ptr;
s[0] = 'b';
cout << s << endl; //prints bello
cout << ptr << endl; //prints hello
return 0;
}
Run Code Online (Sandbox Code Playgroud)