17. 指针类型和步长概念问题
1. 项目场景:
➣ Jack Qiao对米粒说:“今天有道友遇到一个问题,举个栗子数组 arr[5] = { 0 };道友发现&arr[0] + 1与&arr + 1打印出来的地址竟然不同。”米粒测试后果然是这样。
2. 问题描述
☑ 举个栗子:数组 arr[5] = { 0 };道友发现&arr[0] + 1与&arr + 1打印出来的地址竟然不同。
☛ 测试的数据代码:
#include<stdio.h> int main() {int arr[5] = { 0 };printf("%p\n", arr);printf("%p\n", arr + 1);printf("------------------\n");printf("%p\n", &arr[0]);printf("%p\n", &arr[0] + 1);printf("------------------\n");printf("%p\n", &arr);printf("%p\n", &arr + 1); }
☑ 运行的结果如下:
☑ 可以看出000000639EB2F53C比000000639EB2F54C少16个字节。
3. 原因分析:
☑ printf("%p\n", (void*)arr);输出arr 的地址,即数组第一个元素 arr[0] 的地址。
☑ printf("%p\n", (void*)(arr + 1));输出 arr + 1 的地址,即数组第二个元素 arr[1] 的地址。 ☛ 因为 arr 是一个指向 int 的指针,所以 arr + 1 的地址增加4个字节(假设 int 类型占4个字节)。
☑ printf("%p\n", (void*)&arr[0]);输出 &arr[0] 的地址,即数组第一个元素 arr[0] 的地址。★ &arr[0] 和 arr 是等价的。
☑ printf("%p\n", (void*)(&arr[0] + 1)); 输出 &arr[0] + 1 的地址,即数组第二个元素 arr[1] 的地址。因为 &arr[0] 是一个指向 int 的指针,所以 &arr[0] + 1 的地址增加了4个字节(假设 int 类型占4个字节)。
☑ printf("%p\n", (void*)&arr);输出 &arr 的地址,即整个数组 arr 的地址。&arr 是一个指向 int [5] 的指针,类型是 int (*)[5]。
☑ printf("%p\n", (void*)(&arr + 1));输出 &arr + 1 的地址。因为 &arr 是一个指向 int [5] 的指针,所以 &arr + 1 的地址增加了20个字节(5 * 4,假设 int 类型占4个字节)。即&arr + 1 指向的是数组 arr 之后的内存位置。
4. 总结:
- &arr + 1 增加的是整个数组的大小(20个字节)
- &arr[0] + 1 增加的是一个 int 的大小(4个字节)