1. 数组在内存中的真实面貌
记得我刚开始学C语言的时候,老师告诉我们"数组就是一片连续的内存空间",当时我其实不太理解这句话的深层含义。直到后来我真正看到内存中的数据布局,才恍然大悟。
当我们声明一个数组,比如 int arr[5] = {1, 2, 3, 4, 5};,编译器会在内存中分配一块连续的区域。假设这块内存从地址0x1000开始,那么内存布局是这样的:
地址 值
0x1000: 1 // arr[0]
0x1004: 2 // arr[1]
0x1008: 3 // arr[2]
0x100C: 4 // arr[3]
0x1010: 5 // arr[4]
这里有个很重要的细节:每个int占4个字节,所以地址每次增加4。这就是为什么指针运算时,p + 1 实际上会让地址值增加4而不是1——因为指针知道它指向的是int类型。
我在调试时经常用这样一个技巧来验证内存布局:
printf("arr: %p\n", arr);
printf("&arr[0]: %p\n", &arr[0]);
printf("&arr[1]: %p\n", &arr[1]);
你会发现 arr 和 &arr[0] 的值完全相同,而 &arr[1] 比它们大4。这就是数组连续存储的最直接证据。
2. 指针运算的底层魔法
很多人觉得指针运算很神秘,其实它的原理很简单。当我们写 arr[i] 时,编译器在底层会把它转换成 *(arr + i)。但这个转换过程蕴含着精妙的设计。
让我用一个实际的例子来说明。假设我们有这样的代码:
int arr[5] = {


被折叠的 条评论
为什么被折叠?



