簡體   English   中英

在C中訪問多維數組

[英]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 例如,假設您的代碼中有ab ,當您在代碼中處理ab時,實際上ab只是一部分內存。 假設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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM