地址&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] 低位一字节的数据。

posted @   败人两字非傲即惰  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示