我知道C中的数组只是指向顺序存储数据的指针。但是,差异意味着符号[]和*的区别。我的意思是在所有可能的使用环境中 例如:
char c[] = "test";
如果在函数体中提供此指令,则会在
时将字符串分配到堆栈中char* c = "test";
将指向数据(只读)段。
您是否可以在所有使用情境中列出这两种表示法之间的所有差异,以形成清晰的一般视图。
答案 0 :(得分:23)
根据C99标准:
数组类型描述了连续分配的非空集 具有特定成员对象类型的对象,称为元素 类型。
36)数组类型的特征在于它们的元素类型和 数组中的元素数量。据说是一种数组类型 派生自其元素类型,如果其元素类型为
T
,则为数组 type有时被称为{em>T
的数组。阵列的构造 元素类型的类型称为数组类型派生。
指针类型可以从函数类型,对象类型或 一个不完整的类型,称为引用类型。指针类型 描述一个对象,其值提供对实体的引用 引用的类型。从引用的类型
T
派生的指针类型 有时被称为指向T
的指针。指针的构造 引用类型的类型称为指针类型派生。
根据标准声明...
char s[] = "abc", t[3] = "abc";
char s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };
......完全相同。数组的内容是可修改的。另一方面,宣言......
const char *p = "abc";
...将p类型定义为指向常量char
的指针,并将其初始化为指向类型为常量数组char
的对象( in C ++ )长度为4,其元素用字符串文字初始化。如果尝试使用p
修改数组的内容,则行为未定义。
根据 6.3.2.1 数组下标 解除引用和数组下标相同:
下标运算符
[]
的定义是E1[E2]
与(*((E1)+(E2)))
相同。
数组与指针的区别在于:
这些链接可能对主题有用:
答案 1 :(得分:9)
char c[] = "test";
这将创建一个包含字符串test的数组,以便您可以修改/更改任何字符,比如说
c[2] = 'p';
但是,
char * c = "test"
这是一个字符串文字 - 它是一个常量字符 因此,对此字符串文字进行任何修改都会给我们带来段错误。所以
c[2] = 'p';
现在是非法的,并且给了我们段错误。
答案 2 :(得分:4)
char []
表示类型“char的未知边界数组”,而char *
表示类型“指向char的指针”。正如您所观察到的,当使用字符串文字初始化“char未知边界数组”类型的变量的定义时,该类型将转换为“char的数组[N]”,其中N是适当的大小。这同样适用于从数组聚合初始化:
int arr[] = { 0, 1, 2 };
arr被转换为“array”[3] of int“。
在用户定义的类型定义(struct
,class
或union
)中,C ++中禁止使用未知绑定类型的类型,尽管在某些版本的C中它们是允许作为结构的 last 成员,在结构中,它们可用于访问结构末尾的已分配内存;这种用法称为“灵活数组”。
递归式构造是另一个区别;一个人可以构造指向char *
的数组和char **
的数组(char (*)[10]
,char []*
),但这对于未知范围的数组来说是非法的;一个人不能写char [][10]
或char (*)[]
(虽然char [10][]
和typedef char *ptr_to_char
都可以。)
最后,cv-qualification的运作方式不同;给定typedef char array_of_unknown_bound_of_char[]
和const array_of_unknown_bound_of_char
,cv-qualifi指针版本将按预期运行,而cv-qualifying数组版本将cv-qualification迁移到元素类型:即const char []
相当于char (const) []
,而不是虚构的void foo (int const a[]) {
a = 0;
}
。这意味着在函数定义中,数组到指针衰减在构造原型之前对参数进行操作,
{{1}}
是合法的;没有办法使未知绑定数组的参数不可修改。
答案 3 :(得分:1)
如果你知道声明一个指针变量没有创建变量的类型,它就会变得清晰。它创建一个指针变量。
所以,实际上,如果你需要一个字符串,那么你需要指定一个字符数组,稍后可以使用指针。
答案 4 :(得分:0)
实际上,数组等同于常量指针。
此外,char c []为数组分配内存,其基址为c本身。没有分配单独的内存来存储该地址。
写char * c为其基址存储在c中的字符串分配内存。此外,单独的内存位置用于存储c。