多維順序儲存陣列之位址求解問題

2021-08-11 08:00:27 字數 3300 閱讀 8164

近期資料結構課講到多維陣列及矩陣,說到資料儲存在計算機中實際儲存順序的時候就暈了,概念自己倒是知道,但是自己算的時候就迷迷糊糊。身邊也有同學和我抱怨說老師上課進度太快了,認為雖然c裡面提過但上課還是需要再解釋。想了想就寫了這篇文章,也算是幫同學也幫自己大概理一下思路。

本文將就多維陣列的概念、c語言中多維陣列的定義方法及記憶體分析等點進行解析。

在講多維陣列前,我會先說最基本的一維陣列,然後再講二維陣列,再由二維陣列引申至多維陣列。所以建議已經了解陣列的同學可以直接看二維陣列,已經熟悉陣列想搞清多維陣列元素位址求解的同學直接往下拉到最後一部分。

一維陣列

陣列是含有多個具有相同資料型別的資料的有序(此處的「有序」指所有元素依次存放在記憶體中相鄰的一組線性空間內,除了第乙個和最後乙個元素外,每個元素有且只有乙個前驅和後繼)集合,陣列中的資料稱為陣列元素。這些資料在記憶體中占用連續的儲存空間。陣列一旦定義,在程式執行期間其位置和大小不能再發生變化。

這裡涉及到的知識點有關計算機記憶體的儲存結構了,接觸過彙編或者是組成原理的同學肯定懂,不懂的同學建議去了解一下。簡單形象地理解記憶,如圖,我們的資料儲存在相應儲存器的儲存單元中,計算機中儲存單元都是按順序排號的,每個儲存單元有乙個位址,通過對這個位址的查詢你可以訪問到對應的儲存單元。

假設我們定義乙個一維陣列

int a[3] =;
則它在記憶體中相應的儲存形式如圖。

一維陣列元素位址求解

陣列定址可由首位址+偏移量得到。也就是說,要想知道當前元素位址,則必須知道它所在陣列的首址以及相對陣列第乙個元素的偏移量,而偏移量可以由元素

個數∗單

個元素所

佔記憶體大

小 計算得到,所以也就是說,除了陣列首址,我們還必須知道在這個元素前還有多少個元素*, 即 首位址+前面元素個數×單個元素所佔空間 。譬如上面陣列a[2](即值為3的元素)的位址,a即為該陣列的首位址,這個元素前面還有兩個元素,所以它的位址為 a+

2×si

zeof

(int

) 。

二維陣列

如果拿我們最熟悉的座標來模擬的話,剛才的一維陣列相當於是數軸上點的結合,乙個下標就相當與其座標,可以對應乙個元素;而二維陣列就是平面直角座標系中的點的集合,兩個下標課已對應乙個元素。

但是,計算機是線性的儲存結構,是一條帶子一樣順下來的,所以這種二維在計算機中也要按某種規則轉化成一維。

舉個栗子:乙個2*3的矩陣a:a=

[142

536]

int a[2][3] = ,

};

上面我定義了乙個二維陣列,那麼實際上它是由兩個陣列組成,乙個是,乙個是,而這兩個陣列又作為元素被儲存在另乙個更大的陣列a[2][3]中。

按行優先儲存的話,它在記憶體中的儲存形式如圖:

相比較來說,我個人更喜歡把它立體化成乙個平面,照著定義來話,只不過需注意的是兩組陣列間的位址連續

預設對二維陣列定義的話就是按行優先,但如果按列優先儲存的話,它在記憶體中的儲存形式如圖:

同樣的,立體化成平面:

按行優先儲存和按列優先儲存本質上沒有什麼區別,在**上,也只是a[i][j]順序調換一下即可。

\\按行優先

int i, j;

for(i=0; i

<2; i++)

for(j=0; j

<3; j++)

\\按列優先

int i, j;

for(j=0; j

<3; j++)

for(i=0; i

<2; i++)

\\按列操作

