C-String数组初始化 - 这是可变的吗?

Joh*_*0te 9 c++ c-strings

可能重复:
修改C字符串常量?
const char与char数组vs std :: string的指针

我知道我可能会用这个问题击败死马,但我有点困惑,我还没有找到SO或谷歌的确切答案(我有信心是对的 - 这里有太多的信息在C字符串上筛选).另外,我已经将它标记为C++,因为这是我感兴趣的,即使我们特别谈论的是C风格的字符串.

在这种情况下:

char const a*  = "hello";
char const b[] = "goodbye";
Run Code Online (Sandbox Code Playgroud)

我本来以为"你好"和"再见"是不可变的字符串,因为它们来自应衰减到一个char*常量字符串常量.

我已经看到了,在这种特殊情况下,虽然,改变"你好"将是不确定的,同时改变"再见"就可以了,假设你剥去从B数组常量性.

我假设在b的情况下字符串是可变的,因为它存储在用户定义的数组中.

在这种情况下,你好,再见不同吗? 在这个例子中,由于某些原因,再见不是字符串文字.另外,如果再见不是字符串文字,我可以假设它不在全局内存中,并且在编译时间之后对它的唯一引用是留在用户数组单元格中吗?

Set*_*gie 16

第一个创建指向字符串文字的指针,该字符串文字"hello"可能存储在程序的可执行映像中的不可写存储器中.即使不是,也不允许修改该数组的内容.

第二个创建一个自动数组1(在堆栈上(通常,但实现定义))并使用字符串初始化它"goodbye".它相当于

char const b[] = {'g', 'o', 'o', 'd', 'b', 'y', 'e', 0};
Run Code Online (Sandbox Code Playgroud)

因此,虽然"goodbye"它是不可变的,因为它是一个字符串文字char const[8]并存储在不可写的内存中,但是数组b是一个自动的1数组,因为你标记它是不可变的const,但你可以const从变量声明中删除它以使数组的内容可变.您只是使用数组的内容初始化数组的内容"goodbye".

您不能修改它们中的任何一个,因为它们都是const char[],但第二个可以更改为char[]可变,而第一个不能.

有关详细信息,请参阅此答案:https://stackoverflow.com/a/9106798/726361


1正如R. Martinho Fernandes在评论中指出的那样,语法T x[] = ...也可以创建一个静态数组(不是自动的,而是静态的(通常在可执行映像中,但是实现定义))如果它在命名空间范围内,它只是一个自动的否则.


Lig*_*ica 6

字符串文字有类型char const[N]; 当然这种类型的名字可能会腐烂到char const*.

现在:

  1. char阵列可以由一个字符串(8.5.2/1)被初始化,并且由于不能以其他方式复制或分配阵列,它遵循这个初始化实现一个副本.无论你喜欢什么,你都可以自由地使用新的可变数组.

    char str[6] = "hello";
    
    Run Code Online (Sandbox Code Playgroud)
  2. 相反,在初始化指针时,您将获得一个指针,该指针是字符串文字的不可变数组类型衰减的结果.

    char const* str = "hello";
    
    Run Code Online (Sandbox Code Playgroud)

    这里没有新阵列.只需将指针复制到现有的不可变数据即可.