這幾天為了要寫一個二進制搜尋(Binary Searching)又複習了一下指標與陣列的使用。
為了怕以後忘記不好找,就寫上來吧!
變數(Variabel)可以看成盒子,每個盒子可以有自己的名字,也就是每個變數都可以為它命名。
而盒子可以裝東西,PC只認得數字,所以裡面只能存放數字,至於文字,其實PC還是轉換成數字來識別的。
INT VAR = 123;
INT-> 變數的型態是整數(INTEGER),也就是這個盒子只能裝整數的數字,這邊就是 123 這個數字。
陣列(Array)其實是一連串組成的變數。
INT ARRAY[5];
也就是一共有5個疊串在一起的盒子,每個盒子都是裝整數用的,這一串盒子的名字就叫做 ARRAY。
看起來就像這樣
有注意到我把箭頭移到第一個盒子上方了嗎?這個等下就會說到了。
如果想拿第三個盒子的內容要怎麼拿呢?
因為從0開始算起,所以要寫成 VAR = ARRAY[2]; 就可以了。
指標(Pointer)的內容其實是位址(Address)
如果我們把整個記憶體當作盒子來看的話,指標就像是上圖的箭頭了。
DOUBLE *Ptr = 0x00; 指得是有一個指標 ptr,指向DOUBLE的指標。
看起來就像這樣
指標的內容其實就像是"第幾個"盒子一樣,可以算到第幾個盒子,就是所謂的可以定址到多少的意思囉。
想要取出盒子的內容時,加上 * 就可以了,也就是 VAR = *ptr;
那DOUBLE指標跟INT指標有何不同?
因為DOUBLE的長度大小是INT的兩倍,所以當DOUBLE指標每移動一步,距離就是兩個INT的大小。
ptr ++;
VAR(整數型態) = *ptr; 會發生什麼事?
正確答案是,會發生編譯警告。
此時的*ptr取出的值應該是 2233 (有些會跑出 3322,這是 Big endian or Little endian的問題,也就是高位址高放或高位址低放),是DOUBLE型態。
但是由於VAR卻是整數型態,而不是裝DOUBLE這種大小用的盒子,所以編譯器會警告你。
而如果強制這樣做的話,VAR的內容就是 33 or 22 了(視編譯器而定)
有沒有發現?
Pointer與Array似乎有異曲同工之妙。
如果我們把 ptr = ARRAY,ptr的內容就是ARRAY第一個盒子的位址(Address),所以這種陳述常被使用,方便利用Pointer來存取陣列裡的各元素。
承前述
INT Array[5]={0,1,2,3,4};
INT *ptr;
ptr = ARRAY;
ptr += 2;
*ptr 會取出 2
ARRAY[2] 也會取出 2
所以是可以交替使用的
甚至可以寫成 ptr[2]來使用,不過陣列就不能反過來加 * 使用了喔!
陣列也可以宣告成二維以上的,也就是 ARRAY2D[5][5]這樣,其實記憶體是連續一串的,宣告成二維等於只是把一維的組裝成二維。
看起來就像這樣
這樣應該可以了解,不管是幾維的陣列,其實都可以是一維陣列的延伸與組合罷了。
現在要進入重點了。
既然我們常用 *ptr 來替代 ARRAY[],那麼ARRAY2D[][]可以也用指標來替代嗎?
這就是很多初學者會搞不清楚的地方,網路上也很多初心者詢問二維陣列與指標交替的問題。
事實上,使用雙重指標(**dptr),跟二維陣列(ARRAY[][])是不一樣的。
還記得嗎? 指標(Pointer)其實是"箭頭",內容其實是位址(Address),所以(**dptr)是一個指標指另向一個指標。
以例子來說,也就是箭頭會指出第幾個盒子,而指出的盒子裡面放的也是箭頭,可以指出第幾個盒子。
ARRAY[][]則是已經直接指名要第幾個盒子了。這才說它們果真是不相同的。
那麼,如果就是想使用指標來替用怎麼辦?
INT ARRAY2D[num1][num2];
其實可以用
INT (*ptr)[num2];
這樣就可以了。
這樣的意思是,有一個陣列,長度為num2,這是一個型態為INT的指標陣列,也就是陣列的每個元素都是一個指標。(可以由右往左來解釋)
最重要的是,這個ptr每移動一步,就是一個num2的距離。
(prt+1) - ptr 的大小就是一個 num2
要針對ARRAY2D來運用的話,就是
ptr = &ARRAY2D;
VAR = (*(pAlphabet+X))[Y]; /*可以取出值*/
X->相對於陣列的第一維
Y->相對於陣列的第二維
這樣是不是很清楚了!
留言列表