程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++指針、引用知多少?

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

編輯: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所存儲的地址。      不信的話可以改成以下語句:   復制代碼 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; 復制代碼    他的輸出結果就是:           所以,在這裡我們已經對指針有一個初步的認識,指針其實就是一個地址的東西,只不過這個地址保存的是我們所指向的值得地址。      空指針void*      我們一般的指明了指向類型的指針都是只能指向該類型的,比如說上面提到的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();他就返回的是函數指針了。       引用&       實際上引用能起到的作用,*很多時候也能夠起到,那為什麼我們還經常說,要盡量使用引用呢?最大的優點就是指針更安全。當然某些情況下例外。       引用可以認為是一個別名,而指針則是一個實體,雖然他們都有地址的概念在裡面。       這裡主要描述一下引用和指針的不同之處。        1、指針是可以重新指向另外一個對象,而引用不行,引用一旦綁定那就不能再綁定其他了,引用的這種性質有一點嫁雞隨雞嫁狗隨狗的意味在裡面。這對男人是不是更安全呢?O(∩_∩)O哈哈~        2、指針可以是空指針,但是引用不能是空引用啊,所以引用都是必須初始化的。        3、指針是指向一個實體(程序為指針變量分配內存區域),而指針則是一個別名,這個可以怎麼理解呢?我們通過sizeof(指針)和sizeof(引用)可以知道,前者是指針的大小,一般為4,而後者則是引用對象的大小,也就是說,如果對一個字符串長度為100的字符串進行引用sizeof是100哦,而指針還是4.       4、如果需要返回動態分配的對象或者內存,應該使用指針,引用很有可能引起內存洩露問題。       當然還有其他的一些不同,但是總體來說都是由以上衍生出來的。       其實引用本質上來說是一種指針,只不過編譯器進行了優化(所以指針更加靈活),所以引用具有指針的特點,又更安全。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved