直接看例子:

int main( )
{
    
    char *p ;

    printf("打印下标第0和第6个元素所在地址:&a=%x,&a+1=%x\n\n",&a,&a+1);//答应下标第0和第6个元素所在地址:

    printf("注意有(char *)和没有的区别:(char *)(&a+1)-1=%x,(&a+1)-1=%x\n\n",(char *)(&a+1)-1,(&a+1)-1);

    p="zhangning";

//*(p+1)='e';//注意与下面同样一句话的差别,这就是指针和数组的差别,数组对象存放在变量区,指针指向的内容存放在常量区,变量可变,常量则不可。

    printf("打印指针变量p的地址:&p=%x\n",&p);
    printf("打印字符串所在内存首地址:p=%x\n",p);
    printf("打印字符串:p=%s\n\n",p);

    p = a;

*(p+1) = 'e';

    printf("打印数组首地址的方法:a=%x,&a=%x,p=%x,*(&p)=%x\n\n",a,&a,p,*(&p));//打印数组首地址的方法


    printf("打印字符串数组的方法:a=%s,p=%s\n\n",a,p);//打印字符串数组的方法

    //打印下标为1的元素
    printf("打印下标为1的元素:a[1]=%c,*(a+1)=%c,p[1]=%c,*(p+1)=%c,*((&a+1)-4)=%c\n\n",a[1],*(a+1),p[1],*(p+1),\
    *((char *)(&a+1)-5));

    //打印下标为1的元素所在地址
    printf("打印下标为1的元素所在地址:&a[1]=%x,a+1=%x,p[1]=%x,p+1=%x,(&a+1)-4=%x\n\n",&a[1],a+1,p[1],p+1,(char *)(&a+1)-5);
    
    return 0;
}
输出结果:

打印下标第0和第6个元素所在地址:&a=928000,&a+1=928006

注意有(char *)和没有的区别:(char *)(&a+1)-1=928005,(&a+1)-1=928000

打印指针变量p的地址:&p=75f914
打印字符串所在内存首地址:p=9258a4
打印字符串:p=zhangning

打印数组首地址的方法:a=928000,&a=928000,p=928000,*(&p)=928000

打印字符串数组的方法:a=hello,p=hello

打印下标为1的元素:a[1]=e,*(a+1)=e,p[1]=e,*(p+1)=e,*((&a+1)-4)=e

打印下标为1的元素所在地址:&a[1]=928001,a+1=928001,p[1]=65,p+1=928001,(&a+1)-4=928001

如果你把上面每句printf都搞懂,f指针和数组的差别,及指针访问数组的方法肯定全懂了。下面的总结不重要,上面的代码打印方式才是我精心想出来的,但还是总结下吧!

总结:1,对于数组,a指首元素地址,&a指整个数组(对象)的首地址,故a和&a值相等。

   2,a+1跨了一个sizeof(a[0])是第二个元素地址,但&a+1是跨了一个sizeof(a)的地址。

   3,注意(char *)(&a+1)-1和(&a+1)-1的区别。

      4,a[1] = *(a+1),同样p[1] = *(p+1)。

   5,表示字符串时&a和a指向该字符串的首地址,p指向字符串首地址,&p没有意义

 

版权声明:本文为aiden-zhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/aiden-zhang/p/11405709.html