完全搞定C指針-指向另外一指針的指針

一. 回顧指針概念:
當咱們程序以下申明變量:
short int i;
char a;
short int * pi;
程序會在內存某地址空間上爲各變量開闢空間,以下圖所示。
內存地址→6     7      8     9     10     11    12    13     14    15
-------------------------------------------------------------------------------------
…  |     |      |      |      |      |       |      |      |      |   
-------------------------------------------------------------------------------------
    |short int i |char a|      |short int * pi|
圖中所示中可看出:
i 變量在內存地址5的位置,佔兩個字節。
a變量在內存地址7的位置,佔一個字節。
pi變量在內存地址9的位置,佔兩個字節。(注:pi 是指針,我這裏指針的寬度只有兩個字節,32位系統是四個字節)
接下來以下賦值:
i=50;
pi=&i;
通過上在兩句的賦值,變量的內存映象以下:
內存地址→6     7      8     9     10     11    12    13      14     15
--------------------------------------------------------------------------------------
…  |    50      |      |      |    6         |      |      |       |   
--------------------------------------------------------------------------------------
    |short int i |char a|      |short int * pi|
看到沒有:短整型指針變量pi的值爲6,它就是I變量的內存起始地址。因此,這時當咱們對*pi進行讀寫操做時,其實就是對i變量的讀寫操做。如:
*pi=5;   //就是等價於I=5;
你能夠回看本系列的第二篇,那裏有更加詳細的解說。

二. 指針的地址與指向另外一指針地址的指針
在上一節中,咱們看到,指針變量自己與其它變量同樣也是在某個內存地址中的,如pi的內存起始地址是10。一樣的,咱們也可能讓某個指針指向這個地址。
看下面代碼:
short int * * ppi;    //這是一個指向指針的指針,注意有兩個*號
ppi=π

第一句:short int * * ppi;——申明瞭一個指針變量ppi,這個ppi是用來存儲(或稱指向)一個short int * 類型指針變量的地址。
第二句:&pi那就是取pi的地址,ppi=π就是把pi的地址賦給了ppi。即將地址值10賦值給ppi。以下圖:
內存地址→6     7      8     9     10     11    12    13       14    15
------------------------------------------------------------------------------------
…  |    50     |      |      |      6       |       10      |      |   
------------------------------------------------------------------------------------
    |short int i|char a|      |short int * pi|short int ** ppi|
從圖中看出,指針變量ppi的內容就是指針變量pi的起始地址。因而……
ppi的值是多少呢?——10。
*ppi的值是多少呢?——6,即pi的值。
**ppi的值是多少呢?——50,即I的值,也是*pi的值。
呵呵!不用我說太多了,我相信你應明白這種指針了吧!

三. 一個應用實例
1. 設計一個函數:void find1(char array[], char search, char * pi)
要求:這個函數參數中的數組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;
      }
   }
}
你以爲這個函數能實現所要求的功能嗎?
調試:
我下面調用這個函數試試。
void main()
{
  char str[]={「afsdfsdfdf/0」};  //待查找的字符串
  char a=’d’;   //設置要查找的字符
  char * p=0;  //若是查找到後指針p將指向字符串中查找到的第一個字符的地址。
  find1(str,a,p);  //調用函數以實現所要操做。
  if (0==p )
  {
     printf (「沒找到!/n」);//1.若是沒找到則輸出此句
  }
  else
  {
     printf(「找到了,p=%d」,p);  //若是找到則輸出此句
  }
}
分析:
上面代碼,你認爲會是輸出什麼呢?
運行試試。
唉!怎麼輸出的是:沒有找到!
而不是:找到了,……。
明明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的指向並無被改變)。
(若是還有疑問,再看一看《第五篇:函數參數的傳遞》了。)
修正:
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值的修改。
你自行去調試。
通過修改後的程序就能夠完成所要的功能了。數組

相關文章
相關標籤/搜索