對多維數組的一維訪問:它是明確定義的行為嗎?我想我們都同意,通過以一維方式解引用(可能是偏移的)指向其第一個元素的指針來訪問真正的多維數組被認為是慣用的C,例如:void clearBottomRightElement(int *array, int M, int N){ array[M*N-1] = 0; // Pretend the array is one-dimensional}int mtx[5][3];...clearBottomRightElement(&mtx[0][0], 5, 3);然而,我的語言律師需要說服這實際上是明確定義的C!特別是:是否標準保證編譯器不會把填充例如,在中間mtx[0][2]和mtx[1][0]?通常,索引關閉數組的末尾(除了結尾之外)是未定義的(C99,6.5.6 / 8)。所以以下內容顯然是未定義的:struct { int row[3]; // The object in question is an int[3] int other[10];} foo;int *p = &foo.row[7]; // ERROR: A crude attempt to get &foo.other[4];因此,根據相同的規則,人們會期望以下內容未定義:int mtx[5][3];int (*row)[3] = &mtx[0]; // The object in question is still an int[3]int *p = &(*row)[7]; // Why is this any better?那為什么要定義呢?int mtx[5][3];int *p = &(&mtx[0][0])[7];那么C標準的哪一部分明確允許這個?(為了討論,我們假設是c99。)請注意,我毫不懷疑這在所有編譯器中都能正常工作。我要查詢的是標準是否明確允許這樣做。
3 回答

滄海一幻覺
TA貢獻1824條經驗 獲得超5個贊
您想要進行訪問的唯一障礙是類型對象int [5][3]
并且int [15]
不允許彼此別名。因此,如果編譯器意識到類型的指針指向前者的int *
一個int [3]
數組,則它可能會施加數組邊界限制,從而阻止訪問該int [3]
數組之外的任何內容。
您可以通過將所有內容放在包含int [5][3]
數組和int [15]
數組的聯合內部來解決此問題,但是我真的不清楚聯合黑客是否會將人們用于類型懲罰實際上是明確定義的。這種情況可能稍微有點問題,因為你不會打字單個單元格,只有數組邏輯,但我仍然不確定。
應該注意的一個特殊情況是:如果您的類型是unsigned char
(或任何char
類型),那么將多維數組作為一維數組訪問將是非常明確的。這是因為unsigned char
與標準重疊的一維數組被標準明確定義為對象的“表示”,并且本質上允許對其進行別名。
- 3 回答
- 0 關注
- 554 瀏覽
添加回答
舉報
0/150
提交
取消