二維陣列元素位址求解

和一維位址一樣,我們需要知道的就是陣列首址以及所求元素前面的元素個數。陣列首址不需要我們計算,我們需要計算的就是元素個數,這個時候大家可以看立體化成面的圖,我們可以看當前元素前面又多少行或列,因為這些行或者列都是完整的,所以我們只需用 行數(或列數)×每行(或每列)的元素個數×單個元素的所佔記憶體大小,最後再加上該元素相對其所在行首址的偏移量即可。以上面的二維陣列為例,求 a[1][2] 的位址,若按行優先儲存,那麼該元素前面有一行元素,每行有3個元素,第二行排在該元素前面有2個元素,那麼這個元素的相對於首址的位址就是,a+1×3×sizeof(int)+2×sizeof(int);而按列優先儲存的話,則為 a+2×2×sizeof(int)+1×sizeof(int)。

劃(考試)重點:可以看到所求哪個元素,其陣列下標所對應的就代表了該元素前面有多少行(或列)該行(或列)有多少元素(僅針對於陣列下標從0開始的語言)。按行優先是從右往左維數增加,按列優先是從左往右維數增加。這一點從**能很清楚的看到,按行優先的時候,內層迴圈是陣列下標靠右的,這個迴圈事先完成形成第一維,然後一維再不斷地堆疊成二維。

多維陣列

其實二維陣列寫完我覺得已經很清楚了,只要能理解二維陣列,那麼多維陣列也是一樣的道理,而上面的(考試)重點也是對多維陣列也成立的。

這裡我將不再進行過多的文字說明,舉乙個三維陣列的栗子,畫一下圖,大家根據圖再進行理解。

定義乙個三維陣列:

int a[3][2][3] = , 

,};

相對應的儲存示意圖如下:

一維、二維、三維陣列我們可以與數軸、平面直角座標系、空間直角座標系分別關聯記憶,但是維數再往上加就找不到類似的了。但是,方法還是一樣的,大家可以理解為,每增加乙個維度,就相當於將先前的等空間地複製乙份進行儲存

四維及更多維陣列的儲存形式:

&a[i][j][k][...][l] = i×jsize×ksize×...×lsize + j×ksize×..×lsize + ksize×...×lsize + ... + l

按列優先儲存:

&a[i][j][k][...][l] = l×...×ksize×jsize×isize + ... + k×jsize×isize + j×isize + i

求解公式其實就是這麼簡單,但是重要的是在於理解。理解的關鍵點就在於對維數的分解。如果還有不理解的同學,建議結合空間想象和從**的迴圈實現角度去想:n重迴圈實現n維陣列的儲存,最內層迴圈是第一維,每往外出一層迴圈相應的維數就加一,計算位址的時候則是由外至內拆解。

多維陣列的位址轉換

多維陣列和廣義表是一種複雜的非線性結構,它們的邏輯特徵是 乙個資料元素可能有多個直接前驅和多個直接後繼。多維陣列 1 陣列 向量 常用資料型別 一維陣列 向量 是儲存於計算機的連續儲存空間中的多個具有統一型別的資料元素。同一陣列的不同元素通過不同的下標標識。a1,a2,an 2 二維陣列 二維陣列a...

多維陣列的順序表示

多維陣列節點,有四個元素 struct array 譬如乙個2 3的二維陣列,dim就等於二,行優先儲存,bounds 0 就為2,bounds 1 就為3。對於constants,constant i 就是第i 1層的陣列中每一元素 陣列 的大小。對於行主序的2 3的二維陣列來說,constant...

迷糊的多維陣列的位址

為什麼要寫這個?因為這個東西有點混亂,至少我第一次接觸的時候是這樣的。或許以後還會,所以記下來需要的人一起看吧。直接上主題,我做事就是很直接,當然也會很囉嗦,下面你將會一併體驗到。int count 2 3 count 陣列count 0 0 的位址。count 1 陣列count 0 0 行數的偏...