2016-03-07 117 views
36

這是我的代碼:爲什麼m [1] - m [0]返回3,其中m是3x3矩陣?

int m[][3] = { 
       { 0 , 1 , 2 }, 
       { 10, 11, 12 }, 
       { 20, 21, 22 } 
      }; 
printf("%d %d\n", m[1] - m[0], m[1][0] - m[0][0]); 

?爲什麼

m[1] - m[0] 

回報3?我知道爲什麼第二個表達式會返回10,但是對我來說似乎並不合邏輯1 st

+2

'm [1]'是'&m [1] [0]'等等。 – immibis

+0

從技術上講,'m'不是一個3x3矩陣,而是一個數組。 – HelloGoodbye

+0

還沒有回答,但是'm [0]'和'm [1]'是*數組*(不是指針)。當數組被用作'-'運算符的操作數時,會產生一個指針值,它指向相應數組的第一個元素。 –

回答

55

在您的代碼:

m[1] - m[0] 

表示指針減法,讓你基於的類型的兩個指針的差異。在這種情況下,無論是指針由3個要素區分,所以結果是3。

引述C11標準,章§6.5.6

當兩個指針相減,既應指向元件相同的數組對象, 或一個過去的數組對象的最後一個元素;結果是兩個數組元素的 下標的差異。 [...]

[...]換句話說,如果表達式PQ指向,分別i和第j的第一個 元素數組對象,表達式(P)-(Q)的值爲i−j,前提是該值適合ptrdiff_t類型的對象。 [....]

爲了幫助更好地可視化,請參閱下面的圖像

enter image description here

這裏,s是一個二維陣列,被定義爲s[4][2]。考慮到數組使用者的數據類型爲每個2字節,請遵循元素(索引)和相應的內存位置(任意)。這將更好地說明內存中的實際情況,數組元素是連續的。

因此,根據該表示,s[0]s[1]通過兩個元素s[0][0]s[0][1]來區分。因此,s[1] - s[0]將產生2的結果。

+0

謝謝!這有助於我理解它。我會立即通過該測試:) – Martacus

+0

@Martacus這就是信心!祝您好運:) –

+1

請注意'm [1]'和'm [0]'是數組。你描述的指針是「衰減」的結果。 –

35

因爲m[1]m[0]之間的「差異」是三個要素。

這可能是更容易,如果你看它像這樣

 
m[0]       m[1]       m[2] 
|        |        | 
v        v        v 
+---------+---------+---------+---------+---------+---------+---------+---------+---------+ 
| m[0][0] | m[0][1] | m[0][2] | m[1][0] | m[1][1] | m[1][2] | m[2][0] | m[2][1] | m[2][2] | 
+---------+---------+---------+---------+---------+---------+---------+---------+---------+

m[1]m[0]之間的區別,瞭解是元素m[0][0]m[0][1]m[0][2]

+0

啊,是的,這也解釋了,謝謝!我現在得到了它的竅門哈哈。 – Martacus

+0

實際上,如果你用技術術語來看,'m [0]'在技術上將指向與m [0] [0]相同的位置。使用'&m [0]'和'&m [0] [0]'會證明;數組有一個基數和一個偏移量,所以'm [0]'和'm [0] [0]'都有零偏移量和一個等於基準地址的地址。 – cst1992

+0

我想說的是你應該把'm [0]'指向包含'm [0] [0]'的單元的中間,而不是開頭。 'm [1]'和'm [2]'同樣適用。 – cst1992