两个指针变量之间的差异[重复]

时间:2021-06-25 13:30:36

This question already has an answer here:

这个问题在这里已有答案:

i have asked this question in a written test. while running the below code on my lapi, i am getting 10 as output

我在书面测试中问过这个问题。在我的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;
}

Output :

输出:

10 

Can anyone tell me why the output is 10.

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

6 个解决方案

#1


7  

According to the C Standard (6.5.6 Additive operators)

根据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.

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

So your program has undefined behaviour because the pointers do not point to elements of the same array.

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

Nevertheles it seems that the compiler simply generates an object code for subtracting two pointers irrespective of whether the pointers point to elements of the same array (it trusts you).

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

In this case the difference between the two pointers according to the pointer arithmetic is the number of elements that can be placed in the memory between two pointers.

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

In your case the sizeof( int ) is equal to 4. So a memory that has size of 40 bytes can accomodate 10 elements of type int provided that sizeof( int ) is equal to 4.

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

This value that is 10 is outputed by the printf function.

此值为10由printf函数输出。

#2


6  

You are evaluating the difference, or "distance" between two pointers to int. sizeof(int) is 4 on your platform. The difference between 60 and 20 is 40, which is the distance between 10 ints. Your implementation seems to be simply evaluating this difference.

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

However, the C standard places a restriction on the evaluation of the difference between two pointers: both pointers must point to elements in an array, or one past the end. If you can ensure both i and j satisfy this, then the difference evaluation is valid. Since your code does not necessarily satisfy that condition, it may have undefined behaviour, in which case the output/outcome could have been anything.

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

Also note that is is undefined behaviour to de-reference i and j unless they point to valid addresses holding int values.

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

#3


3  

Taking the difference of two pointers is defined by the C Standard only if both pointers point to the same (array) object (or one behind), so the OP's code invokes undefined behaviour. The result could be anything.

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

From the C11 Standard:

从C11标准:

6.5.6/9 Additive operators

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. 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 behavior is undefined.

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

The following code is valid:

以下代码有效:

#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;
}

It also prints 10.

它还打印10。

#4


2  

Taking the difference between pointers that do not point inside the same object is Undefined Behaviour.

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

Your pointers do not point to any object at all.

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

It is Undefined Behaviour to subtract the pointers in your code.

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

Any result (10, 40, 65535, -1) is erroneous.

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

#5


1  

What you are seeing is undefined behavior.

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

Pointer should point to some valid memory location and 60 and 20 are not.

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

Just to quote from the standard

只是引用标准

Both pointers shall point to elements of the same array object, or one past the last element of the array object since this is not what you see in your code this is UB.

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

#6


1  

While it is strictly undefined behaviour and anything is allowed to happen, however compilers are seldom arbitrary in their treatment of of such code and the result can be explained in this case as:

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

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

But be aware that in some circumstances it may not apply; it may for example be dependent on the target memory architecture, or the relative alignment of the objects.

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

#1


7  

According to the C Standard (6.5.6 Additive operators)

根据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.

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

So your program has undefined behaviour because the pointers do not point to elements of the same array.

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

Nevertheles it seems that the compiler simply generates an object code for subtracting two pointers irrespective of whether the pointers point to elements of the same array (it trusts you).

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

In this case the difference between the two pointers according to the pointer arithmetic is the number of elements that can be placed in the memory between two pointers.

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

In your case the sizeof( int ) is equal to 4. So a memory that has size of 40 bytes can accomodate 10 elements of type int provided that sizeof( int ) is equal to 4.

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

This value that is 10 is outputed by the printf function.

此值为10由printf函数输出。

#2


6  

You are evaluating the difference, or "distance" between two pointers to int. sizeof(int) is 4 on your platform. The difference between 60 and 20 is 40, which is the distance between 10 ints. Your implementation seems to be simply evaluating this difference.

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

However, the C standard places a restriction on the evaluation of the difference between two pointers: both pointers must point to elements in an array, or one past the end. If you can ensure both i and j satisfy this, then the difference evaluation is valid. Since your code does not necessarily satisfy that condition, it may have undefined behaviour, in which case the output/outcome could have been anything.

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

Also note that is is undefined behaviour to de-reference i and j unless they point to valid addresses holding int values.

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

#3


3  

Taking the difference of two pointers is defined by the C Standard only if both pointers point to the same (array) object (or one behind), so the OP's code invokes undefined behaviour. The result could be anything.

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

From the C11 Standard:

从C11标准:

6.5.6/9 Additive operators

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. 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 behavior is undefined.

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

The following code is valid:

以下代码有效:

#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;
}

It also prints 10.

它还打印10。

#4


2  

Taking the difference between pointers that do not point inside the same object is Undefined Behaviour.

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

Your pointers do not point to any object at all.

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

It is Undefined Behaviour to subtract the pointers in your code.

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

Any result (10, 40, 65535, -1) is erroneous.

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

#5


1  

What you are seeing is undefined behavior.

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

Pointer should point to some valid memory location and 60 and 20 are not.

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

Just to quote from the standard

只是引用标准

Both pointers shall point to elements of the same array object, or one past the last element of the array object since this is not what you see in your code this is UB.

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

#6


1  

While it is strictly undefined behaviour and anything is allowed to happen, however compilers are seldom arbitrary in their treatment of of such code and the result can be explained in this case as:

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

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

But be aware that in some circumstances it may not apply; it may for example be dependent on the target memory architecture, or the relative alignment of the objects.

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