C 为什么m[1]-m[0]返回3,其中m是3x3矩阵?

C 为什么m[1]-m[0]返回3,其中m是3x3矩阵?,c,arrays,matrix,C,Arrays,Matrix,这是我的代码: 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,但我觉得第一个表达式不符合逻辑。在您的代码中: m[1

这是我的代码:

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
,但我觉得第一个表达式不符合逻辑。

在您的代码中:

 m[1] - m[0]
表示一个指针减法,它根据类型给出两个指针的差。在本例中,两个指针由3个元素区分,因此结果为3

引用标准第§6.5.6章

减去两个指针时,两个指针都应指向同一数组对象的元素, 或超过数组对象最后一个元素一次;结果是两个参数的差异 两个数组元素的下标。[……]

[…]换句话说,如果表达式
p
Q
分别指向 一个数组对象,表达式
(P)-(Q)
的值为
i−j
前提是该值适合
ptrdiff\u t
类型的对象。[……]

为了更好地可视化,请参见下图

这里,
s
是一个二维数组,定义为
s[4][2]
。考虑到数组使用者的数据类型,每个2字节,请遵循元素(索引)和相应的内存位置(任意)。这将更好地理解数组元素在内存中是如何连续的

因此,根据表示,
s[0]
s[1]
由两个元素区分,
s[0][0]
s[0][1]
。因此,
s[1]-s[0]
将产生2的结果。

因为
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[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]| +---------+---------+---------+---------+---------+---------+---------+---------+---------+
m[1]
m[0]
之间的区别在于三个元素
m[0][0]
m[0][1]
m[0][2]
,谢谢!这有助于我理解它。我现在肯定会通过测试:)@Martacus这就是信心!!祝您好运:)请注意
m[1]
m[0]
都是数组。你描述的指针是“衰变”的结果。啊,是的,这也进一步解释了它,谢谢!我现在掌握了窍门哈哈。实际上,如果你从技术角度来看,
m[0]
从技术上讲将指向与
m[0][0]
相同的位置。使用
&m[0]
&m[0][0]
将证明这一点;数组有一个基址和一个偏移量,因此
m[0]
m[0][0]
都有零偏移量和一个等于matix基址的地址。我想说的是,你应该将
m[0]
指向包含
m[0][0]
的单元格的中间,而不是开始。这同样适用于
m[1]
m[2]
m[1]
&m[1][0]
等等。从技术上讲,
m
不是一个3x3矩阵,而是一个数组。目前还没有答案提到这一点,但
m[0]
m[1]
是数组(不是指针)。当数组用作
-
运算符的操作数时,将生成指针值,该运算符指向相应数组的第一个元素。