一、數組的基本概念
從邏輯結構上看,數組A是n(n>1)個相同類型數據元素a1、a2、…、an構成的有限序列。
其邏輯表示爲:A=(a1,a2,…,an)。
其中,ai(1≤i≤n)表示數組A的第i個元素。
一個二維數組可以看作是每個數據元素都是相同類型的一維數組的一維數組。以此類推,任何多維數組都可以看作一個線性表,這時線性表中的每個數據元素也是一個線性表。
多維數組是線性表的推廣。
推廣到d(d≥3)維數組,不妨把它看作一個由d-1維數組作爲數據元素的線性表;或者這樣理解,它是一種較複雜的線性表結構,由簡單的數據結構即線性表——輾轉合成而得。
二、 數組的存儲結構
從存儲結構上看,數組的所有元素存儲在一塊地址連續的內存單元中。幾乎所有的計算機語言都支持數組類型,以C/C++語言爲例,其中數組數據類型具有以下性質:
(1)數組中的數據元素數目固定。一旦定義了一個數組,其數據元素數目不再有增減變化。
(2)數組中的數據元素具有相同的數據類型。
(3)數組中的每個數據元素都和一組唯一的下標值對應。(4)數組是一種隨機存儲結構。可隨機存取數組中的任意數據元素。
在一維數組中,一旦a1的存儲地址LOC(a1)確定,並假設每個數據元素佔用k個存儲單元,則任一數據元素ai的存儲地址LOC(ai)就可由以下公式求出:
LOC(ai)=LOC(a1)+(i-1)*k (0≤i≤n),其中i是從a[0]算起的,如a[5],i=6,其實也可以直接看作是ai的i*k。上式說明,一維數組中任一數據元素的存儲地址可直接計算得到。
對於二維數組來說,由於計算機的存儲結構是線性的,如何用線性的存儲結構存放二維數組元素就有一個行/列次序排放問題。
以行序爲主序的存儲方式:即先存儲第1行,然後緊接着存儲第2行,最後存儲第m行。此時,二維數組的線性排列次序爲:a1,1,a1,2,…,a1,n,a2,1,a2,2,…,a2,n,…,am,1,am,2,…,am,n
對一個已知以行序爲主序的計算機系統中,當二維數組第一個數據元素a1,1的存儲地址LOC(a1,1)和每個數據元素所佔用的存儲單元k確定後,則該二維數組中任一數據元素ai,j的存儲地址可由下式確定:
LOC(ai,j)=LOC(1,1)+[(i-1)*n+(j-1)]*k,其中n爲總列數。
同理可推出在以列序爲主序的計算機系統中有:
LOC(ai,j)=LOC(1,1)+[(j-1)*m+(i-1)]*k,其中m爲總行數。
例1,按行優先順序和按列優先順序列出四維數組A[2][2][2][2]所有元素在內存中的存儲次序。
解: 按行優先的存儲次序:
A[0][0][0][0], A[0][0][0][1], A[0][0][1][0],A[0][0][1][1], A[0][1][0][0], A[0][1][0][1],
A[0][1][1][0], A[0][1][1][1], A[1][0][0][0],
A[1][0][0][1], A[1][0][1][0], A[1][0][1][1],
A[1][1][0][0], A[1][1][0][1], A[1][1][1][0], A[1][1][1][1]
按列優先的存儲次序:
A[0][0][0][0], A[1][0][0][0], A[0][1][0][0],A[1][1][0][0], A[0][0][1][0], A[1][0][1][0],
A[0][1][1][0], A[1][1][1][0], A[0][0][0][1],
A[1][0][0][1], A[0][1][0][1], A[1][1][0][1],
A[0][0][1][1], A[1][0][1][1], A[0][1][1][1],A[1][1][1][1]
例2(求地址,重要!),C/C++中二維數組float a[5][4]的起始地址爲2000,且每個數組元素長度爲32位(即4個字節),求數組元素a[3][2]的內存地址。
解:
LOC(a3,2)=LOC(0,0)+[(i*n)+j]×k = 2000+(3×4+2)×4 = 2056。
從中看到,對於C/C++的數組a[m][n],求a[i][j]元素的地址爲:
LOC(ai,j)=LOC(a0,0)+(i×n+j)×k
例3.行優先存儲數組:如int a[10...20,5...10],且int a[10,5]的地址爲1000,且存儲每個數組元素佔4個字節,求數組[18,9]的內容地址。
解:LOC[18,9]=LOC[10,5]+((18-10)*(10-5+1)+(9-4))*4=1208
當前行18減去10,表示前8行元素;10-5+1表示第10列減去從第5列再加上1,則前面有8*6=48個元素;
再加上第九列和第五列差4,總共52個元素;