23

我想知道数组如何在 c 中工作。我最终得到一个假设,我想知道我是否正确。

我们知道数组是一系列相邻的内存案例(盒子),其中每个盒子都有它所存储类型的大小(即,如果 INT 一个盒子的 size = sizeof(int) 并且一个由 3 个 INT 组成的数组占用内存相邻位置3 sizeof(int) )

现在我们也知道我们可以为特定类型的数组动态分配内存(C 中的 malloc,C++ 中的 new)。

让我想知道的是,当使用括号 [0] 调用数组时,数组的原点是数组第一个框的地址和第一个值(后面框中的值)是 array[0] = = *(array+0) == *array(数组是否被声明为“type * array”或“type array[]”或“type array[size]”)和“array”以这种方式调用,无论定义为指针还是一个数组(“type * array”或“type array[]”或“type array[size]”)是第一个盒子的地址。

我最终想到,我想确认一下:即使用方括号 ([]) 声明的数组实际上在内存中也是一个 n 指针序列,每个指针都包含(作为值而不是地址)的地址一个包含实际值的记忆框 Bi + 那些记忆框(B0,...,Bn 每个都包含实际值)。这样,当一个人声明“int array[5]”时,程序实际上分配了 5 个相邻的 int 指针框 P0、P1、..、P4 和 5 个 int 大小的内存位置,分散在计算机内存 B0、B1 中。 ..,B4 其中 Pi 的值是 Bi 的地址

在此处输入图像描述

我是对还是错!???谢谢!

4

4 回答 4

13

甚至用方括号 ([]) 声明的数组实际上在内存中是一系列 n 指针,每个指针包含 [...] 包含实际值的内存盒 Bi 的地址 + 那些内存盒

没有。

听起来您很困惑,声明为和array[0] == *(array+0) == *array的数组怎么可能是真的。一个完全合理的问题;我们被告知对于指针,表达式获取指针指向的值,所以当我们对数组使用相同的语法时,我们要取消引用的地址在哪里?int array[10];int *array = ...;ptr*ptr

这是秘密:数组索引运算符 ( []) 不适用于 C 和 C++ 中的数组。当您将其应用于数组时,语言会隐式地将数组转换为指向数组第一个元素的指针。因此,添加到数组或取消引用数组看起来与添加或取消引用指针的行为相同。

int array[10];

// These lines do exactly the same thing:
int *ptr1 = &array[0]; // explicitly get address of first element
int *ptr2 = array;     // implicitly get address of first element

所以数组实际上是内存中一组连续的元素,其中每个元素都是值,而不是指向包含该值的另一​​个位置的指针。只是数组的定义方式意味着它们经常隐式转换为指针,因此当实际上只有隐式转换时似乎存在指针。

于 2013-10-14T23:04:34.663 回答
3

数组连续存储在虚拟内存中。但是,它们映射到的物理内存地址可能是连续的,也可能不是连续的。

并且数组元素不存储指向下一个元素的指针。仅存储值。

于 2013-10-14T22:25:46.523 回答
2

可以这样想:

array[n]只是 . 的语法糖*(array + n)

不,没有指针,数组实际上包含连续内存范围中的值。

于 2013-10-14T22:24:11.423 回答
0

该数组不包含任何指针。数组的元素存储在堆上,而对这些元素的引用存储在堆栈上。values如果您声明一个名为type的数组int,它由5元素组成。

变量values是指向values[0]存储在堆上的第一个值的指针,也称为基地址,即数组第一个元素的地址。您可能想知道代码如何找到数组的其他元素。values[1]可以由*(values+1)或在低级别取消引用就像这样,您要取消引用的元素的索引在*(&values + n*sizeof(values[0]))哪里。n

因此,您只需将元素的大小添加到内存中即可获得数组的其他元素。这是因为数组的元素并排存储在内存中,或者从技术上讲,内存块共享相同的边界。

数组没有任何指针,包含指针的类似数据结构的数组称为链表。

您可以在此处了解数组的内部工作

于 2021-12-06T14:27:12.727 回答