问题
I am unable to get that why in this program 2 - 4 gives -1, it has assigned int values to pointers rather than addresses, I know but while I compiled it compiler gave some warnings but compiled the program and it executed but...
Program
#include<stdio.h>
int main(void) {
int *p, *q;
int arr[] = {1,2,3,4};
// I know p and q are pointers and address should be assigned to them
// but look at output, why it evaluates (p-q) to -1 while p as 2 and q as 4
p = arr[1];
q = arr[3];
printf("P-Q: %d, P: %d, Q: %d", (p - q), p, q);
return 0;
}
It gives
P-Q: -1, P: 2, Q: 4
回答1:
Strictly speaking, what happens depends entirely on your compiler and platform... but let's assume we're using a typical compiler and ignoring the warnings.
Let's simplify your question further:
p = 2;
q = 4;
printf("P-Q: %d, P: %d, Q: %d", (p - q), p, q);
which produces the same wacky result:
P-Q: -1, P: 2, Q: 4
As @gsamaras pointed out, we're trying to subtract two pointers. Let's try and see how this might result in -1
:
p - q = (2 - 4) / sizeof(int)
= (-2) / 4
= -1
I suggest trying a couple of your own p
and q
values to see what happens.
Examples with different p
and q
:
p - q = ??
==========
0 - 0 = 0
0 - 1 = -1
0 - 2 = -1
0 - 3 = -1
0 - 4 = -1
1 - 0 = 0
1 - 1 = 0
1 - 2 = -1
1 - 3 = -1
1 - 4 = -1
2 - 0 = 0
2 - 1 = 0
2 - 2 = 0
2 - 3 = -1
2 - 4 = -1
3 - 0 = 0
3 - 1 = 0
3 - 2 = 0
3 - 3 = 0
3 - 4 = -1
4 - 0 = 1
4 - 1 = 0
4 - 2 = 0
4 - 3 = 0
4 - 4 = 0
Generated using gcc -fpermissive
on:
#include <stdio.h>
int main() {
printf("p - q = ??\n");
printf("==========\n");
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
int* p = i;
int* q = j;
printf("%d - %d = %2d\n", p, q, (p - q));
}
}
return 0;
}
回答2:
The duplicate question mentions that:
pointer subtraction yields the number of array elements between two pointers of the same type
Read more about it in Pointer subtraction confusion.
However, your code is wrong and ill-formed, since it invokes Undefined Behavior. Please compile with warnings enabled, and you will get:
main.c: In function ‘main’:
main.c:12:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
p = arr[1];
^
main.c:13:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
q = arr[3];
^
main.c:15:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
printf("P-Q: %d, P: %d, Q: %d", (p - q), p, q);
^
main.c:15:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Wformat=]
main.c:15:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘int *’ [-Wformat=]
The errors will occur nevertheless. For the warnings, I just used the -Wall
flag.
In order for your code to make sense, you could just declare p
and q
as simple int
s and and not as pointers.
Or, you could do this:
p = &arr[1];
q = &arr[3];
printf("P-Q: %td, P: %p, Q: %p", (p - q), (void *)p, (void *)q);
and get something like this:
P-Q: -2, P: 0x7ffdd37594d4, Q: 0x7ffdd37594dc
Note that I used %td for printing the result of the subtraction of pointers.
来源:https://stackoverflow.com/questions/51056210/2-4-1-when-int-value-assigned-to-pointer-in-c