char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
4 回答
amessage
是类型char[16]
。它是一个数组。数组的元素包含字符串文字中的 16 个字符。
pmessage
是类型char*
。它是一个指针。它指向一个(不可修改的)数组,其中包含字符串文字中的 16 个字符。(您应该避免使用 achar*
来指向字符串文字;这样做是邪恶的。const char*
在引用字符串文字时,您应该始终使用 a 。)
如果您使用的是 GCC,请打开 -Wwrite-strings。固定字符串的类型为 const char[length_of_string],转换为 char * 将引发警告 [需要为 const]。
第一个赋值是一个字符数组赋值,而第二个赋值是一个基于指针的赋值(结果字符串被保存为一个固定字符串)
第一个赋值是可以接受的,而第二个需要一个 const 限定符。
在第一次分配中,改变一个点是可以接受的(例如,message[3] = 'q')。在第二个任务中,改变一个点是不可接受的(因为字符串是 const )——你应该得到一个总线错误
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
在 C 中,“=”左边的东西被称为“左值”。该类型仅由“左值”定义。所以'消息'是一个字符数组。'pmessage' 是一个指向字符的指针。
在 C 中,关于数组类型和 'char *' 访问之间的等价以及非等价的内容在 C 中继续进行。
正如声明的“pmessage”是一个可修改的“左值”——“消息”是不可修改的。因此,建议将 'pmessage' 声明为 const,因为它实际上也不应该被修改。
例如
const char* const pmessage = "...";
在内存访问方面,“消息”导致直接访问,而“消息”需要取消引用。
注意:C 编译器只允许在编译时通过字符串文字初始化 'char *'。
例如,如果你有
1. {
2. int j = 1;
3. int *k = &j;
4. int *i = 1;
5. }
第 4 行没有意义,而且是非法的。
强烈推荐 Peter Van Linden 的“Deep C Secrets”,他有一整章关于 C 数组和指针。
除了 James McNellis 的回答之外,amessage
还有一件事——堆栈上的 16 个字符数组恰好包含字符串“now is the time”(因为它们在amessage
创建时被复制到那里)。您可以更改其中包含的内容。
另一方面,pmessage
有两件事——一个字符串文字(存储在内存的不可写部分)和一个指针。您无法更改字符串文字的内容,但您可以更改指针指向的内容,并使其指向不同的字符串。您可以将字符串文字用作其他指针的目标。
(从某种意义上说,这并不完全正确——amessage
还涉及一个字符串文字,因为它是创建内容时复制内容的地方。但是之后你不能对那个字符串文字做任何其他事情。)