char a[]="string";和char *p="string"的区别是什么?

15

3
能否简化这个问题? - liori
1
@liori:char a[]="s"; != char *p="s"; ? :) - PeterM
1
http://c-faq.com/decl/strlitinit.html - nc3b
5个回答

29
第一个是数组,第二个是指针。
数组声明 "char a[6];" 请求分配六个字符的空间,并以名称"a"命名。也就是说,在某个位置有一个名为 "a" 的位置,可以容纳六个字符。另一方面,指针声明 "char *p;" 请求分配一个保存指针的位置。该指针将被命名为 "p",并且可以指向任何 char(或连续的 char 数组)的位置。
下面的语句:
char a[] = "hello";
char *p = "world";

这将导致数据结构可以表示为:

   +---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |
   +---+---+---+---+---+---+
   +-----+     +---+---+---+---+---+---+
p: |  *======> | w | o | r | l | d |\0 |
   +-----+     +---+---+---+---+---+---+
重要的是要意识到,像x[3]这样的引用根据x是否为数组或指针而生成不同的代码。在上述声明中,当编译器看到表达式a[3]时,它会发出从位置"a"开始移动三个位置并获取那里的字符的代码。当它看到表达式p[3]时,它会发出从位置"p"开始获取指针值,将三个添加到指针,最后获取指向的字符的代码。在上面的例子中,a[3]和p[3]都恰好是字符'l',但编译器的实现方式略有不同。
你可以使用搜索,在互联网上有大量关于这个主题的解释。

4
第一种情况和第二种情况中,内存分配在哪里?栈?堆?当你决定将指针p指向其他东西时,这是否意味着"world"会被释放? - Laz
3
在第一种情况下,它取决于定义的位置;如果它在函数中,则可能在堆栈上,如果它在结构体中,则取决于整个结构体从哪里分配;如果它在任何函数外部,则在全局变量段中。指针p也是同样的情况;而指针p所指向的“world”字符串通常位于可执行文件的特定部分中,在加载时映射到内存中,并用作字符串表。 - Matteo Italia

10

char a[]="string"; //a 是一个字符数组。

char *p="string";// p 是一个静态分配的字符串字面量。任何试图修改p内容的尝试都会导致未定义行为,因为字符串字面量存储在只读内存段中。


3

没有区别。除非你想要实际写入数组,否则如果你尝试使用第二种形式,整个世界都会爆炸。详情请见这里


2

第一个声明声明了一个数组,而第二个声明声明了一个指针。

如果您对某个特定方面的差异感兴趣,请明确您的问题。


1

一个区别是,sizeof(a)-1将在编译时被替换为字符串的长度。对于p,需要使用strlen(p)在运行时获取长度。此外,一些编译器不喜欢char *p="string",他们希望const char *p="string",在这种情况下,“string”的内存是只读的,但a的内存不是。即使编译器不要求const声明,修改指向p的字符串(即*p='a')也是不好的实践。指针p可以更改为指向其他内容。对于数组a,必须将新值复制到数组中(如果它适合的话)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接