问题
i have asked this question in a written test. while running the below code on my lapi, i am getting 10 as output
#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
.
回答1:
According to the C Standard (6.5.6 Additive operators)
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.
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).
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
.
This value that is 10 is outputed by the printf function.
回答2:
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.
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.
Also note that is is undefined behaviour to de-reference i
and j
unless they point to valid addresses holding int
values.
回答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.
From the C11 Standard:
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 behavior is undefined.
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
.
回答4:
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.
Any result (10, 40, 65535, -1) is erroneous.
回答5:
What you are seeing is undefined behavior.
Pointer should point to some valid memory location and 60 and 20 are not.
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.
回答6:
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.
来源:https://stackoverflow.com/questions/27885823/difference-between-two-pointer-variables