陣列 與 指標 的再次探討

Golang與C的指標觀念

Gopher is cute
Caesar's study review on Web development
4 min readAug 18, 2018

--

最近練習用C語言進行資料結構Linked List練習,經常使用到指標,發現了一些以前沒想到的盲點,搜尋網路資料後,做個簡易的整理,方便以後回憶

目前打算選擇的後端語言是Golang,類C語言的程式,因此讓我想再次搞懂指標,希望Golang可以讓我轉職WEB後端的路可以順利進行

第一個例子,其差異處?

char *str1 = “test1”; 
char str2[] = “test2”;

str1在該行宣告,可以看成做了3個動作,i.宣告了一個指標變數str1,還沒有指向特定的記憶體空間、ii.在記憶體的data區建立了一個常數字串"test1"、iii.指標變數str1指向了常數字串”test1"

str2同樣可以看成做了3個動作,i.宣告了一個陣列str2,並且拿到6個char的記憶體空間、ii.在記憶體的data區建立了一個常數字串”test2"、iii. str2用strcpy把”test3”複製到陣列中

最重要的差異在於第一點,指標變數str1只能儲存char類型的指標,並沒有被給予記憶體空間,而陣列str2有被分配記憶體空間來儲存字串

在一維陣列的情況下,可以看成宣告陣列時,視為一個指標有獲得記憶體空間,只單純宣告指標變數,不會得到記憶體空間

Ref: https://www.ptt.cc/bbs/C_and_CPP/M.1318386034.A.935.html

int array[3] = {6, 8, 9};其記憶體空間的位址
array: 0061FF24
&array: 0061FF24
&array[0]: 0061FF24
&array[1]: 0061FF28
&array[2]: 0061FF2C
array + 0: 0061FF24
array + 1: 0061FF28
array + 2: 0061FF2C
&array + 0: 0061FF24
&array + 1: 0061FF30
&array + 2: 0061FF3C

首先要知道陣列的名稱可看作一個常數指標,儲存了該陣列第一個元素的記憶體位置,因此用array、&array、&array[0]都是顯示相同的記憶體位置,但指向的記憶體大小不同,在多維陣列的情況下更能顯示差異

int為4bytes 所以 &array[0] ~&array[2]之間的記憶體位置都差距4

陣列名稱array是一個指向陣列第一個元素的位址的指標,儲存了該陣列第一個元素的記憶體位置,並且指向4bytes的記憶體空間

&array同樣,儲存了該陣列第一個元素的記憶體位置,但是指向為12bytes的記憶體空間,實質上是指向了整個陣列,這個指標是一個指向「帶有3個int的陣列」的指標, 我們把該指標命名為 ptr,也就是ptr=&array,其定義寫成 int (*ptr)[3];

  Ptr_array  + n  //記憶體位置計算方式如下
= &array[0] + n * sizeof(*&array[0]) // 陣列的開頭的第一個元素
= array + n * sizeof(*array) // array指向陣列第一個元素
= &array + n * sizeof(*&array) // &array指向整個陣列

雖然儲存同樣的記憶體位址,但&array表示指向了整個陣列(12bytes),array指向第一個陣列的元素也就是整數(4bytes)

因此&array + 1與+2之間,會一次跳12bytes的記憶體空間(請用16進位來想)

Ref : https://www.ptt.cc/bbs/C_and_CPP/M.1486132977.A.B3A.html

用「右-左」的方式來讀, 看

char * a [20]
[4] [3][1] [2]

[1]: 'a' 是一個...
[2]: 長度為 20 的陣列, 其元素是...
[3]: 指標, 指向
[4]: 一或多個字元 (char).
也就是有20個指標
char ( * b )[20]
[4] [2][1] [3]

[1]: 'b' 是一個...
[2]: 指標, 指向...
[3]: 一個大小為 20 的陣列. 其元素為...
[4]: 字元 (char).
也就是只有一個指標,但指向大小為20的陣列

Ref : http://www.programmer-club.com.tw/ShowSameTitleN/c/16447.html

個人隨筆:

  1. 陣列中括號 有類似提領(dereference)的作用
xType[2] 的運算,等於 *(xType + 2)。第一階段:計算 xType + 2 的位址第二階段:對上述位址做 dereference(*)

2. 陣列名稱array是一個指向陣列第一個元素的位址的指標,若為多維陣列, 例如int array[3][2][4],陣列名稱array指向陣列第一個元素,且data type為 int (*)[2][4]

--

--

Gopher is cute
Caesar's study review on Web development

我的第一份後端工作結束了,短短四個月,部門全員掰掰,尋找新的機會。