(2 - 4 = -1) 当 int 值分配给 C 中的指针时?

(2 - 4 = -1) when int value assigned to pointer in C?

我不明白为什么在这个程序中 2 - 4 给出 -1,它已将 int 值分配给指针而不是地址,我知道但是当我编译它时编译器给出了一些警告但是编译了程序并且它执行但是...

计划

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

给出

P-Q: -1, P: 2, Q: 4

duplicate question 提到:

pointer subtraction yields the number of array elements between two pointers of the same type

Pointer subtraction confusion 中阅读更多相关信息。

但是,您的代码是错误的且格式不正确,因为它调用了未定义的行为。请启用警告编译,你将得到:

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=]

错误仍然会发生。对于警告,我只是使用了 -Wall 标志。


为了使您的代码有意义,您可以将 pq 声明为简单的 int 而不是指针。

或者,您可以这样做:

p = &arr[1];
q = &arr[3];

printf("P-Q: %td, P: %p, Q: %p", (p - q), (void *)p, (void *)q);

得到这样的东西:

P-Q: -2, P: 0x7ffdd37594d4, Q: 0x7ffdd37594dc

注意我用的是.

严格来说,发生的情况完全取决于您的编译器和平台...但假设我们使用的是典型的编译器并忽略警告。

让我们进一步简化您的问题:

p = 2;
q = 4;

printf("P-Q: %d, P: %d, Q: %d", (p - q), p, q);

产生同样古怪的结果:

P-Q: -1, P: 2, Q: 4

正如@gsamaras 所指出的,我们正在尝试减去两个指针。让我们试试看这会如何导致 -1:

p - q = (2 - 4) / sizeof(int)
      = (-2)    / 4
      = -1

我建议尝试几个您自己的 pq 值,看看会发生什么。


具有不同 pq 的示例:

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

使用 gcc -fpermissive 生成:

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