2012-12-25 155 views
4

爲什麼在C/C++中需要一個接收MD arr的func參數,使其具有所有子陣列/維度的大小?在C/C++中傳遞多維數組

here(PDF):它說MD ARRS的唯一的區別是 「編譯器會記住每一個虛數維」,但是當我違反這些尺寸的編譯器不執行任何操作,如:

char arr[3][5]; 
arr[0][5] = 10; 

那麼,什麼是記憶點那些尺寸?

回答

7

對數組的索引訪問必須根據索引值以行優先級順序計算內存偏移量計算,並聲明較差的維度。更多關於這一點。

但首先,你的問題是密切相關的這個簡單的觀察:

void foo(char a[]) 
{ 
    a[5] = 'a'; 
} 

// caller of foo() from somewhere 
char arr[5]; 
foo(arr); 

爲什麼編譯器讓你做?因爲這是C,而且你完全有權利用未定義的行爲來拍攝自己的腳。牢記這一點:

void foo(char a[][5]) 
{ 
    a[0][5] = 'a'; 
} 

// caller of foo() from somewhere 
char arr[4][5]; 
foo(arr); 

它只是爲「有效」如現有的代碼(即您在您自己的風險和危險進入UB右內準備得很好)。在這種情況下,它將「工作」,但僅僅是因爲底層數組的線性背景寬度爲20個元素,並且我們只訪問第六個元素,技術上它是arr[1][0]

那些劣尺寸的目的是正確地計算像訪問此

void foo(char a[][5]) 
{ 
    a[2][1] = 'b'; 
} 

2優良指數必須使用聲明下尺寸(在這種情況下5)有效地計算出的線性偏移正確的元素。鋪設在一維線性嵌段2D陣列,它被用於執行此操作:

char arr[20]; // 4*5 
arr[2*5+1] = 'b'; 

注意5。它是所宣稱的劣勢,必須知道它能夠正確地計算跳躍(詞性)。

我希望至少能讓它更清楚一點。

我應該注意到這個化合物。即以下:

char arr[3][4][5]; 
arr[1][2][3] = 'c'; 

有效地計算在針對基礎陣列的線性背景正確的位置:

char arr[60]; // 3*4*5 
arr[ 1*(4*5) + 2*(5) + 3 ] = 'c'; 

等。根據你的願望,儘可能多的維度。必須知道所有劣等維度才能正確執行此操作。

2

數組不是一種特殊的對象,它只是一長串項目。您的arr[3][5]實際上只是一個arr[15],然後arr[0][5]被編譯器重定向到arr[5]

由於C/C++不存儲大小,需要硬編碼他們正確地做出[0][5]地圖[5]

一些編譯器可能執行[0][5]是錯誤(或警告),但因爲其映射爲[5],它會做至少東西。

+0

我明白了, TYPE arr [S1] [S2] arr [x] [y] = *(arr +(x * S2)+ y) – MTVS