为什么指针+ 1实际上加4

#include 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 cd are %x and %x respectively",c,d); return 0; } 

输出值是

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

事实certificate,ptr + 1实际上是这样的?

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

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

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

 *(pointer + offset) 

相当于

 pointer[offset] 

因此,指针aritmetic在字节方面不起作用,但在sizeof(pointer base type)字节大小的块方面。

你真的应该花时间阅读一本好的C编程语言书(比如K&R“C编程语言” )

指针算术是一个棘手的主题。 指针添加意味着传递给下一个指向的元素。 因此地址增加了指向元素的sizeof

简短的回答

指针的地址将增加sizeof(T) ,其中T是指向的类型。 因此对于int ,指针将增加sizeof(int)

为什么?

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

能够编写firstAddress + 2firstAddress + (sizeof(T) * 2)简单得多,并且有助于防止开发人员假设sizeof(int)为4(可能不是)并编写类似firstAddress + (4 * 2)

事实上,当你说myArray[4] ,你说的是myArray + 4 。 这就是数组索引从0开始的原因; 你只需要加0来得到第一个元素(即myArray指向数组的第一个元素),然后n得到第n个元素。

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

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

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

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

 #include  #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; }