Я собираюсь изменить имена ясности, а затем следует строка за строкой:
void print(int *b[])
{
printf("%d,", b[0][2]);
printf("%d,", *b[2]);
printf("%d,", *++b[0]);
printf("%d,", *(++b)[0]);
printf("%d\n", b[-1][+1]);
}
printf("%d,", b[0][2]);
b[0]
является a1
затем a1[2]
является 8
printf("%d,", *b[2]);
b[2]
является a3
и *a3
является первым элементом, который является a3
-12
printf("%d,", *++b[0]);
b[0]
является a1
, то мы увеличиваем поэтому мы имеем *++a1
что эквивалентно до a1[1]
, который составляет 7
printf("%d,", *(++b)[0]);
Теперь в этом случае мы должны сделать только (++b)
, что эквивалентно ++x
, что составляет a2
. теперь у нас есть *a2[0]
, который составляет 23. Важно то, что мы только что изменили b
, указатель на b
только что получил приращение и сохранил новый указатель в b
.
printf("%d\n", b[-1][+1]);
Мы должны помнить, что b
изменил одну строку перед так b
здесь начинается, как если бы он был принят в b+1
первоначально. Это означает, что мы начинаем указатель одного адреса дальше, чем раньше: так это то, как мы имели (x+1)[-1][+1]
, который x[-1+1][+1+1]
или x[0][2]
, который a1[2]
который 8.
Это как это работает, потому что массив здесь действительно только один непрерывный блок памяти. Обратите внимание, что если вы сделали int **x
, это было бы иначе.
Обратите внимание, что это правильный результат, как вы можете видеть, когда вы запустите код здесь: http://ideone.com/0mFvXn
По существу на последней строке, что произошло можно продемонстрировать следующим образом:
#include <stdio.h>
int a1[] = {6, 7, 8, 18, 34, 67};
int a2[] = {23, 56, 28, 29};
int a3[] = {-12, 27, -31};
int *x[] = {a1, a2, a3};
int main(void)
{
printf("%d, %d \n", x[0][0], x[1][1]);
int** z = x;
++z;
printf("%d, %d \n", z[0][0], z[1][1]);
return 0;
}
выход:
6, 56
23, 27
Последний фрагмент кода на ideone: http://ideone.com/cB5y75
. Обратите внимание, что гораздо лучше яснее писать этот тип кода, чем пример кода в вопросе, поэтому, пожалуйста, не делайте ничего подобного в производственном коде.Второй фрагмент кода в этом ответе довольно ясен в моем сознании, чем первый.
И вопрос в том, что? – bitcell
Я думаю, что более важно здесь не использовать оператор инкремента как это, поскольку он уменьшает читабельность кода. Если бы это был код, который вы написали, я бы предложил вам пересмотреть, как вы это написали. – shuttle87
@ shuttle87 Я думаю, что это пример обучения, а не настоящий код. –