[英]C - Address difference between two columns of 3D array
對於以下C代碼段,
int a[2][3][2] = { { {1,2},{3,4},{5,6} },{{7,8},{9,10},{11,12} } };
printf("%d %d",a[1]-a[0],a[1][0]-a[0][0]);
這段代碼給出了輸出3 6
,但我沒有得到這個。
我可以將3D數組a[2][3][2]
可視化為兩個大小為3x2的2D
數組,其索引如下:
a[0][0]--> | 1 2 || 7 8 | <--a[1][0]
a[0|[1]--> | 3 4 || 9 10|
| 5 6 || 11 12|
a[0] a[1]
假設a[0]
地址為1000
則a[1]
地址將為1012
,假設int
大小為2個字節。 所以(a[1] - a[0])
應該是12,但它給出的3. 3實際上是矩陣中的行數。但是,為了得到行數,代碼應該是這樣的:
(a[1] -a[0])/(row_size *sizeof(int));
類似地,在a[1][0]-a[0][0]
。
我不明白這件事。 請解釋。 謝謝。
讓我們嘗試寫出數組在內存中的樣子:
+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+ | a[0][0][0] | a[0][0][1] | a[0][1][0] | a[0][1][1] | a[0][2][0] | a[0][2][1] | a[1][0][0] | a[1][0][1] | a[1][1][0] | a[1][1][1] | a[1][2][0] | a[1][2][1] | +------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+ ^ ^ ^ ^ | | | | a[0][0] a[0][1] a[0][2] a[1][0] | | a[0] a[1]
當你做a[1] - a[0]
你讓子數組衰減到指向第一個元素的指針,兩個指針之間的差異以它們的解引用類型為單位。
所以對於a[0]
(和a[1]
),類型是int [3][2]
。 它衰減到指向其第一個元素的指針,其類型為int (*)[2]
。 取消引用的指針將是int [2]
類型。 現在a[0]
和a[1]
之間a[0]
多少int [2]
a[1]
? 有三個這樣的元素,因此a[1] - a[0]
是3
。
如果我們取a[1][0] - a[0][0]
,則a[1][0]
和a[0][0]
都是int [2]
。 它衰減到一個int *
類型的指針,而dereferenced類型是int
。 並且在a[0][0]
和a[1][0]
之間有六個int
元素。
根據標准6.5.6p9,這是未定義的行為:
當減去兩個指針時,兩個指針都指向同一個數組對象的元素,或者指向數組對象的最后一個元素的元素; 結果是兩個數組元素的下標的差異。 結果的大小是實現定義的,它的類型(有符號整數類型)是在頭文件中定義的ptrdiff_t ...
問題是它會在大多數系統中產生預期的結果。 但是認為a[0]
和a[1]
將屬於同一個數組a
。 但是a[0][0]
和a[1][0]
屬於不同的數組對象,然后指針將指向違反上述規則的兩個不同的數組對象。 這就是未定義行為的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.