在C中,char * s和char s []之间的区别是否适用于其他类型?

时间:2016-12-29 00:29:47

标签: c syntax

我看过(12):

char s[] = "abc";
char t[3] = "abc";

实际上与:

完全相同
char s[] = { 'a', 'b', 'c', '\0' };
char t[] = { 'a', 'b', 'c' };

以下内容:

char *word = "abc";
word[0] = 'd';

word放在只读内存中,导致非法内存操作word[0] = 'd'出错。

这只是char的情况吗?当我做这样的事情时,我不会得到错误:

int array[] = {1, 2, 3};
int *p = array;
p[0] = 0; // No error here
array[1] = 1; // or here

2 个答案:

答案 0 :(得分:7)

它仅适用于字符串文字

字符串文字隐式创建类型为char[N]的数组对象,其中包含文字中的字符,后跟终止\0'字符。此对象具有静态存储持续时间,并且是只读的。 (由于历史原因,它不是const,但是尝试修改它有不确定的行为。)

当你写:

char *ptr = "abc";

您正在创建ptr作为指针对象,并将其初始化为指向包含"abc"的只读静态数组。 (您可以通过将其定义为const来阻止尝试修改它。)

当你写:

char arr[] = "abc";

您将arr创建为char[4]类型的数组对象,并将静态只读数组的内容复制到该对象中。 arr不是只读的。

int array[] = {1, 2, 3};

创建一个数组对象并如图所示初始化它。没有"整数数组文字"这就像字符串文字一样。 (几乎是 - 参见"复合文字" - 但那些不具有与字符串文字相同的只读语义。)

请注意:

char t[3] = "abc";

是一种特殊情况:如果使用字符串文字初始化数组,并且终止'\0'没有空间,则只有非空字符被复制到数组中。因此,t不包含字符串,只包含未终止的字符序列。这与您的问题并不特别相关。

答案 1 :(得分:1)

对于其他数组类型的字符串文字,没有确切的模拟。但是你可以通过使用const限定的复合文字

来接近
const int *p = (const int []) { 1, 2, 3 };

有可能将它放入只读内存中,并且如果尝试修改它(在抛弃constness之后)可能会使程序崩溃。与字符串文字的另一个相似之处是const限定的复合文字可能共享存储。

复合文字和字符串文字之间的一个明显区别是字符串文字总是具有静态存储持续时间,而块级复合文字具有自动存储持续时间。