pointer是專門用來儲存某變數的記憶體位置!
每宣告一個pointer時,就會配置一塊4 bytes的記憶體空間,
專門用來儲存某變數的記憶體位置。
下面用簡單的code來說明,
2 |
int *iPointer = &iValue; |
4 |
printf ( "iPointer的value=%d \r\n" , *iPointer); |
5 |
printf ( "iPointer儲存value的address=%X \r\n" , iPointer); |
6 |
printf ( "iPointer本身的address=%X \r\n" , &iPointer); |
7 |
printf ( "iValue 本身的address=%X \r\n" , &iValue); |
8 |
printf ( "iPointer的size=%d \r\n" , sizeof (iPointer)); |
9 |
printf ( "iValue的size=%d \r\n" , sizeof (iValue)); |
下面為執行結果以及說明,:
output |
說明 |
iPointer的value=10 |
印出儲存的記憶體位置本身的value,前面說過pointer是用來儲存記憶體位置, 如果要取得該記憶體位置的value,就是利用* |
iPointer儲存value的address=28FF3C |
印出iPointer儲存的資訊(記憶體位置) |
iPointer本身的address=28FF38 |
iPointer自己的記憶體起始位置在哪 |
iValue 本身的address=28FF3C |
第四行就是印出iValue本身的記憶體起始位置,會發現跟第二行一樣,因為iPointer就是儲存這個資訊 |
iPointer的size=4 |
印出iPointer的大小,前面說過,每個pointer的大小都為4 bytes,不論型態為和 |
iValue的size=4 |
印出iValue本身的大小,因為是interger,所以為4 bytes |
上面為基本用法。
pointer也很常用來做字串的處理。
原因是用指標處理字串較省記憶體空間,也比較彈性,
我們可以宣告一個字串指標指向一個字串常數,
下面是個簡單的範例:
1 |
char *pValue[2] = { "Ken" , "Yang" }; |
2 |
char szValue[2][10] = { "Ken" , "Yang" }; |
3 |
printf ( "szValue的value=%s \r\n" , szValue[0]); |
4 |
printf ( "pValue的value=%s \r\n" , pValue[0]); |
5 |
printf ( "szValue的size=%d \r\n" , sizeof (szValue)); |
6 |
printf ( "pValue的size=%d \r\n" , sizeof (pValue)); |
下面為執行結果以及說明,顏色相同的為該對應的結果及說明:
output |
說明 |
szValue的value=Ken |
印出儲存在陣列0的value |
pValue的value=Ken |
印出儲存在指標陣列0的value |
szValue的size=20 |
字元陣列的大小為20 |
pValue的size=8 |
指標陣列的大小為8 |
可以發現陣列以及指標陣列的第0項,都是ken阿,可是大小卻都不一樣!
陣列的大小為20,而指標陣列為8
這就是為什麼使用指標會較為省空間的原因,且也較為彈性
因為字串指標是可以更改值的,可是字元陣列是不行的。
指標還有個特性,就是可以用來做運算,
可以看下面簡單的範例,
2 |
cout << pString << endl; |
3 |
cout << *(pString+1) << endl; |
4 |
cout << sizeof (pString) << endl; |
5 |
cout << sizeof (*(pString+1)) << endl; |
6 |
cout << &pString << endl; |
上面的例子,第一行我們先宣告字串指標,然後指定一個字串常數給他,
第二行就是印出value來(會印出Ken)
第三行就是進行指標的運算(會印出e,如果我們改成+2,就變成n)
第四行是印出大小,會印出4,因為說過指標的長度都固定為4
第五行也是印出大小,差別是印出該位置的字元大小,那就一定是1了
第六行就是印出該記憶體位置了,會發現字串指標跟前面講的變數指標(int, double..之類的)存取value或者存取記憶體的方式都不太同。
最後要講的是指標函數,用個簡單的範例來說明,
01 |
void fnPointer( int *pValue){ |
03 |
cout << pValue << endl; |
07 |
cout << &iValue << endl; |
09 |
cout << iValue << endl; |
我們先宣告一個函數,那個函數裡的參數是pointer型態,
那麼使用方式就是傳遞某變數的記憶體位置進去即可,
因為我們說過指標是用來存某變數的記憶體位置!!!
所以就是傳遞記憶體位置進去。
然後我們再函數fnPointer裡面對value進行+1的動作,
然後在印出傳遞進來pointer的記憶體位置,
而主程式則是先印出iValue的記憶體位置,
在印出iValue的值。
會發現,主程式跟函數印出來的記憶體位置都相同!!
且在函數裡面進行+1以後,最後在main印出的value會變成3。
如果有些人可能會認為還是印出2,代表對pointer的概念還是不太了解,因為是pointer,還是存取到原本的變數啊!
所以也是對原本的變數做操作!!!
印出2的方式我們稱為call by value,
但印出3的方式我們稱為call by address!
還有一種是call by reference!
後面一篇會講道!
摘錄自:http://blog.kenyang.net/2011/11/c-pointer.html