大一程設-下
東華大學
東華大學資管系
基本程式概念
資管經驗分享
在真的探討二維的動態陣列之前,有一個必須知道的基本知識就是雙重指標,而他的概念有點不直覺,我們一起來看看。
在開始閱讀這篇筆記前,請確定你閱讀過運算子的優先權了哦! -> 我是傳送門
第一次看請不要灰心,一定會看不懂,多看幾次吧QAQ。
Orange
複習一下,一般的指標變數如下:
那既然會說是雙重指標變數,長相如下:
可以看到有兩顆 *
,那該怎麼理解呢? 我們先從名詞解釋開始吧。
還記得我們稱 int *p
為一個指標變數,會儲存一個指標(記憶體位址)。
不失一般性,int **p
仍為一個指標變數,也會儲存一個指標(記憶體位址),但他儲存的指標是一個指標變數的指標(記憶體位址)。
所以就會有我們常聽到的,雙重指標變數就是「指向指標變數的指標變數」。
我們馬上看個實際例子。
以 int *p1
來看,他是一個指標變數,儲存一個變數 a 的指標。
以 int **p2
來看,他是一個指標變數,儲存一個指標變數的指標。
如果你覺得很饒口,看一下下面的圖幫助你理解。
核心觀念千萬不要忘記,無論是一般的指標變數,還是雙重指標變數,都是儲存記憶體位址,就算今天變成三重指標變數,四重指標變數都一樣哦!
而這邊宣告他們是 int 型態就與上一篇筆記在講一般指標變數時相同,代表該指標變數最後指向的記憶體位址所儲存的值必須要是 int 型態。
今天你宣告一個指標變數是幾層指標,他就必須要指向幾次,可以參考上圖,雙重指標變數(0x300)會根據記憶體位址指兩次,一般指標變數(0x200)只有指一次。
如果你把指向次數不同的位址指派錯人,程式是會報錯的哦,像下面這樣。
你會看到像下面這樣的錯誤訊息。沒有辦法把一重指標變數指派給雙重指標變數,所以請一定要明確了解這邊的運作方式哦。
還記得請各位去看一下運算子的優先權,這邊想跟大家討論的原因是,int **p
這邊有兩個 *,亦稱 dereference 運算子
,請問要先看哪個星號,優先權是如何?
int *(*p2)
看到 *
號(左邊那顆)代表宣告指標變數,但因為是右結合,所以 p2 與 右邊的 *
優先結合,這樣由左至右就可以翻譯成,宣告一個指標變數其指向一個一重指標變數。
相信都是文字有點不直覺,我們再看張圖吧!
已經講到最簡單摟,希望大家多多思考,有問題鼓勵發問!
在真的配置動態二維陣列之前,有一些觀念要跟大家討論。
二維動態陣列配置的記憶體運作方式是像這樣的,請看下圖。
圖片來源 -> here
所以第二層我們稱它為指標變數陣列,陣列中的每一格都儲存一個指標變數。我們後面來說明它。
就像整數陣列每格存整數,浮點數陣列每格存浮點數。
指標變數陣列每格存指標變數,就這麼簡單~
所以你只要搞懂什麼是指標變數你就會了。
Orange
既然已經知道上面那張圖的看法跟建立陣列的方式,我們來看 CODE。
別忘記之前講的。
cout << p2
代表印出指標變數 p2 所指向的位址。
那換成下面這樣。
cout << p2
會印出指標變數 p2 所指向的陣列頭的記憶體位址。
而 cout << p2[0]
會取出 p2 這個指標變數陣列第一格所儲存的值,因為每一格都是指標變數,所以會印出第一格指標變數的記憶體位址。
cout << p2[0][0]
會取出 p2 這個指標變數陣列第一格所儲存的值(位址)所儲存的值。
以下依此類推…
畫個圖就像這樣。
上面這張圖可以用下面這個範例玩一下,確保你知道圖上每個取值取址的不同處哦!
所以其實一個 3 * 2 的動態陣列,就配置了 10 個記憶體位址,你說它真的非常有效率嗎?真的端看需求而定!
上面的例子動態配置了 3 * 2 的陣列,但配出來的這些記憶體,必須要被收回去,語法先來。
我想在看配置的時候,應該有點感覺,我們是從外到內一直分配記憶體出來,所以在回收的時候呢,要先把最內部的記憶體刪乾淨,才能把外面的刪掉。
語法沒有 p[0 ~ 2][0 ~ 1] 這種寫法,這邊只是說明!
這樣寫絕對大扣分
Orange
到這邊的內容是參考書的內容,要考過考試大家要學會,下面是補充。
以下為補充~
我左思右想,我雖然會,但我決定依靠大神們來講解
Orange
雖然語法是 C,不是 C++,但核心概念不變,可以自己用 C++ 的語法試試看
裡面有一些小地方寫錯,麻煩自己判別哦
上面那篇要你們看的地方看得懂的話,這篇一定看得懂
雖然是大陸用語,但我相信聰穎的你一定知道對應到我們常說的甚麼。
不會歡迎來找我討論哦~
給大家一些例子自己閱讀吧~
有問題歡迎來問我~
如果你真的搞懂了 precedence 跟結合性,請問第 11 行怎麼解讀呢?
很累吧,看個搞笑的文章放鬆一下