上午搞了一個小程序,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、如果需要返回動態分配的對象或者內存,應該使用指針,引用很有可能引起內存泄露問題。
當然還有其他的一些不同,但是總體來說都是由以上衍生出來的。
其實引用本質上來說是一種指針,只不過編譯器進行了優化(所以指針更加靈活),所以引用具有指針的特點,又更安全。
版權所有,歡迎轉載,但是轉載請注明出處:瀟一