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]
是数组(不是指针)。当数组用作-
运算符的操作数时,将生成指针值,该运算符指向相应数组的第一个元素。