【原创】C++中的指针,以及指针的指针 扫盲(献给那些被指针弄头大的同学)

 

#include <stdio.h>

void find(char arr[], char search, char** pa)

{

   int i;

   for (i=0;*(arr+i)!=0;i++)

   {

      if (*(arr+i)==search)

      {

        *pa=(arr+i);

        break;

      }

      else if (*(arr+i)==0)

      {

        *pa=0;

        break;

      }

   }

}

 void main()

{

  char str[]={"afsdfsdfdf/0"};  /*待查找的字符串*/

  char a='d';   /*设置要查找的字符*/

  char *p;  //存放所找到的字符 在字符串中所在的地址  

char **pp1=0;

pp1=&p;//将指针p在内存中所在的地址赋给pp1。

  find(str,a,pp1);  /*调用函数以实现所要操作。*/

  if (0==p )

  {

     printf ("没找到!/n");/*1.如果没找到则输出此句*/

  }

  else

  {

     printf("在字符串中第四个字符也就是d在内存中的地址  0x%x /n",str+3);

     printf("找到了,p=0x%x",p);  /*如果找到则输出此句*/

  }

  getchar();

}

 

 

大家可以先复制此代码,运行后,再看解释。

 

1. *,& 在指针操作中的意义

   (1)*

    大家都知道 在写int *p 时,*可以声明一个指针。很少人知道*在C/C++中还有一个名字就是“解引用”。他的意思就是解释引用,说的通俗一点就是,直接去寻找指针所指的地址里面的内容,此内容可以是任何数据类型,当然也可以是指针(这就是双重指针,后面将会讨论)。需要注意的是,在变量声明的时候,*不能当做解引用使用,只是表示你声明的变量是一个指针类型。

   example1:

   int a=50;

   int *p=&a;// '&'的作用就是把a变量在内存中的地址给提取出来,具体后面解释。

   *p=5;//这就是解引用,*解释了 p对常量 50的内存地址的引用,解释结果就是直接去寻找p所指内容,因为p指向a,所以a的内容将被修改为5,而不是50。

   (2) &

     & 在C/C++中具体 3种语义, 按位与,取地址 和 声明一个引用。

     int a=0x0000002 & 0x00000003;//按位与

     int *p=&a;//取地址,取出a在内存中的地址给p,这样就建立一个指针映射,使得p指a

     int &a=b;//声明a是b的引用,对a操作修改也就是直接对b修改。

     在指针操作中,&还有一种叫法叫做“脱去解引用”,在这个表达式中&*p(假设p是指针),&脱去了*对a的解引用,从而得到抵消的效果,得到应该是p所指的变量的地址。

     example2:

      接example1。

      println(“%x ||||| %x”,&p,&*p);

     输出结果:

     p在内存中的地址|||||a在内存中的地址

     为什么呢?

     首先&去指针p的地址,然后&脱去了p对a中5的引用,解引用和脱去解引用效果抵消,从而得到了p所指的变量的地址,也就是a在内存中的地址。

2. 指针的指针(双重指针)

    通俗的说,也就是在双重指针中存放的是另一个指针在内存中的地址,从而构成了一个数据链。pp->p->a->5,这就是这个数据链的简化模型。相信大家搞懂了普通指针,双重指针应该是piece of cake。

 

 

3  实例程序的解析

注意:由于内存地址是动态分配的,所以每次运行得到的地址都是不同的。指针大小在32位机器中是32位的数据,也就是8个0在16进制表示法中0x00000000。

这是在进入find()方法之前的,数据检视表。 


可以发现 &p value 是指针p在内存中的地址。他的子节点(也就是下面那个蓝色没有名称的立体的长方形)也就是p所指的内容的地址,由于我给它赋了0,所以他的value是0x00000000。由于p所指的地址是0,0不对应内存中的数据,所以是一个红色的感叹号。

&pp1是一个双重指针,&pp1是它自己在内存中的地址。下一个子数也就是pp1,它的value是指针p在内存中的地址,下面级联菜单的结构就跟p的结构一致了,因为pp1是一个指向p的双重指针。

这里需要提一下的就是,数组。 数组和指针其实十分类似,都是一种地址的体现。数组是一串连续的内存地址,通过index来访问内部数据。str 就是这个数组的首地址,也就是第一个元素所在的内存地址,只要知道数组长度,就通过index的加减来访问你想要的数据。

所以str+3就是第4个字符 的地址,也就是str[]数组中的第一个字符'd'所在的内存地址, str[3]就是取这个地址中数据的操作。

 

这是在退出方法find()方法之后,数据检视表。




不难发现,在成功发现字符'd'后,*pp1也就是p的内容发生了变化,value变成了第一个字符'd'在str中的地址了,0x002dfe1f。**pp1的内容也就是*p内容都是'd',100是ASCII码。所以成功完成了find()方法的要求,即在目标字符数组中,寻找指定的字符,并返回其在数组中的具体位置也就是字符‘d’的index的内存地址。

这是程序运行的最终结果

 




Conclusion:

结论我用一副图来表示

 




References:

C/C++中文教程,http://download.csdn.net/source/424357#acomment,CSDN.net

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值