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

abc*_*cde 17 c++

以这种方式在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是很常见的.如果是这种情况,则更改字符串的任何元素可能会破坏正确的编码,例如,因为连续字节被其他内容替换.

所以,是的,字符串是可变的,但从语义的角度来看,分配给单个元素可能并不安全.


Kac*_*acy 5

字符串文字本身就像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)

  • @AnonymousAndy-示例中的第一行采用字符串文字,并从该文字创建一个std :: string`object`。它在概念上与您执行`int a = 1;`没什么不同。您可以更改`a`的值,对吗?但是你不能改变`1`。 (2认同)

Shw*_*eta 3

是的,是的。

这就像修改数组的位置 2 一样。