#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实际上,为什么它会这样呢?
6条答案
按热度按时间iyfamqjs1#
因为指针被设计成与数组兼容:
字符串
相当于
型
所以指针运算并不以字节为单位,而是以
sizeof(pointer base type)
字节大小的块为单位。monwx1rj2#
考虑一下指针是什么.它是一个内存地址.内存中的每个字节都有一个地址.所以,如果你有一个4字节的
int
,它的地址是1000,1001实际上是该int
的第二个字节,1002是第三个字节,1003是第四个字节.由于int
的大小可能因编译器而异,当你递增指针的时候,你不能得到int
中某个中间点的地址,这是很重要的。所以,根据你的数据类型,计算出要跳过多少字节的工作是为你处理的,你可以使用你得到的任何值,而不用担心它。正如Basile Starynkvitch所指出的,这个数量会根据指向的数据成员的
sizeof
属性而变化。很容易忘记,即使地址是顺序的,对象的指针也需要考虑容纳这些对象所需的实际内存空间。gv8xihay3#
指针算术是一个棘手的问题。指针加法意味着传递到下一个指针元素。所以地址增加
sizeof
指针元素。huus2vyu4#
简短回答
指针的地址将增加
sizeof(T)
,其中T
是指向的类型。因此对于int
,指针将增加sizeof(int)
。为什么
首先,这是标准要求的。这种行为之所以有用(除了与C兼容之外)是因为当你有一个使用连续内存的数据结构时,比如数组或
std::vector
,你可以通过简单地向指针添加1来移动到数组中的下一个元素。如果你想移动到容器中的第n个元素,你只需要添加n。能够编写
firstAddress + 2
比firstAddress + (sizeof(T) * 2)
简单得多,并且有助于防止开发人员假设sizeof(int)
是4(可能不是)并编写类似firstAddress + (4 * 2)
的代码而产生的错误。实际上,当你说
myArray[4]
时,你说的是myArray + 4
。这就是数组索引从0开始的原因;你只需要添加0来获得第一个元素(即myArray指向数组的第一个元素)和n来获得第n个元素。如果我想一次移动一个字节怎么办?
sizeof(char)
的大小保证为一个字节,所以如果你真的想一次移动一个字节,你可以使用char*
。qco9c6ql5#
指针是用来指向内存中一个特定的字节,这个字节标记了一个对象被分配的位置(从技术上讲,它可以指向任何地方,但这就是它的使用方式)。当你做指针运算时,它的操作基于所指向对象的大小。在你的例子中,它是一个指向整数的指针,每个整数的大小为4个字节。
inn6fuwd6#
让我们考虑一个指针
p
。表达式p+n
类似于(unsigned char *)p + n * sizeof *p
(因为sizeof(unsigned char) == 1
)。试试这个:字符串