[英]Why can´t we assign a new string to an char array, but to a pointer?
我试图将一个字符串重新分配给一个预先初始化的数组 a[],但我得到的只是一个错误
main()
{
char a[] = "Sunstroke";
char *b = "Coldwave";
a = "Coldwave";
b = "Sunstroke";
printf("\n %s %s",a,b);
}
[错误]:从类型 'char *' 分配到类型 'char[10]' 时类型不兼容。
char a[] = "Sunstroke";
但它没有用...
但是在指针的情况下,就像上面的程序一样..
要了解这里发生了什么,有两个语言规则很重要:
了解像"Sunstroke"
这样的字符串文字是什么也很重要。 它是一个常量字符的静态数组,大到足以容纳以终止符结尾的字符串的所有字符。 所以在这种情况下,它是一个const char[10]
数组,包含九个字符,后跟零值终止符。 作为static ,数组在程序的生命周期内存储在内存中的某处。
char a[] = "Sunstroke";
这将创建一个本地数组,并通过从字符串文字中复制字符来初始化它。
char *b = "Coldwave";
这将创建一个指针,并将其初始化为指向文字本身。 请注意,这是危险的:文字是const
,但指针不是,因此您可以编写尝试修改文字的代码,从而给出未定义的行为。 这种转换已被弃用(当然在 C++ 中,我不确定 C),因此编译器应该给你一个警告。 您已经启用了所有可能的编译器警告,不是吗?
a = "Coldwave";
这会尝试重新分配数组,但由于数组不可分配而失败。 没有特别好的理由为什么他们不是。 这就是语言进化的方式。
b = "Sunstroke";
这会重新分配指针以指向不同的文字。 这很好(除了上面提到的缺少const
之外)。
如果您需要操作字符串,则:
<string.h>
的库函数(或您自己编写的代码)来操作这些数组中的字符;std::string
类为您处理内存管理、分配等。诸如“Coldwave”之类的硬编码字符串文字实际上是char[]
(字符数组)类型——但修改它们是未定义的行为( C99 :6.4.5.6)。 但是请注意,下面的b
仍然是一个char*
(字符指针):
char *b = "Coldwave";
已为其分配了char[]
。 没关系。 但它与此不同:
char a[] = "Coldwave";
这是char[]
的初始化。 您只能在声明变量时初始化一次,并且初始化是您可以通过这样的赋值填充数组或其他复合类型(例如结构)的唯一情况。 但是,您不能这样做:
char c[] = a;
因为当在赋值的右侧使用时,数组变量充当指向它们所代表的数组的指针,这就是char *b = a
起作用的原因。
所以你不能用上面的变量做到这一点的原因:
a = b;
// or
a = "Sunstroke";
是因为那会将char*
分配给char[]
—— 不好; 你只能反过来做。
在C的情况下,如果我们查看c99 草案标准第6.5.16
节赋值运算符第2段说:
赋值运算符应有一个可修改的左值作为其左操作数。
和第6.3.2.1
节左值、数组和函数指示符第1段说:
[...]可修改的左值是没有数组类型的左值[...]
因此,由于数组不是可修改的左值,因此您无法分配给它们。 至于初始化部分6.7.8
初始化第14段说:
字符类型的数组可以由字符串文字[...]
在C++ 草案标准中,相关部分是4.2
Array-to-pointer conversion第1段,它说:
“NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。 结果是指向数组第一个元素的指针。
prvalue是纯右值,第5.17
节赋值和复合赋值运算符第1段说:
[...]都需要一个可修改的左值作为它们的左操作数[...]
让我将程序简化为:
char a[] = "Sunstroke";
char *b = a;
假设a
的地址是100,那么在内存中,它看起来是这样的(仅说明指针大小和字节序等可能会有所不同):
[S] [u] [n] [s] [t] [r] [o] [k] [e] [\0] ... [0] [0] [0] [100]
100 101 102 103 104 105 106 107 108 109 200
^ ^
| |
a b
只要数组的生命周期, a
永远是同一个地方,你不能修改它。
b
,另一方面,是一个包含数组地址的指针,你可以修改b
的值指向其他地方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.