У вас есть несколько проблем.
Сначала вы объявляете func
для взятия char **
, но позже определяете его для взятия int *[8]
, что не соответствует. Хуже того, оба они не правы - или, скорее, они не соответствуют типу аргумента, который вы передаете.
За исключением случаев, когда это операнд операторов sizeof
или унарных &
, выражение типа «N-элемент из T
» будет преобразовано («распад») в выражение типа «указатель на T
», а значением выражения будет адрес первого элемента.
Когда вы передаете ptr
в func
, он преобразуется из типа «2-элементный массив 3-элементного массива int
» в «указатель на 3-элементный массив int
», или int (*)[3]
. Таким образом, прототип функции должен быть
void func( int (*ptr)[3] )
или
void func( int ptr[][3] )
Поскольку ваши определения функций и объявления не совпадают, а также потому, что ни один из них не соответствует фактическому типу аргумента, вы получите неожиданный вывод. Вы должны получить предупреждение о несоответствующих типах аргументов функции; в противном случае вам может потребоваться повысить уровень предупреждения.