1. 程式人生 > >C++中傳值引數和引用引數和指標怎樣區別?

C++中傳值引數和引用引數和指標怎樣區別?

C++中傳值引數和引用引數怎樣區別呢?

看以下例子:
#include<iostream>
using namespace std;
void swap(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
}
main()
{
int a=3,b=5;
cout<< "before ‘swap’:a="<<a<<",b="<<b<<endl;
swap(a,b);
cout<<"after  ‘swap’:a="<<a<<",b="<<b<<endl;
}
這個例子是傳值呼叫, 意思就是 形參 的 改變不會影響 實參的值。
你執行一下可知 主函式呼叫了swap函式後 a,b的值並沒有發生交換。
原因是,呼叫swap函式時 編譯器為 swap(int a,int b) 中的形參 a , b單獨分配記憶體空間,並接受主函式傳遞來的值,這塊記憶體空間和 main()函式中的 a ,b 不是同一記憶體空間。 所以在swap(int a,int b) 中 a , b發生了交換,但main函式中a , b沒發生交換。即主調函式與被調函式的操作物件各不相同,引數僅在呼叫時由實參向形參傳遞,而不可由形參向實參傳遞。

要使a ,b發生交換 需要使用傳址呼叫。程式改為如下:
#include<iostream>
using namespace std;
void swap(int &

 a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
cout<<"in ‘swap’:a="<<a<<",b="<<b<<endl;
}
  main()
{
int a=3,b=5;
cout<< "before ‘swap’:a="<<a<<",b="<<b<<endl;

swap(a,b);
cout<<"after  ‘swap’:a="<<a<<",b="<<b<<endl;
}

引用可以看作是一個變數的別名,使用 引用 時 ,對於void swap(int a,int b)   編譯器並沒有給形參a,b分配新的記憶體空間,只是使形參a,b指向了main函式中實參a,b的記憶體空間,他們共享同一內空間,即把地址給了形參。所以在void swap(int a,int b)函式中對這塊記憶體的改變也就改變了實參的值。
除了使用引用,也可以使用指標。

指標方式和引用方式都屬於傳址呼叫。
那麼指標和引用又有什麼樣的區別呢?

兩種引數都允許函式修改實參所對應的物件,兩種型別的引數都允許有效得向函式傳遞大型類物件。

兩者在引數傳遞過程中,有如下幾點不同

   (1)引用必須被初始化為指向一個物件,一旦初始化了,它就不能在指向其它物件。指標可以指向一系列不同的物件,當然也可以定義為NULL;

   如:

 calss Type{

   void operation(const Type&p1,const Type&p2);

   int main(){

    Tyoe obj1;

    Type obj2 = operation(obj1,0);    //引用引數的實參不能為0

   }

   所以在函式中,一個引數可能指向不同的物件的情況,或者這個引數可能不指向任何物件,則必須實用指標引數。

   (2)引用引數的一個重要用法,它允許我們在有效實現過載操作符的還能保證用法的直觀性。如下例:

  Matrix operator+(Matrix m1,Matrix m2)

   {

    Matrix result;

    //do computation

    return result;

   }

   通過上面實現後,就能夠支援兩個Matrix物件的加法,如:a+b

   但是這樣做,效率會非常低。因為該實現的實參是按值傳遞,兩個Matrix物件相加的時候,內容被拷貝到operator+()函式的引數區中,因為Matrix物件非常大的時候,分配這樣一個物件,並把它拷貝到函式引數區中的時間和空間開銷比較高。

   而為了提高我們的操作符函式的效率,假定我們決定把引數申明為指標的時候,如下:

 Matrix operator+(Matrix *m1,Matrix *m2)

   {

    Matrix result;

    //do computation

    return result;

   }

   這種做法,在一定程度上很好得解決了函式實現的效率問題,但是帶來一個新的問題是使用者的使用習慣,對於這樣的operator+操作,呼叫方式變為:&a+&b,這樣大大顛覆了我們傳統的呼叫方式。

   所以這時候,如果申明為引用的方式,就能到達到效率和使用習慣的目的:

 Matrix operator+(Matrix &m1,Matrix &m2)

   {

    Matrix result;

    //do computation

    return result;

   }