C字符串数组初始化-这是可变的
C-String array initialization - is this mutable?
可能重复:
修改C字符串常量
指向常量字符与字符数组与标准::字符串的指针
我知道我可能在这个问题上孤注一掷,但我有点困惑,我还没有在SO或谷歌上找到确切的答案(我相信这是对的——关于C字符串的信息太多了,无法筛选)。另外,我把它标记为C++,因为这就是我感兴趣的地方,尽管我们谈论的是C风格的字符串。
在这种情况下:
char const a* = "hello";
char const b[] = "goodbye";
我本以为"hello"answers"再见"都是不可变的字符串,因为它们来自应该衰减为char const*的字符串文本。
不过,我已经看到,在这种特殊的情况下,如果从b数组中去掉了constness,那么更改"hello"将是未定义的,而更改"再见"则可以。
我假设字符串在b的情况下是可变的,因为它存储在用户定义的数组中。
在这种情况下,你好和再见有区别吗由于某些原因,在给定此示例的情况下,再见不是字符串文字。此外,如果再见不是字符串文字,我能假设它没有保存在全局内存中,并且在编译时对它的唯一引用是留在用户数组单元格中的引用吗?
第一个创建一个指针,指向字符串文本"hello"
,该文本可能存储在程序的可执行映像中的不可写内存中。即使不是,也不允许修改该数组的内容。
第二个创建一个自动数组1(在堆栈上(通常,但这是实现定义的)),并用字符串"goodbye"
初始化它。它相当于
char const b[] = {'g', 'o', 'o', 'd', 'b', 'y', 'e', 0};
因此,虽然"goodbye"
是不可变的,因为它是一个字符串文字,是char const[8]
并存储在不可写的内存中,但数组b
是一个自动的1数组,它不可变,因为您将其标记为const
,但您可以从变量声明中删除const
,使数组的内容可变。您只是用数组"goodbye"
的内容初始化数组的内容。
不允许修改其中任何一个,因为它们都是const char[]
,但第二个可以更改为char[]
以使其可变,而第一个不能。
查看此答案以了解更多信息:https://stackoverflow.com/a/9106798/726361
1正如R.Martinho Fernandes在评论中指出的那样,如果语法T x[] = ...
在命名空间范围内,它也可以创建一个静态数组(不是自动的,而是静态的(通常在可执行映像中,但这是实现定义的),否则它只是一个自动数组。
字符串文字的类型为char const[N]
;当然,这种类型的名称可以衰减为CCD_ 13。
现在:
-
char
数组可以通过字符串文字(8.5.2/1)进行初始化,并且由于不能以其他方式复制或分配数组,因此这种初始化实现了复制。您可以随心所欲地使用新的可变数组。char str[6] = "hello";
-
相反,初始化指针时,您获得的指针是字符串文字的不可变数组类型衰减的结果。
char const* str = "hello";
这里没有新的数组。只是复制一个指向现有不可变数据的指针。
它们是不同的。a
指向一个无法更改的字符串文字。但是,b
是一个使用给定字符串初始化的字符数组。假设const
已删除,则可以更改b
的内容。
是的,它们不同。
字符串文字本身("hello"
和"goodbye"
)确实是不可变的。但是,当您访问b
时,您并没有访问原始的"goodbye"
。您使用的代码声明了一个完全独立的数组b
,它只是用字符串"goodbye"
初始化的。您的'b'完全独立于原始字符串文字"goodbye"
。您的b
是该字符串文字的副本。您的"b"是不可变的唯一原因是您显式包含在其声明中的const
。删除const
,您的b
将变得完全可变,就像任何普通数组一样。
至于您的"a",它是一个直接指向原始字符串文本"hello"
的指针。当然,它是不可变的。
这两个选项都是不可变的,但这并不是因为它们是从字符串文字创建的。它们是不可变的,因为变量声明中有const
关键字。
您还可以编写char c[] = "string_c";
,并创建文字string_c
的可变副本(名为c
)。
在您关于删除b
常量的示例中,在某些情况下,这可能会出现,但就标准而言,这仍然是非法的。只有真正非常量的对象才能发生突变。
- 将C#字符串数组传递给C++
- 如何为 C 型字符串数组编写 getter 和 setter?
- 有没有办法使用 strcpy 将字符串数组复制到另一个字符串或其他数组中?
- 尝试将 c 字符串数组与分隔符连接起来
- 将字符串数组传递给接受常量字符**的函数
- 返回 C++ 中的字符串数组
- 如何从COM模块中的函数返回字符串数组?
- 无法将字符串数组声明为类成员而不是字符 (C++)
- 删除字符串数组
- 如何将字符串数组返回到 java JNI
- 将字符串数组作为函数参数传递
- C++将字符串数组的元素存储到变量中
- 循环访问还包含未使用元素的字符串数组
- 字符串数组上的 sizeof 运算符以 C++ 为单位给出不同的输出
- 乘以字符串/数组和全局数组
- 递归二进制搜索与字符串数组
- 如何初始化一个标准::字符串数组?
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- C++字符串数组的动态向量
- 给定一个等长字符串数组