c ++字符串是否可变UNLIKE Java字符串?

时间:2015-02-10 22:01:36

标签: c++

以这种方式用c ++操作字符串是可以的:

string s = "Sting";
s[2] = 'a';

它可以正常工作(并打印'Stang'),但这样做是否安全?

如果是,这是否意味着它们是可变的?

6 个答案:

答案 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。