为了完全理解这个概念,我使用了指针,然后想减去两个指针,期望这两个地址之间的距离或其他东西,但显然我错了,所以这是我的代码。
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?谢谢。
p - q is 1
yws3nbqq1#
这是未定义的行为.根据标准(N1570):
N1570
6.5.6加法运算符
....9当两个指针相减时,两个指针都 * 应指向同一数组对象的元素,或者指向数组对象 * 最后一个元素之后的一个元素;结果为 * 两个数组元素下标 * 的差。请注意,如果允许,结果就是下标的差。因此,如果指针指向同一类型的两个连续元素,则无论该类型的大小如何,减法都将得到1。(这可能是在具体情况下得到1的原因。)
1
q1qsirdb2#
您的特殊情况是未定义行为的原因,因为p和q指向不相关的对象。只有当p和q指向同一个数组/同一个数组的最后一个元素后的一个元素时,才能理解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。
q - p
p+5
%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。
rqcrx0a63#
公式used by pointer substraction为:第一个月T是p1和p2的类型。
T
p1
p2
int array[10]; int* p1 = array + 2; int* p2 = array + 5; ptrdiff_t a = p2 - p1; // 3 ptrdiff_t b = p1 - p2; // -3
字符串
e0bqpujr4#
指针算术的工作原理是这样的。它不会给予两个地址之间的差异。相反,它会显示两个变量之间的差异,就好像它们存储在一个数组中一样。所以,无论你的变量(相同类型的)是4字节,8字节还是1字节,如果存储在相邻的内存位置,它们的指针减法将始终导致1或-1。
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。
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)将提供两个变量之间的距离,但不会提供两个指针之间的内存间隙。重要提示:只有相同类型的指针才能被减去。
tct7dpnv7#
数组中两个指针的相减将给予两个元素之间的距离。设第一个元素的地址为1000,则第二个元素a+1的地址将为1004,因此p1 = 1000和p2 =1004。
a+1
p1 = 1000
p2 =1004
p2-p1 = (1004- 1000) /size of int = (1004-1000)/4 =4/4 =1
7条答案
按热度按时间yws3nbqq1#
这是未定义的行为.根据标准(
N1570
):6.5.6加法运算符
....
9当两个指针相减时,两个指针都 * 应指向同一数组对象的元素,或者指向数组对象 * 最后一个元素之后的一个元素;结果为 * 两个数组元素下标 * 的差。
请注意,如果允许,结果就是下标的差。因此,如果指针指向同一类型的两个连续元素,则无论该类型的大小如何,减法都将得到
1
。(这可能是在具体情况下得到1
的原因。)q1qsirdb2#
您的特殊情况是未定义行为的原因,因为
p
和q
指向不相关的对象。只有当
p
和q
指向同一个数组/同一个数组的最后一个元素后的一个元素时,才能理解p-q
。字符串
q - p
在这种情况下是5,因为它们指向数组中相隔5个元素的元素。换句话说,
p+5
等于q
。如果你从p
开始,遍历数组的5个元素,你将指向q
指向的数组的同一个元素。顺便说一句,不要使用格式说明符
%d
来打印指针。使用%p
。使用%td
来打印ptrdiff_t
。型
有关不同类型的有效格式说明符,请参见http://en.cppreference.com/w/c/io/fprintf。
rqcrx0a63#
公式used by pointer substraction为:
第一个月
T
是p1
和p2
的类型。字符串
e0bqpujr4#
指针算术的工作原理是这样的。它不会给予两个地址之间的差异。相反,它会显示两个变量之间的差异,就好像它们存储在一个数组中一样。所以,无论你的变量(相同类型的)是4字节,8字节还是1字节,如果存储在相邻的内存位置,它们的指针减法将始终导致1或-1。
amrnrhlw5#
两个指针的减法给予两个变量之间的距离。
//假设a的地址是1000,那么a+1的地址将是1004
字符串
这样做的结果是1,而不是4。在你的例子中也是一样,x和y的位置是连续的,这就是为什么ans是1。
yquaqz186#
字符串
(diff-ptr)将提供两个变量之间的距离,但不会提供两个指针之间的内存间隙。重要提示:只有相同类型的指针才能被减去。
tct7dpnv7#
数组中两个指针的相减将给予两个元素之间的距离。
设第一个元素的地址为1000,则第二个元素
a+1
的地址将为1004,因此p1 = 1000
和p2 =1004
。字符串