33
#include<stdio.h>
int main(void){
  int *ptr,a,b;
  a = ptr;
  b = ptr + 1;
  printf("the vale of a,b is %x and %x respectively",a,b);

  int c,d;
  c = 0xff;
  d = c + 1;
  printf("the value of c d are %x and %x respectively",c,d);
  return 0;
}

输出值为

the vale of a,b is 57550c90 and 57550c94 respectively
the value of c d are ff and 100 respectively%  

事实证明 ptr + 1 实际上,为什么它会这样?

4

6 回答 6

47

因为指针被设计为与数组兼容:

*(pointer + offset)

相当于

pointer[offset]

因此,指针算法在字节方面不起作用,而是在sizeof(pointer base type)-bytes 大小的块方面起作用。

于 2012-07-22T07:06:16.430 回答
36

考虑一下指针是什么……它是一个内存地址。内存中的每个字节都有一个地址。所以,如果你有一个int4 字节的地址,它的地址是 1000,那么 1001 实际上是它的第二个字节,int而 1002 是第三个字节,而 1003 是第四个。由于 an 的大小int可能因编译器而异,因此当您增加指针时,您不能获得int. 因此,根据您的数据类型确定要跳过多少字节的工作已为您处理,您可以使用您获得的任何值而不必担心。

正如 Basile Starynkvitch 指出的那样,这个数量将根据sizeof指向的数据成员的属性而有所不同。很容易忘记,即使地址是连续的,对象的指针也需要考虑容纳这些对象所需的实际内存空间。

于 2012-07-22T07:10:32.730 回答
8

指针算术是一门棘手的学科。指针添加意味着传递到下一个指向的元素。所以地址由sizeof 指向的元素递增。

于 2012-07-22T07:08:20.683 回答
5

简短的回答

指针的地址将增加指向类型的sizeof(T)位置T。所以对于int,指针将增加sizeof(int)

为什么?

首先,标准要求它。std::vector这种行为有用的原因(除了与 C 的兼容性)是因为当您有一个使用连续内存的数据结构时,例如数组或. 如果要移动到容器中的第 n 个项目,只需添加 n。

能够编写firstAddress + 2要比. firstAddress + (sizeof(T) * 2)_sizeof(int)firstAddress + (4 * 2)

实际上,当您说 时myArray[4],您就是在说myArray + 4。这就是数组索引从 0 开始的原因;您只需添加 0 即可获得第一个元素(即 myArray 指向数组的第一个元素),添加 n 即可获得第 n 个元素。

如果我想一次移动一个字节怎么办?

sizeof(char)保证大小为一个字节,因此char*如果您真的想一次移动一个字节,可以使用 a 。

于 2015-06-09T21:55:12.730 回答
2

指针用于指向一个特定字节的内存标记,该字节标记了一个对象已分配的位置(从技术上讲,它可以指向任何地方,但这就是它的使用方式)。当您进行指针运算时,它会根据指向的对象的大小进行操作。在您的情况下,它是一个指向整数的指针,每个整数的大小为 4 个字节。

于 2012-07-22T07:07:07.163 回答
1

让我们考虑一个指针p。表达式p+n就像 (unsigned char *)p + n * sizeof *p(因为sizeof(unsigned char) == 1)。试试这个 :

#include <stdio.h>
#define N   3

int
main(void)
{
    int i;
    int *p = &i;
    printf("%p\n", (void *)p);
    printf("%p\n", (void *)(p + N));
    printf("%p\n", (void *)((unsigned char *)p + N * sizeof *p));
    return 0;
}
于 2012-07-22T12:23:08.047 回答