Когда вы используете имя массива (в большинстве случаев), он распадается на указатель на свой первый элемент.Это означает, что int* p = a;
и int* p = &a[0];
абсолютно одинаковы.
Итак, чтобы понять, что происходит в этом случае, просто пройдите шаг за шагом.В момент вашего первого printf
вызова все выглядит так:
pp p a
+-------+ +------+ +----+----+----+----+
| +---------> +--------> -1 | -2 | -3 | -4 |
+-------+ | | +----+----+----+----+
| |
+------+ b
| | +----+----+----+----+
| +---------> 0 | 1 | 2 | 3 |
| | +----+----+----+----+
+------+
pp
указывает на первый элемент p
, который является указателем на первый элемент a
.
Теперь, когда вы увеличиваете pp
, он изменяется, чтобы указывать на второй элемент p
, который является указателем на первый элемент b
:
pp p a
+-------+ +------+ +----+----+----+----+
| + | | +--------> -1 | -2 | -3 | -4 |
+---|---+ | | +----+----+----+----+
| | |
| +------+ b
| | | +----+----+----+----+
+---------> +---------> 0 | 1 | 2 | 3 |
| | +----+----+----+----+
+------+
Затем вы увеличиваете *pp
.Поскольку *pp
является указателем на первый элемент b
, этот указатель увеличивается для указания на второй элемент b
:
pp p a
+-------+ +------+ +----+----+----+----+
| + | | +--------> -1 | -2 | -3 | -4 |
+---|---+ | | +----+----+----+----+
| | |
| +------+ b
| | | +----+----+----+----+
+---------> | | 0 | 1 | 2 | 3 |
| + | +----+-^--+----+----+
+---|--+ |
+---------------+
Затем вы увеличиваете **pp
.В этот момент pp
является указателем на второй элемент p
, поэтому *pp
является указателем на второй элемент b
.Это означает, что **pp
называет второй элемент b
.Вы увеличиваете это значение с 1
до 2
:
pp p a
+-------+ +------+ +----+----+----+----+
| + | | +--------> -1 | -2 | -3 | -4 |
+---|---+ | | +----+----+----+----+
| | |
| +------+ b
| | | +----+----+----+----+
+---------> | | 0 | 2 | 2 | 3 |
| + | +----+-^--+----+----+
+---|--+ |
+---------------+
Теперь давайте рассмотрим (++**pp)[a]
.++**pp
такой же, как и раньше, поэтому второй элемент b
увеличивается до 3
.
Теперь для любого указателя ptr
и целого числа n
, ptr[n]
одинаковыкак *(ptr + n)
.Поскольку сложение коммутативно, ptr + n
совпадает с n + ptr
.Это означает, что ptr[n]
- это то же самое, что и n[ptr]
.
. Сочетание этих значений означает, что (++**pp)[a]
- это то же самое, что и 3[a]
, что совпадает с a[3]
.a[3]
равно -4
, следовательно, ваш результат.