两个指针变量之间的差异

我在书面测试中问过这个问题。 在我的lapi上运行下面的代码时,我得到10作为输出

#include int main() { int *i, *j;/* two pointer variable*/ i = (int *)60; j = (int *)20; printf("%d \n",ij); return 0; } 

输出:

 10 

任何人都可以告诉我为什么输出是10

根据C标准(6.5.6添加剂操作员)

9当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异。

因此,您的程序具有未定义的行为,因为指针不指向同一数组的元素。

Nevertheles似乎编译器只是生成一个用于减去两个指针的目标代码,而不管指针是否指向同一个数组的元素(它信任你)。

在这种情况下,根据指针算术的两个指针之间的差异是可以在两个指针之间放置在存储器中的元素的数量。

在您的情况下, sizeof( int )等于4 。 因此,如果sizeof( int )等于4 ,则大小为40字节的内存可以容纳10 int类型的元素。

此值为10由printf函数输出。

您正在评估两个指向int指针之间的差异或“距离”。 sizeof(int)在您的平台上是4。 60和20之间的差值是40,即10个英尺之间的距离。 您的实现似乎只是简单地评估这种差异。

但是,C标准限制了对两个指针之间差异的评估:两个指针都必须指向数组中的元素,或者指向结尾的元素。 如果您可以确保ij满足此要求,那么差异评估是有效的。 由于您的代码不一定满足该条件,因此它可能具有未定义的行为 ,在这种情况下,输出/结果可能是任何东西。

另请注意,除非它们指向保存int值的有效地址,否则是取消引用ij未定义行为。

只有当两个指针指向同一个(数组)对象(或后面的一个)时,C标准才能定义两个指针的差异,因此OP的代码调用未定义的行为。 结果可能是任何事情。

从C11标准:

6.5.6 / 9加法运算符

当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异。 结果的大小是实现定义的,其类型(有符号整数类型)是在头中定义的ptrdiff_t 。 如果结果在该类型的对象中无法表示,则行为未定义。

以下代码有效:

 #include  int main() { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int * i = a + 0; int * j = a + 10; /* Points "one past the last element" of the array. */ printf("%td \n", i - j); return 0; } 

它还打印10

取消指向同一对象内部的指针之间的区别是未定义行为。

你的指针根本没有指向任何对象。

在Undefined Behavior中减去代码中的指针是未定义的行为。

任何结果(10,40,65535,-1)都是错误的。

你所看到的是未定义的行为。

指针应指向一些有效的内存位置,而60和20则不是。

只是引用标准

两个指针都应指向同一个数组对象的元素,或者指向数组对象的最后一个元素,因为这不是您在代码中看到的,这是UB。

虽然它是严格未定义的行为 ,但允许发生任何事情,但编译器在处理此类代码时很少是任意的,结果可以在这种情况下解释为:

  (i - j) == ((60 - 20) / sizeof(int)) 

但请注意,在某些情况下可能不适用; 它可以例如取决于目标存储器架构或对象的相对对齐。