(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 : 只代表数组第一个元素的地址, 所以左右类型不一致 .
原文:https://blog.youkuaiyun.com/i_pangpang/article/details/80261597