(1) 测试代码 :
#include<stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
printf("a = %p\n",a); // 数组名代表首地址 . 000000000064FE30
printf("&a = %p\n",&a); // "&a"代表数组的地址 . 000000000064FE30
printf("a+1 = %p\n",a+1); // 数组名代表首地址 . 000000000064FE34
printf("&a+1 = %p\n",&a+1); // "&a"代表数组的地址 . 000000000064FE44
return 0;
}
分析 :
* a是数组名, 代表数组的首地址, a+1就是数组的下一个元素的地址(也就是第二个元素的地址) .
* "000000000064FE34" - "000000000064FE30" = 4(转换为十进制也是4)
(因为int型的数组一个变量占4个字节) .
* "000000000064FE30" - "000000000064FE44" = 14
(转换为十进制是20), (因为int型数组中有 5 个元素, 一个元素占 4 个字节) .
* 说明:
(1) 数组名 + 1 = 第二个元素 .
(2) &数组名 + 1 = 整个数组的下一个地址 .
* "&数组名" + 1 : 一次移动一个数组 .
* "数组名" + 1 : 一次移动一个元素 .
(2) 面试题 :
#include<stdio.h>
int main()
{
int b[5] = {1,2,3,4,5};
int *ptr1 = (int*)(&b + 1);
int *ptr2 = (int*)(b + 1);
printf("%x\n",ptr1[-1]); // 输出 5
printf("%x\n",*ptr2); // 输出 2
return 0;
}
分析 :
* 可以把ptr1[-1] 看成 : *(ptr1 - 1), 因为这时候 ptr1 指向的是整个数组的下一个地 址, 所以减一代表数组中最后一个元素的地址 .* ptr2最终指向的是数组的第二个元素的地址 .
(3)误区分析:
#include<stdio.h>int main(){ int ch[5] = {1,2,3,4,5}; int (*ptr1)[5] = &ch; // 第二行 . int (*ptr2)[5] = ch; // 第三行(报错行) . return 0; }
分析 :
* 整个程序会在第三行出报错, 因为前后的类型并不匹配 .
* &ch: 代表整个数组的地址, 所以左右类型一致.
* ch : 只代表数组第一个元素的地址, 所以左右类型不一致 .