两个指针变量之间的差异

Difference between two pointer variables

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

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

输出:

10 

谁能告诉我为什么输出是 10

您看到的是未定义的行为。

指针应该指向某个有效的内存位置,而 60 和 20 不是。

仅引用标准

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

您正在评估两个指向 int 的指针之间的差异,或 "distance"。 sizeof(int) 在您的平台上是 4。 60 和 20 之间的差异是 40,这是 10 个 int 之间的距离。您的实施似乎只是在评估这种差异。

但是,C 标准对计算两个指针之间的差异进行了限制:两个指针都必须指向数组中的元素,或者指向数组末尾的元素。如果能保证ij都满足这个,那么差值求值是有效的。由于您的代码不一定满足该条件,它可能有 未定义的行为,在这种情况下 output/outcome 可能是任何东西。

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

根据 C 标准(6.5.6 加法运算符)

9 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

所以你的程序有未定义的行为,因为指针不指向同一个数组的元素。

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

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

在您的例子中,sizeof( int ) 等于 4。因此,如果 sizeof( int ) 等于 4.

,则大小为 40 字节的内存可以容纳 10 个 int 类型的元素

这个值10是printf函数输出的

仅当两个指针都指向同一个(数组)对象(或后面的一个)时,C 标准才定义两个指针的不同,因此 OP 的代码调用未定义的行为。结果可以是任何东西。

来自 C11 标准:

6.5.6/9 Additive operators

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header. If the result is not representable in an object of that type, the behaviour is undefined.

以下代码有效:

#include <stdio.h>

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.

取不指向同一对象内部的指针之间的差异是未定义行为。

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

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

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

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

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

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