54

我知道 C 中的数组只是指向顺序存储数据的指针。但是什么不同意味着符号[]和*的不同。我的意思是在所有可能的使用环境中。例如:

char c[] = "test";

如果您在函数体中提供此指令,它将在堆栈上分配字符串,而

char* c = "test";

将指向一个数据(只读)段。

您能否在所有使用上下文中列出这两种符号之间的所有差异,以形成清晰的总体视图。

4

5 回答 5

34

根据C99标准:

数组类型描述了一组连续分配的具有特定成员对象类型(称为元素类型)的非空对象。

  1. 数组类型的特征在于它们的元素类型和数组中元素的数量。数组类型被称为从其元素类型派生,如果其元素类型是T,则该数组类型有时称为数组T。从元素类型构造数组类型称为数组类型派生

指针类型可以派生自函数类型、对象类型或不完整类型,称为引用类型。指针类型描述了一个对象,其值提供对被引用类型实体的引用。从引用类型派生的指针类型T 有时称为指向 的指针T。从引用类型构造指针类型称为指针类型派生

根据标准声明……</p>

char s[] = "abc", t[3] = "abc";
char s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };

……是相同的。数组的内容是可修改的。另一方面,声明……</p>

const char *p = "abc";

...将 p 的类型定义为指向常量char的指针,并将其初始化为指向类型为常量数组char在 C++ 中)的对象,其长度为 4,其元素使用字符串字面量进行初始化。如果尝试使用p来修改数组的内容,则行为未定义。

根据6.3.2.1数组下标取消引用和数组下标是相同的:

下标运算符的定义[]E1[E2]相同(*((E1)+(E2)))

数组与指针的区别在于:

  • 指针后面没有内存大小的信息(没有可移植的方法来获取它)
  • 无法构造不完整类型的数组
  • 指针类型可以派生自不完整的类型
  • 一个指针可以定义一个递归结构(这个是前两个的结果)

有关该主题的更多有用信息,请访问 http://www.cplusplus.com/forum/articles/9/

于 2012-07-19T08:19:41.120 回答
11
char c[] = "test";

这将创建一个包含字符串 test 的数组,以便您可以修改/更改任何字符,例如

c[2] = 'p';

但,

char * c = "test"

它是一个字符串文字——它是一个 const char。
因此,对这个字符串文字进行任何修改都会给我们带来段错误。所以

c[2] = 'p';

现在是非法的并给我们段错误。

于 2012-07-19T08:33:54.490 回答
4

char []表示类型“char 的未知边界数组”,而char *表示类型“指向 char 的指针”。正如您所观察到的,当使用字符串文字初始化“char 的未知边界数组”类型的变量的定义时,该类型将转换为“char 的数组 [N]”,其中 N 是适当的大小。这同样适用于从数组聚合初始化:

int arr[] = { 0, 1, 2 };

arr 被转换为“array[3] of int”类型。

在用户定义的类型定义 ( struct,classunion) 中,C++ 中禁止未知绑定数组类型,尽管在某些 C 版本中它们被允许作为结构的最后一个成员,在那里它们可用于访问已分配的结构结束后的内存;这种用法称为“灵活数组”。

递归类型构造是另一个区别。可以构造指向char *(例如char **char (*)[10])的指针和数组,但这对于未知边界的数组是非法的;一个人不能写或char []*char [][10]虽然很好)。char (*)[]char [10][]

最后,cv-qualification 的操作方式不同;给定typedef char *ptr_to_chartypedef char array_of_unknown_bound_of_char[],指针版本的 cv 限定将按预期运行,而数组版本的 cv 限定会将 cv 限定迁移到元素类型:也就是说,const array_of_unknown_bound_of_char等效于const char []而不是虚构的char (const) []. 这意味着在函数定义中,数组到指针的衰减在构造原型之前对参数进行操作,

void foo (int const a[]) {
    a = 0;
}

是合法的;无法使未知绑定数组参数不可修改。

于 2012-07-19T08:20:28.200 回答
1

如果您知道声明指针变量不会创建变量的类型,那么整个事情就会变得清晰,它指向。它创建一个指针变量。

因此,在实践中,如果您需要一个字符串,那么您需要指定一个字符数组,并且稍后可以使用一个指针。

于 2012-07-19T08:21:02.640 回答
0

实际上数组等价于常量指针

此外, char c[] 为数组分配内存,其基址是 c 本身。没有分配单独的内存来存储该地址。

写入 char *c 会为其基地址存储在 c 中的字符串分配内存。此外,一个单独的内存位置用于存储 c。

于 2012-07-19T08:11:47.197 回答