關於C/C++中指針做形參的一點小分析

今天寢室的山東兄弟在練二級的上機,其中一個題目大概是這樣:在一個函數中,有一個指針形參,記爲*p,然後在函數內部定義了臨時變量a,a和*p是同種類型。經過一系列計算 ,a得到了一個值,這個值最後是需要記錄在指針*p裏面的,應該怎麼保存呢?我當時隨便就說,p=&a。結果發生錯誤了,沒有得到預期結果。正確答案是*p=a。

下面來分析下原因。

 學過C的人都知道到,函數的實參與形參的之間是值傳遞,單向傳遞。在譚浩強那本C語言教材中就有這樣一個經典的例子:

 

int a=3,b=4;

void exchange(int x,int y)

{  

          
int temp;

          temp
=a;a=b;b=temp;   //試圖交換a,b

}


exchange(a,b);

cout
<<a<<" "<<b<<endl;

 

輸出的來的仍然是3,4.

要交換a,b,只需改變函數exchange,傳遞a,b的地址,如下:

 

void exchange(int *x,int *y)

{

         
int temp;
         temp
=*x;*x=*y;*y=temp;
}
   exchange(&a,&b);
   cout<<a<<" "<<b<<endl;
  

這樣,a,b就成功交換了。爲什麼呢?下面再說。

 

再回到開始提出的那個問題,爲什麼p=&a錯誤而*p=a正確呢?

再看兩段代碼:

 

#include<iostream>
using namespace std;
void test_point(int *p)
{
     
int a=3;
     p
=&a;   // 不同之處
}

int main()
{
     
int x=4;
     
int *p1=&x;
     test_point(p1);
     cout
<<*p1<<endl;
         return 0;
}

   
   

此時輸出的結果是4,也就是說,指針p1調用test_point函數後值並沒有得到改變,接着看下一段代碼

 

#include<iostream>
using namespace std;
void test_point(int *p)
...{
     
int a=3;
     
*p=a;   //不同之處
}

int main()
{
     
int x=4;
     
int *p1=&x;
     test_point(p1);
     cout
<<*p1<<endl;
     
return 0;
}

此時輸出結果是3,證明指針p1在調用test_point函數後得到改變。

不難發現,兩段代碼不同之處在於函數中對p的處理,一個是p=&a,一個是*p=a,有什麼區別呢?

翻開C++ primer(第四版)105頁可以發現其中的解釋:

對p=&a,稱之爲給指針賦值,意思是給指針本身一個指向的對象。

而對*p=a稱之爲通過指針進行賦值,意思是改變指針所指對象的值。

有了上面的基礎就很好解釋了,p=&a是相當於把函數的形參指針p指向a(即給指針賦值,此值是a的地址),但由於a是臨時變量,函數調用完後即不存在了,所以實參p1是不會被改變的,*p1=4。

而*p=a就不同了,我們知道,函數是值傳遞,實參p1傳遞給形參p的值是什麼呢?當然是x的地址,也就是說,在函數test_point調用的過程中,形參指針p指向了x,然後進行的*p=a是通過指針進行賦值,改變了p指向的對象x,p1仍然指向x,故*p1=3.

這樣,那個exhange函數也很好解釋了,也就是一個通過指針進行賦值的問題。

    

       

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