C语言。无法理解指针的输出

C language. Can't understand the output of the pointers

我有如下一段代码。

    int a = 10, b = 20;
    int *x, *y, *z;
    int **pp;
    int arr[3] = { 5, 13, 29 };
    x = &b;
    pp = &y;
    y = arr + 1;
    *y = a;
    z = y;
    **pp = 999;
    y++;

    printf("%i %i %i %i %i %i %i %i %i", a, b, *x, *y, *z, **pp, arr[0], arr[1], arr[2]);

我预计输出会是 10 20 20 29 10 999 5 999 29,但是,正确的输出似乎是 10 20 20 29 999 29 5 999 29。区别在于 *z**pp。我无法理解为什么会这样,尽管我尝试绘制图表并逐步分析结果。为什么*z**pp分别是999和29,而不是10和999?谢谢。

这条语句之后

y = arr + 1;

指针y指向数组的第二个元素arr,

所以在下一条语句

之后第二个元素设置为10
*y = a;

并且我们有如下数组内容arr

{ 5, 10, 29 }

指针z也指向这个第二个元素

 z = y;

但是第二个元素被改写了

 **pp = 999;

因为取消引用的指针 pp 总是产生指针 y。现在数组的内容是

{ 5, 999, 29 }

并且指针 y 递增并且在该语句之后

y++;

指向数组的第三个元素。注意指针pp仍然指向现在存储数组第三个元素地址的指针y

变量ab没有改变>所以printf的调用输出

10 20

指针x指向变量b所以我们有

10 20 20

指针y指向数组的第三个元素。所以

10 20 20 29

指针z指向数组的第二个元素,因为它在递增前具有指针y的值。

10 20 20 29 999

指针 pp 指向指针 y,因此表达式 **pp 产生与表达式 *y

相同的值
10 20 20 29 999 29

而这些表达式arr[0], arr[1], arr[2]依次提供数组的值

10 20 20 29 999 29 5 999 29