Все это связано с тем, как массив преобразуется в указатель при доступе, см .: Стандарт C11 - 6.3.2.1 Другие операнды - L-значения, массивы и указатели функций (p3) .
В вашем случае у вас есть двумерный массив int a[NUM_ROWS][NUM_COLS];
. Который в действительности является массивом массивов int[NUM_COLS]
. (массив массивов 1D).
При доступе к a
, a
преобразуется в указатель на первый массив 1D и имеет тип int (*)[NUM_COLS]
(указатель на массив NUM_COLS
целые числа).
Вы объявляете p
как указатель на массив NUM_COLS
целых чисел, поэтому p
совместим по типу с a
. Вы можете просто инициализировать:
p = a;
(вместо p = &a[0];
)
В вашем цикле for
вы делаете цикл из p = a;
(указатель на первый 1D массив), ицикл, в то время как p
меньше &a[NUM_ROWS]
(адрес 1 после окончательного 1D массива), увеличивая p
каждую итерацию (а поскольку p
является указателем на int[NUM_COLS]
, p
указывает на следующую строкукаждый раз, когда вы увеличиваете p
)
При разыменовании p
у вас есть массив int[NUM_COLS]
, поэтому, когда вы обращаетесь к (*p)[i] = 0;
, вы устанавливаете элемент i th этот ряд к 0
.
Вот в двух словах. Дайте мне знать, если вы все еще в замешательстве и где, и я с радостью постараюсь объяснить дальше.