使用NULL的指针算术

Sap*_*ire 5 c pointers

有人可以解释,为什么

int main(void)
{
    char *a = NULL;
    int *b = NULL;
    double *c = NULL;

    printf("\n%d %d %d\n%d %d %d\n\n",
    (int) (a+1), (int)(b+1), (int)(c+1),
    (int) (a+5), (int)(b+7), (int)(c+17));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

1, 4, 8
5, 28, 136
Run Code Online (Sandbox Code Playgroud)

我认为它与这些变量的字节大小有关.但我不明白第二行输出.

Typ*_*eIA 14

如果p是指向类型的指针T,并且它保存内存地址X,那么p + N就是内存地址X + N * sizeof(T).

(int) (a +  1) == 0 +  1 * sizeof(char)   ==  1 * 1 ==   1
(int) (b +  1) == 0 +  1 * sizeof(int)    ==  1 * 4 ==   4
(int) (c +  1) == 0 +  1 * sizeof(double) ==  1 * 8 ==   8

(int) (a +  5) == 0 +  5 * sizeof(char)   ==  5 * 1 ==   5
(int) (b +  7) == 0 +  7 * sizeof(int)    ==  7 * 4 ==  28
(int) (c + 17) == 0 + 17 * sizeof(double) == 17 * 8 == 136
Run Code Online (Sandbox Code Playgroud)

小调:正如Barmar在他的回答中所指出的,对NULL指针的算术在技术上是未定义的行为.因此,符合标准的编译器可能会对该算法做出不同的处理; 代码可能打印了1,11415或玩扑克的狗的照片.但是,你观察到的行为是一样的定义,如果你想与有效指针开始,你就已经观察到的行为,所以你可能不需要担心这个问题.