【问题标题】:Pointer arithmetic and address指针算术和地址
【发布时间】:2012-09-27 14:34:39
【问题描述】:

我遇到过这样的代码:

#include <stdio.h>

int main(void)
{
 int a[5] = { 1, 2, 3, 4, 5};
 int *ptr = (int*)(&a + 1);
 int *ptr2 = (int*) &a;
 ptr2 +=1 ;
 printf("%d %d %d \n", *(a + 1),*(ptr - 1) ,*ptr2 );
 return 0;
}

除了这一行之外,指针算法为我做了:

int *ptr = (int*)(&a + 1);

这是未定义的行为吗? 为什么我们在取消引用 *(ptr - 1) 时会得到 5

【问题讨论】:

  • int a[5] = { 1, 2, 3, 4, 5,6 }; 是一件非常糟糕的事情!
  • @jsn 我的错!问题中只有 5 个元素,我在这里复制代码之前做了一些奇怪的测试,我会更改它:) 但问题仍然存在。

标签: c pointers memory-address


【解决方案1】:

a 的大小为“5 ints”。所以&amp;a + 1 指的是a 的第一个内存位置过去,因为指针运算是以a 的大小为单位完成的。

【讨论】:

  • int *ptr = (int *)(&a[0] + 1); // 数组 a 的第二个元素
  • @RichardChambers 是吗?不确定这是否意味着反论点......因为+ 1 然后适用于&amp;a[0] 的结果,它的类型是普通的int
  • @unwind 我认为他将其发布为对 OP 的修复。
  • @unwind +1 解释得很好:)
  • @unwind 我已经理解了,但相反,为什么 *(a+1) 给出 2 ?这里 sizeof(a) 是 5 个整数,并且 a 也是指向第一个元素的指针,所以它不应该给我们未定义的行为,即超出范围吗? *(ptr - 1) 通过将 sizeof(ptr) 指定为 int 来证明是合理的。
【解决方案2】:

试试看!

int a[5] = {1, 2, 3, 4, 5};
printf("%#x, %#x, %#x, %#x\n", a, &a, a+1, &a+1);

0xbfa4038c, 0xbfa4038c, 0xbfa40390, 0xbfa403a0

那么这告诉我们什么?

0xbfa4038c == 0xbfa4038c 表示a == &amp;a。这是数组中第一个元素的地址或a[0]

我们知道 int 的大小是 4,而您知道 *(a+1) == a[1](数组中的第二个元素),这可以通过以下方式证明:

0xbfa4038c + 0x4 = 0xbfa40390 表示a + one int = address of the next element

因此,如果我们看到&amp;a+1 == 0xbfa403a0,这意味着我们有((0xa0-0x8c)/4) = 5 个元素进入数组。你知道a[5] 是无效的,所以这意味着我们已经通过了数组的末尾。

所以如果你采取:

int *ptr = (int*)(&a + 1); //one passed last element in the array
printf("%d",*(ptr - 1));//back up one, or last element in the array and deference

这就是你得到5的原因

【讨论】:

  • +1 明白了!我仍然有点困惑! a 和 &a 给出了地址,但两者都加 1 会给我们不同的结果。 &a+1 添加 5 个整数,因为 sizeof(a) 是 5*sizeof(int) 但为什么不是 a+1 ?
  • +1 是根据 TYPE 给地址加一。尝试this link作为您问题的答案(不是选择的答案,得票多的更清楚)
【解决方案3】:

对于类型为 T 的 n 个元素的数组,则第一个元素的地址类型为“指向 T 的指针”; the address of the whole array 具有类型“指向 T 类型的 n 个元素的数组的指针”;

int *ptr = (int*)(&a + 1); //&a-> address whole array, size=20 bytes, 
         //ptr=&a+1: next element =adress of a +20 bytes.
         //ptr - 1 = address of a +16 = address of last a's element = address of 5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    相关资源
    最近更新 更多