“ int array [int]”与“ int * array”之间的混淆

时间:2019-01-24 11:26:51

标签: c arrays pointers memory-management

int array[100];

int *array;

所以我对int array[100]int * array之间的差异感到困惑。

当我执行int array[100]时很重要(100只是int的一个示例),我只是在内存中保留了100个整数,但是我可以执行int * array并且我没有为该数组指定任何类型的大小,但是我仍然可以进行array[9999] = 30,这仍然有意义。

那么这两者之间有什么区别?

7 个答案:

答案 0 :(得分:5)

指针是一个 pointer ,它指向其他地方(如数组的第一个元素)。编译器没有关于它可能指向的位置或它可能指向的数据大小的任何信息。

一个数组是由多个相同类型的连续元素组成的数组。编译器知道它的大小,它总是指定大小(尽管有时大小是隐式指定的)。

可以初始化数组,但不能分配给它。数组也经常衰减到指向其第一个元素的指针。

数组衰减示例:

int array[10];

int *pointer = array;  // Here the symbol array decays to the expression &array[0]

// Now the variable pointer is pointing to the first element of array

数组自然不能传递给函数。当您声明诸如int arr[]之类的函数参数时,编译器会将其翻译为int *arr

所有这些信息以及更多信息,都应该放在任何好书,教程或课堂中。

答案 1 :(得分:2)

不同之处在于,执行int array[100]时,在{em> stack 中分配了100 * sizeof(int)的存储块,但是执行int *array时,需要动态分配内存(例如,使用malloc函数)以使用array变量。动态分配的内存位于上,而不是 stack 上。

答案 2 :(得分:2)

int array[100]表示变量array,该变量将能够容纳100个int值,此内存将从堆栈中分配。变量array将具有数组的基地址,并且将为其分配内存。

但是对于int *array,由于您将其声明为局部变量,因此指针变量array将具有垃圾地址。因此,如果您尝试array[9999],则可能会导致分段冲突,因为您正在尝试访问程序外部的垃圾内存位置。

答案 3 :(得分:1)

非技术性解释:

指针的内容引用一个地址(可能有效或无效)。数组具有地址(该地址必须有效才能使该数组存在)。

您可以认为指针就像信封一样-可以在上面放置任何想要的地址,但是如果要将其发送到特定的地方,则该地址必须正确。

一个数组就像你的房子-它存在于某个地方,所以它有一个地址。正确解决的问题会被发送到那里。

简而言之:

指针持有一个地址。

一个数组具有一个地址。

所以

int *array;

创建一个不确定值的指针 (它可以指向任何地方!)。

当你拥有

array[9999] = 30;

您正在尝试将第int指向的第9999个array值设置为30的值。但是您不知道array的位置点,因为您没有提供实际值。

那是未定义的行为。

答案 4 :(得分:1)

int * array中未指定大小,array[9999] = 30可能会导致分段错误,因为这可能会导致无法访问的内存的访问

答案 5 :(得分:1)

一些有用的知识点:

  • 通过int arr[N],您可以指定类型为int一个数组,该数组可以存储N 整数。要获取有关占用多少内存阵列的信息,可以使用sizeof运算符。只需将数组中的项目数乘以类型N*sizeof(int)的大小即可。
  • 数组名称指向数组中的第一个元素,例如*arrarr[0]相同,您可能还会想知道为什么a[5] == 5[a]
  • 非静态存储持续时间的未初始化数组填充有不确定的值。
  • 如果运行int arr[] = {1, 2},则数组的大小可能在运行时已知。
  • 访问不存在的元素会导致未定义的行为,这意味着有可能发生任何事情,并且在大多数情况下,您会获得垃圾值。

  • 通过int *array,您可以指定类型为array指针 int
  • 除非分配了值,否则默认情况下,指针将指向某个垃圾地址。
  • 如果您根本不分配内存,或者不完全分配内存或访问不存在的元素,但是尝试将指针用作数组,则会出现未定义的行为。
  • 分配内存后(不再需要指针时),应释放内存。

答案 6 :(得分:0)

int array[100];定义了int数组

int *array;int定义了一个指针。该指针可能指向int变量或int数组的元素,或者根本没有指向(NULL),甚至指向其中的任意,有效或无效地址。内存,当它是未初始化的局部变量时就是这种情况。调用此指针array有点误导,但在命名确实指向实际数组的函数参数时经常使用。编译器无法根据指针值确定数组的大小。

这是一个地形隐喻:

  • 将数组想像成具有建筑物的街道。它具有GPS坐标(内存地址),名称(但不总是)和固定数量的建筑物(在给定时间很难更改)。街道名称和建筑物编号一起指定了精确的建筑物。如果您指定的数字大于最后一个数字,则该地址无效。

  • 指针是完全不同的东西:将其视为地址标签。这是一张小纸,可以用来识别建筑物。如果为空(空指针),则无用,如果将其粘贴到字母上并发送,则字母将丢失并被丢弃(行为不确定,但很容易看出它是无效的)。如果您在上面写了一个无效的地址,则效果是相似的,但是在交付失败之前(未定义的行为且难以测试)可能会花费更多。

  • 如果街道被夷为平地(如果释放了内存),则先前编写的地址标签不会被修改,但是它们将不再指向任何有用的内容(如果发送信件,则行为不确定,这是困难的一种)。如果以后用标签上的名称命名了一条新街道,则可能会发送该字母,但可能不符合预期(再次发生未定义的行为,释放了内存,而其他分配的对象恰好位于相同的内存地址)。

  • 如果您将建筑物传递给功能,通常不会发掘并运输它,而只是传递其街道地址(指向街道第n座建筑物的指针) ,&array[n])。如果您未指定建筑物,而只是命名街道,则意味着转到街道的起点。同样,当将数组传递给函数为C时,函数会收到指向数组开头的指针,我们说 arrays会随着指针的衰变