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

时间:2016-07-21 20:19:24

标签: c pointers pointer-arithmetic

指针存储指向值的内存地址,因此指针包含的内存地址与值的内存地址相同。因此,向这两个内存地址添加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

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

3 个答案:

答案 0 :(得分:7)

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

所以当你这样做时:

&ages+1

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

同样,当你这样做时:

cur_ages+1

此处,cur_ages指向int,因此添加1会将sizeof(int)添加到指针值。

答案 1 :(得分:3)

& cur_ages是cur_ages存储在堆栈中的地址。由于& cur_ages + 1大8,我认为这是在64位模式下完成的,其中指针的大小是8个字节。

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

示例代码不打印年龄和年龄+ 1,这将因sizeof(int)而不是5 * sizeof(int)而不同。没有&年龄前缀,数组的大小无关紧要。

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

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

答案 2 :(得分:2)

这里发生了一些事情。

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