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

Sep 8, 2017


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"};/*待查找的字符串*/
  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();
}

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

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

example1:

int a=50;

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

*p=5;//这就是解引用,*解释了 p对常量 50的内存地址的引用,解释结果就是直接去寻找p所指内容,因为p指向a,所以a的内容将被修改为5,而不是50。
  • & & 在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在内存中的地址。

指针的指针(双重指针)

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

实例程序的解析

注意:由于内存地址是动态分配的,所以每次运行得到的地址都是不同的。指针大小在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