C语言的指针真的很灵活,这是我之前做过的一道关于C语言指针与强制类型转换的一道题,我以我的理解分享给大家看看,图画的有点丑不要介意
#include <stdio.h>
int main(void)
{
long a[4]={1,2,3,4};
long *p1=(long*)(&a+1);
long *p2=(long*)((long)a+1);
printf("%lx\n",p1[-1]);
printf("%lx\n",*p2);
return 0;
}
运行结果:
分析: long *p1=(long *)(&a+1);
(&a+1): 数组a的地址加一
&a+1的地址指向了蓝色区域
因为P1是long*类型指针,因此p1所代表的地址为红色区域
所以,p1[-1] 就是p1指针向后移动一位在解引用,p1[-1]为4
long p2=(long)((long)a+1)
逐次分解,首先看 a+1
a表示数组首元素地址,因此a+1表示第二个元素的地址。
假设a的地址为0x123456,那么a+1表示为0x123456+8
但是,这里它把a的地址强制类型转换成了long型,所以(long)a+1 的值因该为0x123456+1
然后在强制类型转换为long*型相当于地址向上偏移了一个字节。由于long在64位编译器中占8个字节,所以P2所指向的位置为下图红色区域。
而1在64位机存储形式位0x0000000000000001(用16进制表示)
其在内存的存放形式如下图所以
所以红色区域解引用为200000000000000