不過因為指標的東西不少,這篇就只先揀比較簡易的觀念介紹囉~
1. What is a pointer?
指標呢,也是一種變數
什麼是變數呢,就是像 int, double, char 之類的東西,可以用來放東西用的
那指標放啥呢? 指標放的是記憶體位置
記憶體位置是啥呢? 就是變數住的地方(就像門牌號碼一樣啦)
變數是什麼呢? 剛剛有講過喔XD
所以我們只要把指標也當成一種數字來看就好了(如果把它想成位置會讓你腦鈍鈍、眼花花的話@@)
那因為它也是一種變數,所以我們也可以對它用指定(=),加減法(+-)
用一個擬人化的比喻的話,指標就是一個弓箭手,它記著它要把箭射往何處
(等下我們還會繼續用這個比喻來進行)
在這裡,我們先把一般的變數比喻成箭靶
弓箭手(指標)只會記它要把箭射到哪邊去,而不知道那裡有什麼東西(切記,切記)
這個是指標很重要的觀念喔,大家一定要記得喔
2. Mark
指標最顯而易見的,就是有一枚 * 在變數名前
指標的表示法嘛...可以用 int* 來表示(這篇裡面的型態都先使用整數型)
一般變數就用 int 表示
注意到有一個星號了嗎? 這個就是指標的標記
3. Relationship with variables
指標和變數的關係可說是密不可分
(因為箭靶就是要拿來被射的嘛)
兩者間的轉換,就要透過 * 和 & 兩個運算符號來進行了
這兩個運算符,如同 +-*/ 可以對變數產生作用一般,也可以對指標產生作用
* 的作用是取值(dereference)
如果覺取值艱澀難懂的話呢,取值就是看這個指標指到的東西是什麼
以方才的比喻,這個星號的功用就像是給了弓箭手能量、讓他可以射出箭,並且看看他射到的箭靶上面寫了些什麼東西(值)
而 & 的功用是取址(reference)
取址是什麼鬼東西呢? 就是看看變數住在什麼地方(也就是記憶體位置)
射箭的例子中,這就是靶在哪裡,就是經度幾度啦,緯度多少啦這樣
真實的情況下,記憶體位置是用一個數字來表示(和經緯很像,不過它只有一維)
如果用圖來表示的話,就像這樣
reference 呢,我們中文常常會叫做參照,感覺很難,但它代表的就只是"參考位置"
就像我們翻參考書要翻開哪一頁來參考一樣,只是講參照好像比較厲害(?)
實際上就還只是變數住在哪而已(箭靶)
從圖中也可以看到呢, * 和 & 互為反函數
一個是變過去,一個是變回來
所以兩個一起用的時候呢,就等於沒有用一樣XD
ptr 和 *&ptr 和 &*ptr 其實都是一樣的東西(以上圖來說就只是轉了一圈又回到原點)
dereference 呢,就只是把 reference 反過來做,就去看看這個地方住著誰(箭靶上寫著什麼)
4. Manipulation
對變數的加法,就是簡單+1(或其它數字)
指標裡一樣可以進行加減法(好像就沒有乘除法了@@)
指標的加法呢,就是讓弓箭手的目標移到下一個箭靶上
實際上呢,是讓指標指去下一個變數上面
比如現有一陣列 num[ 2 ] (int型) 所以 num 上面就有了 2 個箭靶(兩個數字)
假如一開始指標(弓箭手)指向第一個箭靶(num[ 0 ]),那麼 ++ptr 或 ptr++ 都會讓指標(弓箭手)指向下一個箭靶(num[ 1 ])
那我再加一次,又會怎麼樣呢?
我沒有第三個箭靶可以讓它射了,如果這時候還對它取值( * ),讓弓箭手射出箭的話,你可能就會射中空氣(運氣更糟點還會射到別人的臉上,假如那個位置剛好放了別人的臉0.0)
(註:這個時候"可能"會發生 segmentation fault,就是你指錯地方了)
那如果 *ptr++ 或是 ++*ptr,卻又如何呢? (ptr is int*)
前面所述(忘了的話麻煩往上滑一下囉~),*ptr 已經是個 int 了(靶上寫的東西)
對它 ++,就像是對普通的 int 做 ++,所以靶上寫的東西就會+1(塗改靶上的值)
所以 ptr++ 和 *ptr++ 是不同的東西喔
一個還在指標型態進行加法(移動目標),一個卻已經先變成變數型態了(移動靶值)
所以兩個加法會出現不同的結果
注意到如果我寫 ptr+2 的時候,代表指標往後移兩個 int 後的位置(弓箭手所指往後兩個箭靶)
*ptr+2 則是靶上的值加 2 (還是指向同一個靶)
5. Assignment
指標的指定,如同變數的指定一般,是讓它的值變成某一個東西
現有 ptr, ptr2, ptr 指向了一個變數, ptr2 不知道指去哪
ptr2 = ptr 之後
它們就指去同一個地方(靶)了
如果我改了 ptr 指到的靶上寫的東西的話,那 ptr2 指到的值也會跟著變
(因為指在同個靶上嘛)
這篇就寫到這了,希望大家都還看的懂囉~
沒有留言:
張貼留言