C 中两个指针相减时

问题描述 投票:0回答:7

我正在玩指针,以便完全理解这个概念,然后想减去两个指针,期望这两个地址之间的距离或其他东西,但显然我错了,所以这是我的代码。

int x = 5, y = 7;
int *p = &y;
int *q = &x;
printf("p is %d\nq is %d\np - q is %d", p, q, (p - q));

为什么程序会输出

p - q is 1
?谢谢你。

c pointers
7个回答
19
投票

这是未定义的行为。根据标准(

N1570
):

6.5.6 加法运算符
....
9 当两个指针相减时,两个都指向同一个数组对象的元素, 或者超过数组对象的最后一个元素;结果是 的差异 两个数组元素的下标

请注意,如果允许,结果是 下标 差异。因此,如果指针指向同一类型的两个连续元素,则无论类型的大小如何,减法都会得到

1
。 (这也许就是您在具体案例中得到
1
的原因。)


5
投票

您的特殊情况是导致未定义行为的原因,因为

p
q
指向不相关的对象。

仅当

p-q
p
指向同一个数组/超过同一数组的最后一个元素时,您才能理解
q

int array[10];
int* p = &array[0];
int* q = &array[5];

ptrdiff_t diff1 = q - p;  // Valid. diff1 is 5
ptrdiff_t diff2 = p - q;  // Valid. diff2 is -5
在本例中,

q - p
为 5,因为它们指向数组中相距 5 个元素的元素。

换句话说,

p+5
等于
q
。如果从
p
开始,跨过数组的 5 个元素,您将指向
q
所指向的数组中的同一个元素。


顺便说一句,不要使用格式说明符

%d
来打印指针。使用
%p
。使用
%td
代替
ptrdiff_t

printf(" p is %p\n q is %p\n p-q is :%td", p, q, p-q);`
//            ^^        ^^

请参阅 http://en.cppreference.com/w/c/io/fprintf 了解不同类型的有效格式说明符。


2
投票

指针减法使用的公式是:

( p2 - p1 ) == ( addr( p2 ) - addr( p1 ) ) / sizeof( T )


其中

T

both p1
p2
 的类型。

int array[10]; int* p1 = array + 2; int* p2 = array + 5; int* a = p2 - p1; // == addr(array + 3) int* b = p1 - p2; // == addr(array - 3)
    

1
投票
指针算术就是这样工作的。它不会告诉您两个地址之间的差异。相反,它将显示两个变量之间的差异,就好像它们存储在数组中一样。因此,无论您的变量(相同类型)是 4 字节、8 字节还是 1 字节,如果存储在相邻的内存位置,它们的指针减法将始终导致 1 或 -1。


1
投票
2 个指针相减得出 2 个变量之间的距离。 例如。

//设a的地址为1000,则a+1的地址为1004

int a[]={1,2,3}; int *p1=a; int *p2=a+1; printf("%u",p2-p1);

结果将是 1 而不是 4。 在您的情况下,x 和 y 的位置是连续的,这就是 ans 的原因。是 1。


0
投票
int a=5,b=6; int *ptr=&a,*diff; diff=ptr; printf("%p\n",diff); ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++; printf("%p\n",ptr); printf("diff==%td\n",(ptr-diff)*sizeof(int));
(diff-ptr) 将提供两个变量之间的距离,但不会提供两个指针之间的内存间隙。
重要提示:只有相同类型的指针才能相减。


-1
投票
数组中两个指针相减即可得到两个元素之间的距离。

设第一个元素的地址为1000,那么第二个元素

a+1

的地址将为1004。因此
p1 = 1000
p2 =1004

p2-p1 = (1004- 1000) /size of int = (1004-1000)/4 =4/4 =1
    
© www.soinside.com 2019 - 2024. All rights reserved.