簡體   English   中英

標准是否定義了`a [i]`的類型,其中`a`是`T [M] [N]`?

[英]Does the standard define the type for `a[i]` where `a` is `T [M][N]`?

我偶爾會使用多維數組,並且很好奇標准所說的(C11和/或C ++ 11)索引的行為,其“維度”小於為數組聲明的索引。

鑒於:

int a[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};

標准是說a[1]是什么類型,還是a[0][1] ,它是否合法,是否應該按預期正確地索引子數組?

auto& b = a[1];

std::cout << b[1][1];

m[1]只是int[2][2] 同樣, m[0][1]只是int[2] 是的,作為子數組的索引按照您的想法運行。

標准是否定義a[i]的類型,其中aT [M][N]

當然。 該標准基本上定義了所有表達式的類型,如果不是,則它將是缺陷報告。 但我想你對這種類型更感興趣......

雖然標准可能沒有明確提到你的情況,但規則是陳述的並且很簡單,給定類型為TN元素的數組a ,表達式a[0]是類型T的左值表達式。 在變量聲明int a[2][2]中, a 的類型是兩個類型為int的兩個元素的數組元素的數組 ,它應用上面的規則意味着a[0]一個2元素數組的左值 ,或者你必須在程序中輸入它: int (&)[2] 添加額外的維度不會影響機制。

我認為C11中的這個例子含蓄地解釋了它。

C11 6.5.2.1數組下標

示例考慮由聲明int x[3][5];定義的數組對象int x[3][5]; 這里x是3×5的整數數組; 更確切地說, x是一個由三個元素對象組成的數組,每個元素對象是一個由五個整數組成的數組。 在表達式x[i] ,它等價於(*((x) + (i)))x首先被轉換為指向五個int的初始數組的指針。 然后根據x的類型調整i ,這在概念上需要將i乘以指針所指向的對象的大小,即五個int對象的數組。 添加結果並應用間接以產生五個整數的數組。 當在表達式x[i][j] ,該數組又被轉換為指向第一個int的指針,因此x[i][j]產生一個int

類似的是在C ++ 11 8.3.4數組中

示例:考慮

 int x[3][5]; 

這里x是3×5的整數數組。 x出現在表達式中時,它將轉換為指向(三個中的第一個)五元數組整數的指針。 在表達式x[i] ,它等價於*(x + i)x首先被轉換為如上所述的指針; 然后將x + i轉換為x的類型,其涉及將i乘以指針所指向的對象的長度,即五個整數對象。 添加結果並應用間接以產生一個數組(五個整數),然后將其轉換為指向第一個整數的指針。 如果有另一個下標,則同一參數再次適用; 這次結果是一個整數。 - 末端示例] - 尾注]

要記住的關鍵點是,在C和C ++中,多維數組只是一個數組數組(因此三維數組是數組數組的數組)。 多維數組的所有語法和語義都遵循它(當然還有語言的其他規則)。

所以給定一個對象定義:

int m[2][2][2];

mint[2][2][2]類型的對象(兩個數組的數組,每個數組由兩個元素組成,每個元素由兩個元素組成,每個元素都是兩個int的數組) 。

當你寫m[1][1][1] ,你已經在評估mm[1]m[1][1]

表達式m是一個引用int[2][2][2]類型的數組對象的左值。

m[1] ,數組表達式m被隱式轉換為(“衰減”)指向數組第一個元素的指針。 該指針的類型為int(*)[2][2] ,指向int的雙元素數組的雙元素數組。 根據定義, m[1]相當於*(m+1) ; +1m前進一個元素並取消引用結果指針值。 因此m[1]引用int[2][2]類型的對象(兩個數組的數組,每個數組由兩個int元素組成)。

(數組索引operator []被定義為對指針而不是數組進行操作。在像arr[42]這樣的常見情況下,指針恰好是隱式數組到指針轉換的結果。)

我們重復m[1][1] ,給我們一個指向兩個intint(*)[2]類型int(*)[2]數組的指針。

最后, m[1][1][1]得到了評估m[1][1]並再次重復該過程,給出了一個引用int類型對象的左值。 這就是多維數組的工作原理。

只是添加到輕浮,像foo[index1][index2][index3]這樣的表達式可以直接使用指針和數組。 這意味着您可以使用指針和任意大小的分配來構造一些(幾乎)像真正的多維數組一樣的東西。 這使您可以在每行中使用“不規則”數組,其中包含不同數量的元素,甚至是缺少的行和元素。 但是,由您來管理每一行的分配和釋放,甚至是每個元素。

推薦閱讀: comp.lang.c FAQ的第6部分。

旁注:有些語言中多維數組不是數組數組。 例如,在Ada中(使用括號而不是方括號進行數組索引),您可以擁有一個數組數組,索引類似於arr(i)(j) ,或者您可以擁有一個二維數組,索引類似於arr(i, j) C不同; C沒有對多維數組的直接內置支持,但它為您提供了自己構建它們的工具。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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