【问题标题】:Subtracting addresses in a 3d array减去 3d 数组中的地址
【发布时间】:2023-03-16 08:10:02
【问题描述】:

我创建了一个 3d 数组

a[2][3][2]

现在当我尝试打印时

printf("%d",a[1] - a[0]);

我得到 3 作为输出。

我的理解是 a[1] 给了我 a[1][0][0] 元素的地址,a[0] 给了我 a[0][0][0] 的地址。

设 a[0][0][0] 的地址为 BA,则 a[1][0][0] 的地址为 BA + 4*2*3 其中 4 字节是整数数据类型的内存空间

我期望结果是 6。

我也试过了

printf("%d",(&a + 1) - &a);

收到的输出是 1。

我哪里错了?

编辑 1:整个代码

#include<stdio.h>

int main(){
    int a[2][3][2] = {{{1,2},{3,4},{5,6}},{{7,8},{9,10},{11,12}}};
    printf("%d",a[1]-a[0]);
    return 0;
}

【问题讨论】:

  • printf("%d",a[1] - a[0]); ----> printf("%p", (void *)(a[1] - a[0]));
  • 提供完整的代码,你会做什么?
  • a[1] 给你一个指向a[1][0] 的指针,现在它与a[1][0][0] 具有相同的地址,但它的类型是pointer to array of 2 xxx
  • @LPs - 这是错误的。指针减法的结果(这是你在所有衰减之后得到的)是一个 ptrdiff_t,而不是另一个指针。

标签: c dev-c++


【解决方案1】:

让我们把表达式a[1] - a[0]拆开:

a[1] - 引用第二个 [3][2] 数组。
a[0] - 引用第一个 [3][2] 数组。

现在,当大多数上下文中使用数组时,它们会衰减为指向第一个元素的指针。所以a[i] 将衰减为指向二维数组int(*)[2] 的指针。

按照指针算法的规定,在sizeof(int[2]) 中计算差异。并且可以看到[a[0], a[1])范围内有3个int[2]单位。

【讨论】:

  • 感谢您打破和简化。我是指针和地址的新手,因此它真的很有帮助
  • a[1] 和 [0] 指向两个独立的对象。如 6.5.6 §8 中所述,行为未定义一些类似的附加推理:stackoverflow.com/a/6291590/4082723,如果我不清楚的话。
  • @2501 a[1] 衰减到 a[0] 末尾之后的指针。算术定义明确。
  • @2501 - 如果我的保证还不够,您可以咨询 6.5.6/9。
  • 你提到的规则是:当两个指针相减时,两个指针都指向同一个数组对象的元素,或者指向数组对象最后一个元素的元素。指针 a[1] 和 a[0] 不属于同一个数组对象。它们每个都指向一个单独的数组,它们都恰好属于另一个数组a,但这并不能使它们成为同一个数组对象。
【解决方案2】:

我的理解是 a[1] 给了我 a[1][0][0] 元素的地址,a[0] 给了我 a[0][0][0] 的地址。

这是错误的a[0] 会给出第一个二维数组的地址。第一个二维数组的地址和a[0][0][0]的地址可能重合,但并不相同。

具体&amp;a +1不等于&amp;a[0][0][0] +1

【讨论】:

  • 如果您将“指针”(具有类型)和“地址”(它们只是地址)区分开来,这个答案会更好。因此,我将其表述为 addresses 相同 - 但类型不同(因此减法不同)。
  • @Rishikesh Raje 是的,我知道 &a + 1 会给我 3d 数组之后的内存位置的地址,即 &a[2][3][2] + 1。但它会出现 1因为它会在减法中考虑数组 a 的完整大小?类似 if ((BA + 2*3*2*4)-BA))/sizeof(a)
猜你喜欢
  • 2015-01-26
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
  • 2011-06-09
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
相关资源
最近更新 更多