C / C ++ int [] vs int *(指针与数组表示法)。有什么不同?

时间:2012-07-19 07:35:58

标签: c++ c arrays pointers standards

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

char c[] = "test";

如果在函数体中提供此指令,则会在

时将字符串分配到堆栈中
char* c = "test";

将指向数据(只读)段。

您是否可以在所有使用情境中列出这两种表示法之间的所有差异,以形成清晰的一般视图。

5 个答案:

答案 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“。

在用户定义的类型定义(structclassunion)中,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。