地址&a和首地址&a[0]的区别
1 2 3 4 5 6 7 8 9 10 11 | main(){ long a[4] = {1, 2, 3, 4}; long *p1=( long *)(&a+1); // long *p1=(&a+1);//整个数组地址的下一个long数组的首地址,即存储整个数组a的最后一个字节的下一个字节内存的地址 // long *p1=(&a[0]+1);//数组第1个元素地址的下一个long的元素首地址,即数组第2个元素的首地址 // long *p1=(long*)(&a[0]+1);//同上 long *p2=( long *)(( long )a+1); printf ( "%lx\n" , p1[-1]); printf ( "%lx\n" , *p2); } |
(&a+1)和(&a[0]+1)中的1不同,前者的是整个数组的长度,后者是数组元素数据类型的长度
首先
1 | long *p1=( long *)(&a+1); |
&a是整个数组的地址,因此&a+1实际上是向后偏移了16个字节,因此 p1 指向了数组边界。然后输出 p1[-1] 等价于 *(p1-1),因为 p1 是 long 型指针,因此 p1-1 就向前偏移 sizeof(long) 个字节,也就是指向了 a[3]。
其次
1 | long *p2=( long *)(( long )a+1); |
(long)a+1 是一个纯整数运算(因为a被强转为long了),因此 p2 就指向了long型数据 a[0] 的第二个字节,最后打印 *p2 时,由于 p2 是一个 long 型指针,系统会从 a[0] 的第二个字节开始,取出 sizeof(long) 个字节出来作为 long 型数据来解释,因此最后输出的结果是 a[0] 的高位三字节和 a[1] 低位一字节的数据。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库