再論指針

(1)平常的調用如果傳遞的是指針參數的話.比如

void a (int * a)
{
  *a = 3;   //這樣則改變了參數的值.
}

因爲a代表的是實參中的地址, 改變*a就代表改變實參地址中的值..

但是
void a(int *a)
{
  int i = 2;
  int* t = &i;
  a = t;
}

這樣是不會改變的..這樣只是改變了指針形參a的指向.注意"形參"兩個字..因爲當進行函數調用時,都要

進行一次隱含的參數拷貝.其實該參數展開後是這樣.
void a(int *a)
{
  int* temp = a;
  int i = 2;
  int *t = &i;
  temp = t; 
}

看到了吧..改變的只是temp的指向..由於temp和i, *t都是臨時變量存儲於棧上,在函數結束時,系統自動

回收.所以*a的值是不會改變的. 第一種形式中.展開後依然是.


void a (int * a)
{
  int* t = a;
  *temp = 3;  
}
即使是臨時變量..但*temp和*a指向的卻是同一個地址,因此該變量值是確定的..就是實參的值..所以能改

變其值.

PS:
指針其實是個神祕的東西,它不像一般變量,簡單賦值..指針指向的是變量的內存地址,想想,如果一個指針

指向一塊變量的首地址,但是這塊首地址由於某種原因,被釋放掉了,那該指針就變得沒用了,也就是所謂的

野指針了..所以指針是靈活使用的.對其賦值後,要同時關注被賦值的那個變量的值..所以C++推出了const

指針.

const <typename T> *p //該指針是一個常量指針,即一旦指針被賦值後,被賦值的那個必須是常量,而且不能

改變,但是指針卻能指向其他變量.

<typename T>* const p//該指針是一個指針常量,即指針只能被賦一次值,但賦值後被指向的變量的值可以改

變.

 

更復雜一些的例如:
struct m
{
  int d;
  int c;
};
void a( m* a)
{
   a->d = 2;
   a->c = 4;
}
展開後其實就是
void a(m* a)
{
  m *temp = a;
  temp->d = 2;
  temp->c = 4;   //始終未改變指針的指向..所以*temp和*a其實指向同一塊內存區域.因此能操縱同一

變量來達到改變其值的目的.
}


當指針作爲數組首地址傳遞時(平時也可以這麼用),指針可以作爲數組名來使用
void a(int* p)
{
  for( int i = 0; i< 5; i++)
  cout << a[i] << endl;
}

void a(int* p)
{
  int* temp = p;
  for( int i = 0; i< 5; i++)
  cout << temp[i] << endl;  //同理,未改變指向.
}


(2)

現在再回首看第二種形式,我們再引出來一個新概念,即指向指針的指針.int**p.
void a(int *a)
{
  int i = 2;
  int* t = &i;
  a = t;
}
如果真想改變指針a的值,要怎麼做呢.很簡單..因爲現在是值傳遞,不要以爲指針傳遞都是傳地址,雖然,指

針的值是地址,但是自己也提到了,是指針的"值"啊!!! 所以就是值傳遞了..呃..
上面的函數展開後其實是這樣:
void a(int *a)
{
   int *temp = a;
   int i = 2;
   int *t = &i;
   temp = t;   //臨時變量temp銷燬..參數值不變..
}

如果現在改成這樣定義.
void a(int** a)
{
  int i = 2;
  int *t = &i;
  *a = t;
}

然後在調用時
int main()
{
  int i = 3;
  int* p1 = &i;
  int** pp = &p1;
  a(pp);

  cout << *p<< endl;

  return 0;
}

沒錯, 這樣就會改變p1的值了..將上面的函數展開.

void a(int** a)
{
  int **temp = a;  //同時指向同一塊內存地址..即指針p1的地址.
  int i = 2;
  int *t = &i;
  *temp = t;    //現在*temp表示p1所指向的變量的地址...
} //這樣一般是不對的,因爲在函數結束時,臨時變量i銷燬,所以該塊內存已經沒有...最好就是在參數中傳遞數組的首地址,然後將數組中的地址做爲返回值返回..

但是,上面的函數僅僅是改變了指針p1的指向,但卻不能改變變量i的值..因爲在函數調用時:
a 中裝的指針p1的地址
*a中裝的是i的起始地址
**a中裝的纔是變量i的值..

對*a的修改就是對指針p1的內容的修改...
如果想改變變量i的值,修改**a就行了..

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章