为什么添加到指向第一个数组成员的指针在C中循环它们?

ale*_*lex 1 c

我刚刚读到这一点,通过指向第一个数组成员的指针,您可以通过添加到指针来循环.

char my_array[] = "I am an array of chars";

char *my_pointer = my_array;

printf("%c\n", *my_pointer);

my_pointer++;

printf("%c", *my_pointer);
Run Code Online (Sandbox Code Playgroud)

我想这意味着数组成员总是按顺序存储,并且分配的空间总是保留,并且数组的大小不能扩展(因为在长度之后它可能包含内存中的其他内容)?

为什么这完全奏效?当使用下标访问数组时my_array[5],C会只知道数组的起始位置(即my_array[0]),并且必须将内部指针增加5才能返回它吗?

如果这看起来显而易见,我道歉,但我在高级语言中度过了一生,而C对我来说非常有趣.

pax*_*blo 7

抛开你的代码的问题,是的,数组是连续的元素.

下面的代码片段的第二行会发生什么:

int * iptr = malloc (40 * sizeof(int));
int x = iptr[10];
Run Code Online (Sandbox Code Playgroud)

因此:

  • 该值10乘以int得到70 的大小(在本例中,我们假设一个7字节int).
  • 然后将其添加到基指针iptr(未缩放),并从该位置提取(7字节)值.

这种缩放是一个重要的特征.你不会看到它时,你正在使用char数组,但价值观&(iptr[0])&(iptr[1])将的大小分开int,没有一个char(在本例的情况下高于7).

当您向指针添加1(实际上不添加1)时,它会添加基础数据类型的大小.以便:

int *p = &(iptr[0]);
p++;
Run Code Online (Sandbox Code Playgroud)

不会给你一个与该存储器的第二个字节对应的地址,它实际上会给你第二int个字节的地址(第七个字节).

To that end, iptr[3] is exactly equivalent to *(i+3) in that they both give you element number three, even though it's made up of bytes from offset 21 through 27 inclusive.


Pre-emptive strike, just in case: keep in mind that a byte in ISO C is not necessarily 8 bits. ISO uses the term octet for that. A byte is the size of a char.

  • `%p`需要将指针强制转换为`(void*)`(通常的隐式转换不会发生,因为它是变量参数列表的一部分). (2认同)