我试图将一个字符串重新分配给一个预先初始化的数组a[],但我得到的只是一个错误
main()
{
char a[] = "Sunstroke";
char *b = "Coldwave";
a = "Coldwave";
b = "Sunstroke";
printf("\n %s %s",a,b);
}
字符串
【错误】:当从类型'char'赋值给类型'char[10]'时,不兼容的类型..我搜索了这个,但找不到任何原因..我还试图通过重新声明重新赋值,如
char a[] = "Sunstroke";
型
但它没有工作…
但在指针的情况下,它是可能的,如在上述程序。
4条答案
按热度按时间ibps3vxo1#
要理解这里发生的事情,两个语言规则很重要:
同样重要的是要理解什么是像
"Sunstroke"
这样的 string literal。它是一个常量字符的静态数组,足够大,可以容纳一个字符串的所有字符,结尾有一个终止符。所以在这个例子中,它是一个const char[10]
数组,包含9个字符,后跟一个零值终止符。作为 static,数组在程序的生命周期内存储在存储器中的某个地方。字符串
这将创建一个本地数组,并通过从字符串字面量复制字符来初始化它。
型
这将创建一个指针,并初始化它以指向文字本身。请注意,这是危险的:文字是
const
,但指针不是,因此您可以编写代码尝试修改文字,从而产生未定义的行为。(当然在C++中,我不确定C),所以编译器应该给你一个给予警告。你已经启用了所有你能启用的编译器警告,不是吗?型
这试图重新分配数组,但失败了,因为数组是不可分配的。没有特别好的理由为什么它们不是;这只是语言进化的方式。
型
这将重新分配指针指向不同的文字。这很好(除了上面提到的缺少
const
)。如果你需要操作字符串,那么:
<string.h>
中的库函数(或你自己手工编写的代码)来操作这些数组中的字符;std::string
类为您处理内存管理,分配等。sbtkgmzw2#
硬编码的字符串字面量,如“Coldwave”实际上是
char[]
(字符数组)类型-但修改它们是 * 未定义的行为 *(C99:6.4.5.6)。请注意,下面,然而,b
仍然是char*
(字符指针):字符串
char[]
被分配给它。没关系。但它与此不同:型
这是一个
char[]
的 * 初始化 *。你只能初始化一个变量一次,当它被声明时,初始化是你可以通过像这样的赋值来填充数组或其他复合类型(如结构体)的唯一情况。但是,你不能这样做:型
因为当在赋值的右侧使用时,数组变量的作用是指向它们所表示的数组的指针,这就是
char *b = a
工作的原因。所以你不能用上面的变量做这个的原因是:
型
因为这将把
char*
赋值给char[]
--不好;只能反过来做。a14dhokn3#
在 C 的情况下,如果我们看c99 draft standard部分
6.5.16
* 赋值运算符 * 段落 2 说:赋值运算符必须有一个可修改的左值作为其左操作数。
第
6.3.2.1
节 * 左值、数组和函数指示符 * 第1段 * 说:[...]可修改的左值是没有数组类型[...]的左值
因此,由于数组是不可修改的左值,所以你不能给它们赋值。至于初始化部分
6.7.8
* paragraph 14 说:字符类型的数组可以由字符串字面量[...]初始化。
在C++ draft standard中,相关的部分是
4.2
* 数组到指针转换 * 段落 1,内容如下:类型为“array of N T”或“array of unknown bound of T”的左值或右值可以转换为类型为“pointer to T”的纯右值。结果是指向数组第一个元素的指针。
a prvalue是纯右值,而section
5.17
* 赋值和复合赋值运算符 * paragraph *1 * 表示:[...]都需要一个可修改的左值作为它们的左操作数[...]
ktecyv1j4#
让我们将程序简化为:
字符串
假设
a
的地址是100,那么在内存中,它看起来像这样(仅说明指针的大小和字节序等可能会有所不同):型
只要在数组的生命周期内,
a
将永远在同一个地方,你不能修改它。另一方面,
b
是一个包含数组地址的指针,您可以**修改b
的值以指向其他位置。