以这种方式用c ++操作字符串是可以的:
string s = "Sting";
s[2] = 'a';
它可以正常工作(并打印'Stang'),但这样做是否安全?
如果是,这是否意味着它们是可变的?
答案 0 :(得分:11)
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
C ++ std::string
对象肯定是可变的,假设它们未被声明为std::string const
。如果您认为char
个对象的序列彼此独立,则可以分配给单个对象。但是,字符串实际上包含编码为UTF-8字节的Unicode是很常见的。如果是这种情况,则更改字符串的任何元素可能会破坏正确的编码,例如,因为延续字节被其他内容替换。
所以,是的,字符串是可变的,但从语义的角度来看,分配给各个元素可能并不安全。
答案 1 :(得分:3)
字符串文字本身是不可变的,就像在Java中一样。
字符串文字存储在内存的只读部分。
例如,如果您执行以下操作,则会出现段错误:
char *ptr = (char *) "hello";
ptr[0] = 'a'; //segfault! you can't change something that's immutable
然而!您可以使用s[2] = 'a'
修改字符串,除非使用const关键字
原因是字符串的=
运算符被重载,将字符串文字作为参数,然后遍历字符串文字,将每个字符复制到可变字符数组中。
因此,如果您在比较Java和C中的字符串文字,它们在不可变时会有相同的行为。 Java和C中的String对象在可变时也具有相同的行为。
这是一个显示字符串有副本的事实的例子:
#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;
}
答案 2 :(得分:1)
是和是。
就像修改位置2的数组一样。
答案 3 :(得分:1)
是的,它是完全安全的,是的字符串是可变的,这意味着您可以更改它们,向它们添加新内容并从中删除部分。
答案 4 :(得分:0)
C ++中的字符串是可变的,但强大的功能带来了很大的责任:如果你读取或存储到超出范围的字符串内存,你将得到未定义的行为。例如,在你的例子中,如果你提到s [12],你会得到未定义的行为。
答案 5 :(得分:0)
C ++ std::string
是可变的,并且赋值(通常)复制字符串数据。 Java String
是不可变的,赋值复制对字符串的引用。
类型std::shared_ptr< const std::string >
在某种程度上类似于Java字符串。然而,这是一个穷人的替代品。在C ++ 03中,它与优化例如对字符串集合进行排序,但使用C ++ 11移动语义,它不再与任何东西相关 - 除了学术POV。