C语言 为什么一个指针+1加4实际上

0ve6wy6x  于 11个月前  发布在  其他
关注(0)|答案(6)|浏览(114)
#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实际上,为什么它会这样呢?

iyfamqjs

iyfamqjs1#

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

*(pointer + offset)

字符串
相当于

pointer[offset]


所以指针运算并不以字节为单位,而是以sizeof(pointer base type)字节大小的块为单位。

monwx1rj

monwx1rj2#

考虑一下指针是什么.它是一个内存地址.内存中的每个字节都有一个地址.所以,如果你有一个4字节的int,它的地址是1000,1001实际上是该int的第二个字节,1002是第三个字节,1003是第四个字节.由于int的大小可能因编译器而异,当你递增指针的时候,你不能得到int中某个中间点的地址,这是很重要的。所以,根据你的数据类型,计算出要跳过多少字节的工作是为你处理的,你可以使用你得到的任何值,而不用担心它。
正如Basile Starynkvitch所指出的,这个数量会根据指向的数据成员的sizeof属性而变化。很容易忘记,即使地址是顺序的,对象的指针也需要考虑容纳这些对象所需的实际内存空间。

gv8xihay

gv8xihay3#

指针算术是一个棘手的问题。指针加法意味着传递到下一个指针元素。所以地址增加sizeof指针元素。

huus2vyu

huus2vyu4#

简短回答

指针的地址将增加sizeof(T),其中T是指向的类型。因此对于int,指针将增加sizeof(int)
为什么
首先,这是标准要求的。这种行为之所以有用(除了与C兼容之外)是因为当你有一个使用连续内存的数据结构时,比如数组或std::vector,你可以通过简单地向指针添加1来移动到数组中的下一个元素。如果你想移动到容器中的第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*

qco9c6ql

qco9c6ql5#

指针是用来指向内存中一个特定的字节,这个字节标记了一个对象被分配的位置(从技术上讲,它可以指向任何地方,但这就是它的使用方式)。当你做指针运算时,它的操作基于所指向对象的大小。在你的例子中,它是一个指向整数的指针,每个整数的大小为4个字节。

inn6fuwd

inn6fuwd6#

让我们考虑一个指针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;
}

字符串

相关问题