为什么指针 +1 包含的内存地址与指向的值的地址 +1 不同

Why memory address contained by pointer +1 is different from address of value being pointed + 1

指针存储的是所指向的值的内存地址,因此指针包含的内存地址与值的内存地址相同。因此,向这两个内存地址加 1 应该会产生相同的结果,但这并没有发生。为什么? 这是代码

 int main()
 {
     int ages[] = {23, 43, 12, 89, 2};
     int *cur_ages = ages;

     printf("\n&cur_ages=%p, &cur_ages+1=%p", &cur_ages, &cur_ages+1);
     printf("\n&ages=%p, &ages+1=%p", &ages, &ages+1);
     printf("\ncur_ages=%p, cur_ages+1=%p", cur_ages, cur_ages+1);
     printf("\n*cur_ages=%d, *cur_ages+1=%d", *cur_ages, *(cur_ages+1));

     return 0;
 }

输出为

&cur_ages=0x1ffff85f3d0, &cur_ages+1=0x1ffff85f3d8
&ages=0x1ffff85f3dc, &ages+1=0x1ffff85f3f0
cur_ages=0x1ffff85f3dc, cur_ages+1=0x1ffff85f3e0
*cur_ages=23, *cur_ages+1=43

&ages+1 不等于 cur_ages+1。为什么?

这里发生了几件事。

  1. &cur_ages是指向一个值的指针的地址,而不是一个值的地址。因为C中的(arguably odd) semantics of array names&ages是一个值的地址。
  2. 指针运算 (&<anything>+1) 按整个项目而不是按字节计算。因此,将 1 添加到 int * 将添加 sizeof(int) 个字节,而不是一个字节。

指针算法将指针的值增加给定值乘以它指向的类型的大小。

所以当你这样做时:

&ages+1

您获取 ages 的地址(类型为 int [5])并将 sizeof(ages) 添加到指针值。假设 sizeof(int) 是 4,这会将指针值加 20。

同样,当您这样做时:

cur_ages+1

这里,cur_ages指向一个int,所以指针值加1就是sizeof(int)

&cur_ages是cur_ages入栈的地址。由于 &cur_ages+1 大于 8,我假设这是在指针大小为 8 字节的 64 位模式下完成的。

&ages 类似于声明 int (*ptr_to_ages)[5],其中 ptr_to_ages 是指向 5 个整数的数组的指针,它可以是指向数组第一行的指针矩阵,其中每行是 5 个整数的数组。 &ages = 存储数组第一个成员的地址。正如 dbush 的回答中提到的,由于 ages 是 5 个整数的数组,那么 &ages+1 指向 ages 中 5 个整数之后的 5 个整数的数组,所以 + 5 * 4,其中 4 是整数的大小,实际上与指向矩阵第二行的指针相同,其中每一行都是 5 个整数的数组。

示例代码不会打印出 ages 和 ages+1,它们的区别在于 sizeof(int) 而不是 5 * sizeof(int)。如果年龄上没有 & 前缀,数组的大小将无关紧要。

cur_ages 和 cur_ages+1 指向年龄中的第一个和第二个整数,正如预期的那样。

*cur_ages 和 *(cur_ages+1) 是 ages 中的第一个和第二个整数值。