在C中减去两个指针时,

d4so4syb  于 11个月前  发布在  其他
关注(0)|答案(7)|浏览(83)

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

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?谢谢。

yws3nbqq

yws3nbqq1#

这是未定义的行为.根据标准(N1570):

6.5.6加法运算符

....
9当两个指针相减时,两个指针都 * 应指向同一数组对象的元素,或者指向数组对象 * 最后一个元素之后的一个元素;结果为 * 两个数组元素下标 * 的差。
请注意,如果允许,结果就是下标的差。因此,如果指针指向同一类型的两个连续元素,则无论该类型的大小如何,减法都将得到1。(这可能是在具体情况下得到1的原因。)

q1qsirdb

q1qsirdb2#

您的特殊情况是未定义行为的原因,因为pq指向不相关的对象。
只有当pq指向同一个数组/同一个数组的最后一个元素后的一个元素时,才能理解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

rqcrx0a6

rqcrx0a63#

公式used by pointer substraction为:
第一个月
Tp1p2的类型。

int array[10];
int* p1 = array + 2;
int* p2 = array + 5;

ptrdiff_t a = p2 - p1; // 3
ptrdiff_t b = p1 - p2; // -3

字符串

e0bqpujr

e0bqpujr4#

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

amrnrhlw

amrnrhlw5#

两个指针的减法给予两个变量之间的距离。
//假设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。

yquaqz18

yquaqz186#

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)将提供两个变量之间的距离,但不会提供两个指针之间的内存间隙。重要提示:只有相同类型的指针才能被减去。

tct7dpnv

tct7dpnv7#

数组中两个指针的相减将给予两个元素之间的距离。
设第一个元素的地址为1000,则第二个元素a+1的地址将为1004,因此p1 = 1000p2 =1004

p2-p1 = (1004- 1000) /size of int = (1004-1000)/4 =4/4 =1

字符串

相关问题