这是一道概念题,让我更好地理解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
而不是它应该的是?也许我误解了加法函数,但如果有人能向我解释一下,我将不胜感激。
最佳答案
From what I understand about C arrays, they store pointers to values
不,数组直接存储值。事实上,数组本质上是它们的元素。 C 不添加额外的结构。
char someCharArray[] = {'a', 'b', 'c'};
OK,这里someCharArray
由3个字节的内存组成。如果它存在于静态存储中(例如,因为它是一个全局变量),则此内存通常是数据部分的一部分;如果它存在于自动内存中(即它是一个局部变量),它通常被放置在堆栈中。
Let's say my heap doesn't have sequential 12 bits for this array
堆是怎么涉及到这里的?为什么是 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
) 到原始指针值。
我们最终得到一个值为 0xAB0001 的 char *
。
然后我们尝试将指针分配给普通 char
,这是无效的。但是我们可以使用 *
取消引用指针并获取存储在那里的值:
char x = *(someCharArray + 1); // 'b'
...或者我们可以使用指针变量:
char *ptr = someCharArray + 1; // 0xAB0001 in this example
关于C中的数组可以存储在非顺序指针中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50139288/