地址&a和首地址&a[0]的区别

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不同,前者的是整个数组的长度,后者是数组元素数据类型的长度

 

首先

long  *p1=(long *)(&a+1);

&a是整个数组的地址,因此&a+1实际上是向后偏移了16个字节,因此 p1 指向了数组边界。然后输出 p1[-1] 等价于 *(p1-1),因为 p1 是 long 型指针,因此 p1-1 就向前偏移 sizeof(long) 个字节,也就是指向了 a[3]。

其次

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 @ 2023-04-25 09:15  败人两字非傲即惰  阅读(62)  评论(0编辑  收藏  举报