跳到主要內容

Pointer 之不是我排擠你而是我搞不定你!

學習 C 的過程中, Pointer 這個章節對我來說是個無法抹去的痛.
也許是我領悟力太差, 又或許是練習不夠, 我始終無法說服我自己 Pointer 的概念是很自然的.

在 Java 中, 不會操作到指標, 也沒有操作指標的方法.
Primitive Datatype 就是傳數值, Object Datatype 就是傳位址. 雖然骨子裡頭, 物件的操作一樣是使用指標傳遞位址, 但是看不到指標卻是如此的神清氣爽.

在 Objective-C 裡就不是這麼一回事了. Pointer 又回來了.
沒辦法搞定 Pointer 就沒辦法搞定 Objective-C, 不得不, 還是得好好的練習摸索.

於是, 用幾個範例來幫助自己記憶, 分享給所有對 Pointer 沒轍的程式人 orz...
int numbers[] = {1, 2, 3};
int *numbersPtr;
numbersPtr = numbers;
NSLog(@"%i, %i, %i, %i", *numbers, numbers[0], numbers[1], numbers[2]);
NSLog(@"%i, %i, %i, %i", *numbersPtr, numbersPtr[0], numbersPtr[1], numbersPtr[2]);
[輸出結果]
1, 1, 2, 3
1, 1, 2, 3
先複習一下, 宣告變數時, 在變數名稱前加上 "*", 即為宣告該變數為特定資料型態的指標.
使用變數時, 在變數前加上 "&" 可以取得儲存該變數的位址, 可以用來指派給指標.
使用指標變數時, 在變數前加上 "*" 可以取得該指標指向之位址所儲存的數值.
那指標是什麼? 指標是一個變數, 用來儲存某種資料型態之資料的位址.

回到範例, 在這個例子裡頭很明顯可以看到,  以中括號宣告的 int array 可以指派給 int pointer.
又可以看到, *numbers 和 numbers[0] 的數值相同, *numbersPtr 和 numbersPtr[0] 的數值相同.

所以可以推論
=> 陣列是一種指標, 而陣列變數存的其實是第一個 element 的位址.

實際上書裡也是這麼寫的,
numbersPtr = numbers <-equals-> numbersPtr = &numbers[0]
所以 "*" 加陣列名稱實際上取得的是第一個 element 的數值.

看起來, 似乎沒什麼問題了, 根本沒想像中那麼難嘛, 寫程式的人是怎麼回事, 有那麼恐怖嗎?
用到一個 "*" 的時候看起來好像真的沒那麼難, 那如果用到兩個 "*" 呢?
老實講, 我頭好暈 orz...

最簡單的就是在 Objective-C 中的 Object Datatype. 換個例子再看看.
NSString *string1 = @"String1";
NSString *string2 = @"String2";
NSString *strings[2]; //an array of NSString objects
strings[0] = string1;
strings[1] = string2;
NSString **stringsPtr; //a pointer to NSString object 
stringsPtr = strings;
NSLog(@"%@ %@ %@", *strings, strings[0], strings[1]);
NSLog(@"%@ %@ %@", *stringsPtr, stringsPtr[0], stringsPtr[1]);
[輸出結果]
String1 String1 String2
String1 String1 String2
要先說明的是, 在 Objective-C 中物件的宣告和 Java 不同, 必須用到 "*".
但問題來了, 該怎麼取得物件的內容呢?
如果依照 Primitive Datatype 的概念, 第一個想到的答案會是使用 "*" 加上物件名稱, 然而這樣的操作方式, 並不能取得該物件的內容. (那會取得什麼呢? 有興趣可以自己玩玩看 XD)
取得物件的方式和 Java 沒兩樣, 不需要加上 "*", 直接使用物件名稱就可以取得物件的內容.
那麼, 怎麼進行物件的指派呢? 這也和 Java 一樣, 不需要加上任何符號, 直接以物件名稱就可以進行指派. 說明結束, 回頭看範例!

在這個範例中, stringsPtr 這個變數有兩個 "*".
別和我一樣一看到兩個 "*" 就暈了. 冷靜想想, 兩個 "*" 並沒有那麼恐怖. 因為在 Objective-C 中物件的宣告必須使用到 "*", 所以 stringsPtr 的宣告實際上是這個意思
=> 宣告 stringsPtr 為一個指向 NSString 物件的指標.

剩下的其實就跟第一個範例一樣, 陣列就是一種指標
=>  strings 這個 NSString 物件陣列, 可以指派給 stringsPtr 這個 NSString 物件的指標.
陣列名稱存放的其實是第一個 element 的位址
=> "*" 加陣列名稱將會取得在陣列中的第一個物件.

呼... 看似簡單, 但每次用上卻依然覺得頭昏眼花.
真的希望是熟練度的問題, 希望在我多多練習後, 不會再次碰上 Pointer 指向哪, 看了程式碼卻越看越花的窘境.

留言

這個網誌中的熱門文章

引數?! 參數??!! 什麼鬼啊!!

我想這個不僅是只有我會遇到的問題, 大概也是所有 Programming 的人都有的疑惑 (應該是吧?) 什麼引數?? 什麼參數?? 天啊... 到底是誰翻譯的呀!!!! 就字面上來看... 講句實在話, 我真的不了解, 大概是學藝不精所致. 也許有些人認為 => 管它那麼多!! 寫得出來就好了!! 不過龜毛如我, 我還是想搞清楚定義是什麼!

世界第一! 臺灣的驕傲! iPod 全球最貴 XD!!??

2009 年 9 月 10 日 凌晨 1 點鐘, Apple 於美國舉行了 Apple Special Event September 2009 . 先說點題外話, 這場演說對 Apple 迷而言, 是久違的一場, 也不知道還能有幾場像這場一樣, 由 Steve Jobs 親自站臺. 這場演說的主題, 除了 iTunes 9, iPhone (iPod touch) OS 更新為 3.1 外, 就是 iPod 產品線的更新. 在看完發表會之後, 我去研究了一下新 iPod 的全球售價, 這也是這篇文章的重點, 蘋果臺灣的定價創下了新的紀錄- 套用一下最近常聽到的 Slogan 世界第一, 臺灣的驕傲, iPod 全球最貴!!??

關於 Polymorphism! 是的, 就是多型!

這幾天真的是寫了好多關於程式基礎的東西, 今天心血來潮想寫個物件導向的特性 - Polymorphism. 是的, 你沒看錯, 就是多型. 多型, 這有什麼好寫的呀? 每本物件導向的書籍, 不管是程式語言或是方法論, 一定都會提到的基本特性. 去書局翻翻就有了, 甚至在網路上搜尋 “物件導向” “多型”, 就可以找到讀也讀不完的資料. 在這老調重彈, 似乎有點... 多餘? 會想把這個議題拿出來講, 關鍵就在於我發現 Objective-C 上的多型, 和我以前認識的不太一樣, 更加 Powerful.