#include <stdio.h>
int main() {
int *p = 100;
int *q = 92;
printf("%d\n", p - q); //prints 2
}
上述程序的输出不应该是8?
相反,我得到了2.
答案 0 :(得分:12)
除了未定义的行为,这是您使用指针算法获得的行为:当减去指针是合法的时,它们的差异表示指针之间的数据项数。如果int
在您的系统上每个int
使用四个字节,则八个字节间隔的指针之间的差异为(8 / 4)
,这可以达到2
。< / p>
这是一个没有未定义行为的版本:
int data[10];
int *p = &data[2];
int *q = &data[0];
// The difference between two pointers computed as pointer difference
ptrdiff_t pdiff = p - q;
intptr_t ip = (intptr_t)((void*)p);
intptr_t iq = (intptr_t)((void*)q);
// The difference between two pointers computed as integer difference
int idiff = ip - iq;
printf("%td %d\n", pdiff, idiff);
答案 1 :(得分:2)
您的代码为undefined behavior。
你不能简单地减去两个“任意”指针。引用C11
,章节§6.5.6/ P9
当减去两个指针时,两个指针都指向同一个数组对象的元素, 或者超过数组对象的最后一个元素;结果是差异 两个数组元素的下标。结果的大小是实现定义的, 并且其类型(有符号整数类型)在
ptrdiff_t
标头中定义为<stddef.h>
。 [....]
另外,如上所述,如果正确地减去两个指针,结果将是ptrdiff_t
类型,您应该使用%td
来打印结果。
话虽如此,初始化
int *p = 100;
本身看起来很错!!为了澄清,它不将值100
存储到指向的内存位置(问题:它指向哪里?)p
。它试图用整数值100
设置指针变量本身,这似乎是一个约束违规本身。
答案 2 :(得分:2)
此
int *p = 100;
int *q = 92;
已经无效C.在C中,您无法初始化具有任意整数值的指针。除了从空指针常量0
转换之外,语言中没有隐式的整数到指针转换。如果由于某种原因需要将特定的整数值强制转换为指针,则必须使用显式强制转换(例如int *p = (int *) 100;
)。
即使你的代码以某种方式编译,它的行为也不是由C语言定义的,这意味着这里没有“应该”答案。
答案 3 :(得分:1)
根据标准(N1570)
当减去两个指针时,两个指针都应指向 相同的数组对象,或者超过数组最后一个元素的数组 宾语;结果是两者下标的差异 数组元素。
答案 4 :(得分:0)
这些是整数指针,sizeof(int)
是4.指针算术以指向的事物的大小为单位完成。因此&#34; raw&#34;差异以字节为单位除以4.此外,结果为ptrdiff_t
,因此%d
不太可能削减它。
但是请注意,正如Sourav指出的那样,你所做的是技术上未定义的行为。它几乎是偶然地在最常见的环境中工作。但是,如果p和q指向同一个数组,则定义行为。
int a[100];
int *p = a + 23;
int *q = a + 25;
printf("0x%" PRIXPTR "\n", (uintptr_t)a); // some number
printf("0x%" PRIXPTR "\n", (uintptr_t)p); // some number + 92
printf("0x%" PRIXPTR "\n", (uintptr_t)q); // some number + 100
printf("%ld\n", q - p); // 2
答案 5 :(得分:0)
int main() {
int *p = 100;
int *q = 92;
printf("%d\n", p - q); //prints 2
}
它被称为pointer arthmetic
会发生什么。
该值为(100-92)/sizeof(int)
。在您的情况下sizeof(int)=4
。
在ISO9899中,指针运算被定义为减法ptr-ptr
。第6.5.6p9章
当减去两个指针时,两个指针都指向同一个数组对象的元素, 或者超过数组对象的最后一个元素;结果是差异 两个数组元素的下标。