C/C++ int[] vs int*(指针vs.数组表示法),有什么区别吗?

k97glaaz  于 2023-05-16  发布在  C/C++
关注(0)|答案(5)|浏览(148)

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

char c[] = "test";

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

char* c = "test";

将指向数据(只读)段。
你能列出这两种符号在所有使用上下文中的所有差异,以形成一个清晰的总体视图吗?

sqougxex

sqougxex1#

根据C99标准:
数组类型描述具有特定成员对象类型(称为元素类型)的连续分配的非空对象集。
1.数组类型的特征在于它们的元素类型和数组中元素的数量。数组类型被称为从其元素类型派生,如果其元素类型为T,则数组类型有时称为 array of 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* 的指针,并将其初始化为指向类型为 constant array of char(C++中的***)的对象,长度为4,其元素使用字符串文字初始化。如果尝试使用p修改数组的内容,则行为未定义。
根据 6.3.2.1数组下标解引用和数组下标相同:
下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))
数组和指针的区别是:

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

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

cdmah0mi

cdmah0mi2#

char c[] = "test";

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

c[2] = 'p';

但是

char * c = "test"

它是一个字符串常量。
因此,对这个字符串字面量进行任何修改都会导致segfault。所以呢

c[2] = 'p';

现在是非法的,并给我们segfault。

92dk7w1h

92dk7w1h3#

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

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

arr被转换为类型“array[3] of int”。
在用户定义的类型定义(structclassunion)中,未知绑定类型的数组在C++中是禁止的,尽管在某些C版本中,它们被允许作为结构体的最后一个成员,在那里它们可以被用来访问结构体末尾之后的分配内存;这种用法被称为“灵活阵列”。
递归类型构造是另一个区别;可以构造指向char *的指针和char *的数组(例如,char **char (*)[10]),但这对于未知边界的数组是非法的;不能写char []*char [][10](尽管char (*)[]char [10][]是好的)。
最后,CV-资格的运作方式不同;给定typedef char *ptr_to_chartypedef char array_of_unknown_bound_of_char[],cv-qualifying指针版本将按照预期的行为,而cv-qualifying数组版本将迁移cv-qualifying到元素类型:也就是说,const array_of_unknown_bound_of_char等价于const char [],而不是虚构的char (const) []。这意味着在函数定义中,数组到指针的衰减在构造原型之前对参数进行操作,

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

是法律的的;没有办法使unknown-bound参数的数组不可修改。

1hdlvixo

1hdlvixo4#

如果你知道声明一个指针变量并不创建变量的类型,它指向。创建一个指针变量。
所以,在实践中,如果你需要一个字符串,那么你需要指定一个字符数组,一个指针可以在以后使用。

rwqw0loc

rwqw0loc5#

实际上,数组等价于 * 常量指针 *。
此外,char c[]为数组分配内存,其基址是c本身。不分配单独的存储器来存储该地址。
写入char *c将为基址存储在c中的字符串分配内存。另外,单独的存储器位置用于存储c。

相关问题