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

int *p=somearray but (p+1) is not equal to address of somearray[1]. Why?

#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打印的地址不等于a[1]?相反,还有 4 个字节的额外差异。

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

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

    p=a+1;    //LINE1

写的时候

&a

您正在获取数组 a 的地址。由于数组a的类型是int [3],所以这个指针的类型是int (*) [3],一个指向三个整数数组的指针。

当你再写

&a + 1

你说的是 "go to the object one past the one pointed at a." 请记住 a 的类型是 int (*) [3],所以 C 将其解释为指向 "point at the array of three ints that comes after the array of three ints pointed at by a." 结果,你将指向 3 × sizeof(int) 字节超出数组的底部,这不是您可以找到元素 a[1].

的地方

您可能应该从

行收到编译器警告
p = (&a) + 1

因为类型不对。指针 p 是一个 int *,右侧的表达式的类型为 int (*) [3]。使用高警告设置编译可能会提醒您 something 是错误的,这可能会提示您这里有些地方不太对劲。我建议以后使用高警告设置进行编译,因为如今编译器标记的许多警告都是合理的问题。

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

&a[0] + 1

表达式 &a[0] 表示 "a pointer to the first element of a" 并且具有类型 int *,因此当您向其添加一个时,C 将其解释为“指向下一个 inta[0] 之后,即 a[1] 居住的地方。

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

a + 1

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

总结一下:

  • 指针运算取决于基础类型的大小。
  • &a 给你一个指向元素数组的指针,而不是指向数组第一个元素的指针。地址相同,但类型不同

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

无论什么时候给a加1,它都会指向3个整数后的下一个内存位置。 指针 &(a[0]) 的类型是 int *.

希望这能解决您的问题。