zoukankan      html  css  js  c++  java
  • C语言指针—————第二篇:指向另一指针的指针

    本文转自 : http://c.biancheng.net/cpp/html/495.html  原文存在部分问题,现在已经修改,并重新发出来

     

    一、回顾指针概念

    早在本书第贰篇中我就对指针的实质进行了阐述。今天我们又要学习一个叫做“指向另一指针地址”的指针。让我们先回顾一下指针的概念吧!
    当我们程序如下声明变量:
       short int i;
       char a;
       short int * pi;
    程序会在内存某地址空间上为各变量开辟空间,如下图所示:

    图中所示中可看出:
       i 变量在内存地址5的位置,占2个字节。
       a变量在内存地址7的位置,占1个字节。
       pi变量在内存地址9的位置,占2个字节。(注:pi 是指针,我这里指针的宽度只有2个字节,32位系统是4个字节)
    接下来如下赋值:
       i = 50;
       pi = &i;
    经过上在两句的赋值,变量的内存映象如下:

    看到没有:短整型指针变量pi的值为5,它就是i变量的内存起始地址。所以,这时当我们对*pi进行读写操作时,其实就是对i变量的读写操作。如:
       *pi=5; /* 就是等价于i = 5; */
    你可以回看本书的第贰篇,那里有更加详细的解说。

    二、指针的地址与指向另一指针地址的指针

    在上一节中,我们看到,指针变量本身与其它变量一样也是在某个内存地址中的,如pi的内存起始地址是9。同样的,我们也可能让某个指针指向这个地址。看下面代码:
       short int **ppi; /* 这是一个指向指针的指针,注意有两个“*”号 */
       ppi = π
    第一句:short int **ppi; —— 声明了一个指针变量ppi,这个ppi是用来存储(或称指向)一个short int * 类型指针变量的地址。
    第二句:&pi那就是取pi的地址,ppi = &pi就是把pi的地址赋给了ppi。即将地址值9赋值给ppi。如下图:

    从图中看出,指针变量ppi的内容就是指针变量pi的起始地址。于是……
       ppi的值是多少呢?—— 9。
       *ppi的值是多少呢?—— 5,即pi的值。
       **ppi的值是多少呢?——50,即i的值,也是*pi的值。
    呵呵!不用我说太多了,我相信你应明白这种指针了吧!

    三、一个应用实例

    (1)设计一个函数:void find1(char array[], char search, char *pa)
    要求:这个函数参数中的数组array是以0值为结束的字符串,要求在字符串array中查找字符是参数search里的字符。如果找到,函数通过第三个参数(pa)返回值为array字符串中第一个找到的字符的地址。如果没找到,则为pa为0。

    设计:依题意,实现代码如下。

    void find1(char array[], char search, char *pa)
    {
       int i;
       for (i = 0; *(array + i) != 0; i++)
       {
          if ( *(array+i) == search)
          {
             pa = array + i;
             break;
          }
          else if (*(array+i) == 0)
          {
             pa = 0;
             break;
          }
       }
    }

    你觉得这个函数能实现所要求的功能吗?

    调试:我下面调用这个函数试试。

    int main()
    {
       char str[] = {"afsdfsdfdf"}; /* 待查找的字符串 */
       char a = ’d’; /* 设置要查找的字符 */
       char *p = 0; /* 如果查找到后指针p将指向字符串中查找到的第1个字符的地址。 */
       find1(str, a, p); /* 调用函数以实现所要操作。 */
       if (0 == p)
       {
          printf("没找到!
    "); /* 如果没找到则输出此句 */
       }
       else
       {
          printf("找到了,p = %d", p); /* 如果找到则输出此句 */
       }
       return(0);
    }


    分析:上面代码,你认为会是输出什么呢?运行试试。
    唉!怎么输出的是:没有找到!而不是“找到了,……”。

    明明a值为’d’,而str字符串的第四个字符是’d’,应该找得到呀!
    再看函数定义处:void find1(char array[], char search, char *pa)
    看调用处:find1(str, a, p);

    依我在第伍篇的分析方法,函数调用时会对每一个参数进行一个隐含的赋值操作。整个调用如下:
    array = str;
    search = a;
    pa = p; /* 请注意:以上三句是调用时隐含的动作。*/
    int i;
    for(i =0; *(array+i) != 0; i++)
    {
       if (*(array+i) == search)
       {
          pa = array + i;
          break;
       }
       else if (*(array+i)==0)
       {
          pa=0;
          break;
       }
    }
    哦!参数pa与参数search的传递并没有什么不同,都是值传递嘛(小语:地址传递其实就是地址值传递嘛)!所以对形参变量pa值(当然值是一个地址值)的修改并不会改变实参变量p值,因此p的值并没有改变(即p的指向并没有被改变)。(如果还有疑问,再看一看《C语言指针—————第一篇:函数参数的传递》了。)

    修正:

    void find2(char array[], char search, char **ppa)
    {
       int i;
       for (i=0; *(array + i) != 0; i++)
       {
          if(*(array + i) == search)
          {
             *ppa = array + i;
             break;
          }
          else if(*(array + i) == 0)
          {
             *ppa = 0;
             break;
          }
       }
    }


    主函数的调用处改如下:
       find2(str, a, &p); /*调用函数以实现所要操作。*/
    再分析:这样调用函数时的整个操作变成如下:
    array = str;
    search = a;
    ppa = &p; /* 请注意:以上三句是调用时隐含的动作。 */
    int i;
    for (i = 0; *(array + i) != 0; i++)
    {
       if (*(array + i) == search)
       {
          *ppa = array + i
          break;
       }
       else if (*(array+i)==0)
       {
          *ppa=0;
          break;
       }
    }
    看明白了吗?ppa指向指针p的地址。对*ppa的修改就是对p值的修改。你自行去调试。

    经过修改后的程序就可以完成所要的功能了。看懂了这个例子,也就达到了本篇所要求的目的。

  • 相关阅读:
    1093 Count PAT's(25 分)
    1089 Insert or Merge(25 分)
    1088 Rational Arithmetic(20 分)
    1081 Rational Sum(20 分)
    1069 The Black Hole of Numbers(20 分)
    1059 Prime Factors(25 分)
    1050 String Subtraction (20)
    根据生日计算员工年龄
    动态获取当前日期和时间
    对计数结果进行4舍5入
  • 原文地址:https://www.cnblogs.com/mrsandstorm/p/5775785.html
Copyright © 2011-2022 走看看