C中的数组可以存储在非顺序指针中吗?

时间:2018-05-02 16:21:59

标签: c arrays

这是一个概念性的问题,让我更好地理解C.根据我对C数组的理解,它们存储指向按照分配的空间顺序生成的值的指针。例如,如果我有这个代码

char someCharArray[] = {'a', 'b', 'c'};

假设我的堆没有为此数组提供连续的12位,因此我将指针存储到以下非连续地址0x001, 0x011, 0x040

我知道有两种方法可以访问此数组中的值,如this answer所示。

让我说我像这样访问数组的第二个元素

char datPointer = someCharArray[1];

在这种情况下,datPointer将指向0x011,因为地址存储在数组中。

但是,以下代码是否会返回错误的地址?

char datWrongPointer = (someCharArray + 1);

因为我将顺序地址添加到someCharArray的起始地址,所以假设字符为4位,我将datWrongPointer变为0x004而不是它应该是什么?也许我误解了添加功能,但如果有人能向我解释,我会很感激。

1 个答案:

答案 0 :(得分:4)

  

根据我对C数组的理解,它们存储指向值的指针

不,数组直接存储值。实际上,基本上的数组是它们的元素。 C不增加额外的结构。

char someCharArray[] = {'a', 'b', 'c'};

好的,这里someCharArray由3个字节的内存组成。如果它存在于静态存储中(例如因为它是全局变量),则该存储器通常是数据部分的一部分;如果它存在于自动存储器中(即它是一个局部变量),它通常放在堆栈上。

  

让我们说我的堆没有这个数组的顺序12位

这里的堆是如何涉及的?为什么12位? C并不真正支持小于1字节的对象(字节不能小于8位)。

为了一个例子,我们假设someCharArray最终被放置在地址0xAB0000处。然后第一个元素位于0xAB0000,第二个元素位于0xAB0001,第三个元素位于0xAB0002。

char datPointer = someCharArray[1];

datPointer不是指针,它只是一个char。此代码会将'b'分配给datPointer(因为someCharArray[1]'b')。

char datWrongPointer = (someCharArray + 1);

这是类型错误。

someCharArray计算指向其第一个元素的指针(如数组所做的那样,除非它们是sizeof&的操作数)。这为我们提供了char *类型的值(并且在上面,值为0xAB0000)。

我们添加1,它添加了足够的字节来到达内存中的下一个元素。这里的指针类型为char *,因此我们将1 * sizeof (char)(只是1 * 1,只是1)添加到原始指针值。

我们最终得到一个char *,其值为0xAB0001。

然后我们尝试分配一个指向普通char的指针,该指针无效。但是我们可以用*取消引用指针并获取存储在那里的值:

char x = *(someCharArray + 1);  // 'b'

...或者我们可以使用指针变量:

char *ptr = someCharArray + 1;  // 0xAB0001 in this example