2016-03-07 121 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