float (*ptrs[])[2] = {a, b, c};
, который читается как
ptrs -- ptrs
ptrs[] -- is an array of unknown size
(*ptrs[]) -- of pointers
(*ptrs[])[2] -- to 2-element arrays
float (*ptrs[])[2] -- of float
, и мы инициализируем его указателями на a
, b
и c
.
Ваше определение функции будет выглядеть так:
void take_values( float (**ptrs)[2] )
{
...
}
int main( void )
{
float (*ptrs[])[2] = {a, b, c};
...
take_values( ptrs );
}
Вы будете индексировать в каждом массиве как
ptrs[i][j][k]
в main
и take_values
.
Как мы туда доберемся:
Каждое из выражений a
, b
и c
будет "распадаться" до введите float (*)[2]
1 , поэтому указатель на каждый массив может быть объявлен как
float (*pt1)[2] = a;
float (*pt2)[2] = b;
...
et c. Мы просто объявляем массив указателей для хранения всех трех.
Вы будете индексировать в каждом массиве как
ptrs[i][j][k]
Помните, что a[i]
определяется как *(a + i)
, поэтому
*a == *(a + 0) == a[0]
Это означает, что
(*ptrs[i])[k] == (*(ptrs[i] + 0))[k] == (ptrs[i][0])[k] == ptrs[i][0][k]
Таким образом,
(*(ptrs[i] + j))[k] == (ptrs[i][j])[k] == ptrs[i][j][k]
В main
, поскольку ptrs
является массивом T
, где T
это "массив указателей на 2-элементные массивы float
", когда вы передаете его функции, он "затухает", чтобы набрать "указатель на T
", или "указатель на указатель на 2-элементный массив из float
".
В take_values
вы имеете дело с указателем на указатель, поэтому
(**ptrs)[i] == (*(*ptrs + 0))[i] == (*ptrs[0])[i] == (*(ptrs[0] + 0))[i] == (ptrs[0][0])[i]
Обратите внимание, что вам нужен способ указать, насколько большой массив из указателей есть, и сколько строк содержит каждый из массивов.
За исключением случаев, когда он является операндом операторов sizeof
или унарных &
или является строковым литералом, используемым для инициализации массива символов в объявлении выражение типа "массив N-элементов из T
" будет преобразовано ("распад") в выражение типа "указатель на T
" и значение выражения будет адрес первого элемента массива.