C++指針、引用知多少?

 

     上午搞了一個小程序,test半天都沒有獲得想要的結構,原來是遞歸的時候沒有注意的循環的問題,結果直接死循環了。催了...看來當程序出現問題的時候,首先要整理的是算法思路是否有問題,其次是算法的實現,是否容易進入死循環,邊界條件是否出現錯誤。算法

       好的,廢話很少說,繼續整理。小程序

       指針數組

       指針這東西,要是搞複雜了,這還真是高深莫測,你不認真研讀研讀還真不行,真心以爲搞程序一浮躁,各類bug就都出來了。安全

       指針的聲明:函數

1     int x=20; 2     int *p,q; 3     int* m,n; 4     p=&x; 5     q=x; 6     m=&x; 7     n=x; 8     cout<<*p<<" "<<q<<" "<<*m<<" "<<n;

     我想,這應該就是最簡單的聲明瞭吧,p是一個指針,而且是一個指向x的指針。那麼若是cout<<p;會獲得什麼結構呢?其實p自己保存的是一個地址。而且保存的是x所存儲的地址。優化

   不信的話能夠改爲如下語句:spa

1     int x=20; 2     int *p,q; 3     int* m,n; 4     p=&x; 5     q=x; 6     m=&x; 7     n=x; 8     cout<<p<<" "<<&x<<" "<<m;

   他的輸出結果就是:3d

  

   因此,在這裏咱們已經對指針有一個初步的認識,指針其實就是一個地址的東西,只不過這個地址保存的是咱們所指向的值得地址。指針

   空指針void*code

   咱們通常的指明瞭指向類型的指針都是隻能指向該類型的,好比說上面提到的p指針,它只能指向Int類型。可是void*是怎麼樣的呢?

   其實void*指針能夠指向任何類型,固然也能夠指向int。若是咱們下面代碼會出現什麼狀況呢?

1     void *y; 2     y=&x; 3     cout<<y;

   實際上咱們會發現,y輸出的是地址,而且和上面的P,m的地址是一致的,實驗發現,我上面的說法是對的。

   很顯然,若是僅僅獲得一個void*指針是沒有太大意義的,那麼咱們怎麼把他轉化成原有的int*,甚至轉化成int呢?

   這裏咱們須要顯示轉化,(int*)y,轉化成整數的話就是*((int*)y);

   因此如今咱們應該知道了當函數的返回值是void和void*是有多麼大的不一樣了吧。void*是返回一個特殊的指針類型。

   多重指針

   這裏說的多重指針在不少地方也稱爲指向指針的指針。

   咱們是否是常常會遇到int **m;這種狀況呢,其實他就是一個多重指針。

   仍是上面那個例子,咱們如下定義一個多重指針

1     int **z; 2     z=&p; 3     cout<<"多重指針"<<p<<*z;

   p咱們知道會輸出x的地址,那麼*z又是上面呢,z是一個指向指針p的指針。那麼z保存的是p的地址,*z理所固然的應該保存的也是x的地址。見下圖

   瞭解了這個以後,那麼咱們就很容易的知道了,動態二維數組的建立過程了,就是一個指向指針的指針,二重指針嘛,so easy。

   函數指針

   咱們常常會須要動態的調動幾個函數的某一個,若是咱們只是if else那代碼量可能有時候會比較大,有沒有能夠在函數參數中直接傳遞一個函數呢?

   答案是不可能的,可是咱們有一種方式能夠實現,那就是經過指針函數來講。

   typedef void (*pf)(int &m,int *n);

   這是什麼意思呢?他的意思就是說pf是一個指針函數,他能夠指向任意的返回值爲void,而且參數是int &m和int *n的函數。

    一樣咱們聲明pf f;就能夠把f做爲一個函數了,也能夠把f當作一個參數傳到函數體中了。具體例子見下面。

 1 void swap(int &m,int *n); //定義一個有兩個參數的函數swap
 2 typedef void (*pf)(int &m,int *n);//  3 void print(int &m,int *n,pf x);//定義一個能傳遞指針函數的函數
 4 int _tmain(int argc, _TCHAR* argv[])  5 {  6     int m=6,q=20;  7     pf f=swap;  8     int* n=&q;  9  f(m,n); 10     cout<<&m<<*n; 11  print(m,n,f); 12     system("pause"); 13     return 0; 14 }

    一樣的道理,咱們也能夠返回一個指針函數,只不過返回類型是pf。它返回的實際類型應該是 void (*)(int&,int*);解釋起來就是一個指向兩個傳輸的函數指針。

   咱們能夠定義一個 pf fun();他就返回的是函數指針了。

    引用&

    實際上引用能起到的做用,*不少時候也可以起到,那爲何咱們還常常說,要儘可能使用引用呢?最大的優勢就是指針更安全。固然某些狀況下例外。

    引用能夠認爲是一個別名,而指針則是一個實體,雖然他們都有地址的概念在裏面。

    這裏主要描述一下引用和指針的不一樣之處。

     一、指針是能夠從新指向另一個對象,而引用不行,引用一旦綁定那就不能再綁定其餘了,引用的這種性質有一點嫁雞隨雞嫁狗隨狗的意味在裏面。這對男人是否是更安全呢?O(∩_∩)O哈哈~

     二、指針能夠是空指針,可是引用不能是空引用啊,因此引用都是必須初始化的。

     三、指針是指向一個實體(程序爲指針變量分配內存區域),而指針則是一個別名,這個能夠怎麼理解呢?咱們經過sizeof(指針)和sizeof(引用)能夠知道,前者是指針的大小,通常爲4,然後者則是引用對象的大小,也就是說,若是對一個字符串長度爲100的字符串進行引用sizeof是100哦,而指針仍是4.

    四、若是須要返回動態分配的對象或者內存,應該使用指針,引用頗有可能引發內存泄露問題。

    固然還有其餘的一些不一樣,可是整體來講都是由以上衍生出來的。

    其實引用本質上來講是一種指針,只不過編譯器進行了優化(因此指針更加靈活),因此引用具備指針的特色,又更安全。

 

 

     版權全部,歡迎轉載,可是轉載請註明出處:瀟一

相關文章
相關標籤/搜索