[英]accessing multidimensional array in c
我需要以下代碼的解釋:
int a[2][3][2] = { 1,2,3,
4,5,6,
7,8,9,
10,11,12 };
std::cout << a[0][5][0];
就multi dimensional arrays
而言,第一個索引指示行數,第二個索引指示列數,第三個索引指示數組數。 但是,這段代碼給了我11
作為輸出,更令人震驚的是
for(int i=0; i<12; i++)
std::cout<<a[0][0][i];
打印數組的所有元素。 我在網絡上的任何地方都找不到這種訪問的解釋。 有人請澄清一下!
這樣想吧。
a [2] [3] [2]實際上只是將a [12]分為2組然后是3組。
a [0] [5] [0]確實是a [0] [0] [5 * 2] = a [0] [0] [10]
這是因為將數組加載到連續內存中。
這個故事的寓意是……“沒有湯匙”(矩陣)。
沒有行,列和頁面。 只是具有線性序列的內存,其中元素僅一個接一個地存儲。
多維數組只是一個“投影”,而想法或頁面/行/列只是一個抽象。
a[k][j][i]
意思僅僅是(間接層之間的距離) *(a + k*Y*X + j*X + i)
其中Z,X和Y是尺寸的大小。 我們最可能稱為“頁面”,“行”和“列”的內容。
注意。 與Z,Y和X無關,將k = 0,j = 0,i = 11放在等效表達式中是完全合理的,並且將引用12值。
只要您處於a[2][3][2]
的范圍內,您期望的結果就一直保持。 也就是說,當您對a[1][2][1]
執行a[0][0][0]
時,您的假設將成立。 但是,一旦越過邊界,您看到的結果將不再相同。
實際上,考慮到您在代碼中使用的數字, a[i][j][k]
在技術上與第一個元素之后的k+j*2+i*2*3
元素相同。 這樣就可以表示看起來像“ 3D”的數組,但實際上在內存中它們是“行”或一維數組。 因此,通過執行*2
和*2*3
您實際上跳到了“下一個”子數組。
當您超出a[2][3][2]
的范圍時,為什么它不起作用? 以a[i][j][k]
k=4
a[i][j][k]
為例,它等效於i*2*3 + j*2 + k = i*2 + (j+1)*3 + 1
。 因此,就好像它已經“跳到”了下一行/列/任何內容。
您可以通過想象一個表格並遍歷該行,從而更好地將其可視化為二維數組,一旦超出該行的最后一列,您便會落在其下方的行上。
但是,當您超出多維數組的范圍時,或者當您“掉下”所在行時,C不會警告您。
更新資料
您正確地說 a[0][5][0]
不存在。在這種情況下,發生的事情是您實際上將讀取內存中緊挨着 a
。例如,假設您的代碼中有 a
和b
,當您在代碼中處理a
和b
時,實際上a
和b
只是一部分內存。假設 a
是一個總共包含12個元素的數組,當您超出這12個元素時,C只會假設該數組與您說的一樣大,然后獲取15個“塊”之后的內存會給你的因此 a[15]
實際上存在,但不屬於數組。如果它們在內存上彼此相鄰,則它可能屬於 b
,或者它可以完全屬於其他東西。
技術術語是,當您將 a
聲明為大小為12的整數數組時,它將彼此相鄰分配12整數(12 * 4字節)的內存,並為您標記a
。a
將指向該內存的開始;這是一個指針。 當您執行 a[x]
或a[i][j][k]
您將獲得指向a的第x個內存的指針。並且如果x大於12,它將在a之外並抓住那里的任何東西,並認為它是整數。 (雖然它可能是其他東西;這就是為什么當您執行這種操作時可能會產生垃圾,因為它實際上可能是其他東西,並且他們將其解釋為整數)。
多維數組存儲在內存中的連續內存位置,因此您的數組在內存中的外觀類似於:
1 2 3 4 5 6 7 8 9 10 11 12
由於C無法提供數組綁定檢查的方法,因此您可以在數組限制后訪問內存,甚至可以訪問未分配的內存( 有時會產生錯誤)。
訪問a [x] [y] [z]是使用x,y,z,值和相對於a的內存地址中數組a的大小來計算的(您可能知道,a是指向第一個元素的指針)在這種情況下,數組中為[[0] [0] [0])。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.