int * p = somearray但是(p + 1)不等于somearray [1]的地址。为什么?

时间:2017-09-24 17:15:49

标签: c pointers pointer-arithmetic

#include <stdio.h>

int main()
{
    int a[]={11,12,13},*p;
    printf("%x\n",a);

    for(int i=0;i<3;i++)
       printf("%x  ",(a+i));

    p=(&a)+1;    //LINE1
    printf("this is this %x\n",p); //LINE2
    printf("%d  ",*p);
    printf("%d\n",*(p-1));
    return 0;
}

LINE1上的指针运算后,为什么LINE2打印的地址不等于[1]?相反,还有4个字节的额外差异。

3 个答案:

答案 0 :(得分:4)

写作时

&a

您将获得数组a的地址。由于数组a的类型是int [3],因此该指针的类型为int (*) [3],指向三个整数数组的指针。

然后写下

&a + 1

你说的是“转到一个指向a的对象。”请记住,a的类型为int (*) [3],因此C将此解释为指向“指向三个int的数组之后的三个int的数组。 a“。因此,您将指向数组底部的3×sizeof(int)个字节,而不是您将找到元素a[1]的位置。

您可能应该从行

获得编译器警告
p = (&a) + 1

因为类型错误。指针pint *,右侧的表达式是int (*) [3]。使用高警告设置进行编译可能会提醒您某些错误的事实,这可能会让您知道某些事情并不完全正确。我建议继续使用高警告设置进行编译,因为这些天编译器标记的许多警告都是合法的问题。

您可以采取一些措施来解决此问题。一个是写

&a[0] + 1

表达式&a[0]表示“指向a的第一个元素的指针”并且类型为int *,因此当您向其添加一个时,C将此解释为“指向int之后的a[0] a[1]a + 1 生活的地方。

由于数组到指针的衰减,你也可以写

a

因为C将表达式a解释为指向&a[0]的第一个元素的指针(即&a)。

总结:

  • 指针运算取决于基础类型的大小。
  • 'Guerre Stellari / Star Wars (1977)'.replace(/.*?\/\s+/, '') 为您提供指向元素数组的指针,而不是指向数组第一个元素的指针。地址相同,但类型不同。

答案 1 :(得分:1)

对于指针运算,您应该知道指针的类型。 现在这里是一个指向3个元素的整数数组的指针。 即a的数据类型是int(*)[3]。

每当你向a添加1时,它将指向3个整数后的下一个内存位置。 指针类型&amp;(a [0])是int *。

希望这能解决您的问题。

答案 2 :(得分:0)

您需要对数组的元素使用指针算法: a已经是int *所以你有两个选择:

    p=(&a[0])+1;    //LINE1

    p=a+1;    //LINE1