【问题标题】:Subtracting pointers why is 4227140 - 4227136 = 1?减去指针为什么是 4227140 - 4227136 = 1?
【发布时间】:2021-03-24 19:46:56
【问题描述】:

This 文档中关于指向数组中单元格的指针的内容如下:

如果表达式 P 指向数组对象的第 i 个元素,则 表达式 (P)+N(等价于 N+(P))和 (P)-N(其中 N 具有 值 n) 分别指向 数组对象,前提是它们存在。

我有一个这样声明的数组:

static int heap [MANY];

我输出指向堆的指针:

printf("heap = %ld\n", heap);

输出显示如下:

heap = 4227136

那是指向heap[0] 的指针,对吧?

接下来,我输出指向heap[1]的指针:

printf("heap + 1 = %ld\n", (heap+1));

根据上面的引用,我预计指针的值1 大于4227136,即,我预计指针的值4227137。看到指针比4227136多了4,我很惊讶:

heap + 1 = 4227140

为什么指向heap[1]4的指针比指向heap[0]的指针多?

然后我尝试减去指针:我从heap[1] 中减去heap[0]

printf("(heap+1) - heap = %d\n", ((heap+1)-heap));

我希望输出是:4227140 - 4227136 = 4

相反,我得到了1的答案:

(heap+1) - heap = 1

我很困惑。为什么我会得到这些结果?

【问题讨论】:

  • 指针加减在粒度上对应类型的sizeof
  • I expected, based on the quote above, that the pointer would have a value 1 more than 4227136 Why? 上面特别写着point to, respectively, the i+n-th and i-n-th elements of the array objecti + 1'th 元素不在地址 i + 1 而是在 i + sizeof(int)
  • 如果您想要整数数学,请使用 整数。将指针视为整数存在缺陷。指针加法/减法只是众多此类漏洞之一。做printf("heap = %ld\n", heap);也是UB。指针不是整数不是指针。

标签: arrays c pointers pointer-arithmetic


【解决方案1】:

因为sizeof (int) 在您的机器上是 4 个字节。 heap+1 指向下一个元素。不是字节。

运算符[] 是指针运算的简单语法糖。 a[1]*(a+1) 相同。这有一个有趣的结果,a[1]1[a] 相同。

【讨论】:

    【解决方案2】:

    完整(即非void)指针根据指向类型的大小递增。

    考虑一下,如果您的系统上有sizeof(int) == 4,并且您有一个指向int 数组的指针,例如int data[] = {1, 2, 3, 4, 5}; int *p = data;,您希望用*(p + 1) 取消引用什么?元素 sizeof(int) 向上字节,而不是下一个字节。

    【讨论】:

      【解决方案3】:

      考虑到您的报价,&heap[0]heap + 0 指向数组的第一个元素,而 &heap[1]heap + 1 指向数组的第二个元素。

      所以( heap + 1 ) - ( heap + 0 ) 等于1。也就是指向同一个数组元素的两个指针的差等于指针之间的元素个数(正数或负数)。

      另一方面,由于heap + 1 指向数组的第二个元素,则指针中存储的地址与数组的第一个元素的地址相差sizeof( heap[0] ) 值或相同在您的情况下,值 sizeof( int ) 等于 4

      【讨论】:

        猜你喜欢
        • 2011-02-03
        • 1970-01-01
        • 2021-12-01
        相关资源
        最近更新 更多