Пара точек:
Прежде всего, функции C не могут возвращать типы массивов;они могут возвращать указатели в массивы, однако:
T (*foo())[N] {...} // returns pointer to N-element array of type T
Подпись разбивается на:
foo -- foo
foo() -- is a function
*foo() -- returning a pointer
(*foo())[N] -- to an N-element array
T (*foo())[N] -- of T
Указатели на массивы не так удобны для использования;Вы (обычно) должны знать размер типа массива, с которым имеете дело (указатель на массив из 10 элементов типа int - это другой, несовместимый тип по сравнению с указателем на массив из 11 элементов типа int), и вынеобходимо разыменовать идентификатор массива перед применением индекса ((*arr)[i] = ...)
. Во-вторых, вы не можете просто вернуть адрес массива из функции, такой как
int (*foo())[10]
{
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
return &arr; // THIS DOESN'T WORK!!!!!!!!
}
, поскольку после выхода из функции arr
технически больше не существует, и значение, полученное вызывающей стороной, теперь указывает на память, которая потенциально была перезаписана или больше не доступна.
Обычная идиома состоит в том, чтобы функция динамически выделяла кусок памяти нужного вам типа., инициализируйте его, а затем верните указатель на этот базовый тип:
T *foo(size_t count) // you may pass other arguments if necessary for
// for initializing the buffer
{
T *bar = malloc(sizeof *bar * count);
if (bar)
{
// initialize the contents of bar
}
return bar;
}
int main(void)
{
T *blah = foo(10);
if (blah)
{
int i;
for (i = 0; i < 10; i++)
do_something_with(blah[i]);
}
return 0;
}
Замените T выше вашим типом связанного списка, и это должно дать вам основу того, что вы хотите сделать.
Если вы не хотите связываться с динамической памятью (лучший способ избежать проблем с управлением памятью - избегать памятиnagement), вы можете передать целевой массив в качестве параметра функции следующим образом:
void foo(T *bar, size_t count) // along with any other parameters necessary
// to initialize bar
{
size_t i;
for (i = 0; i < count; i++)
do_something_with(bar[i]);
}
int main(void)
{
T blah[10];
foo(blah, sizeof blah / sizeof blah[0]);
...
}
Помните, что в большинстве случаев выражение массива будет иметь неявно преобразованный тип ("decay") из "N"-элемент массива T (T [N]
) "to" указатель на T (T *
) ", поэтому при вызове foo
с аргументом массива функция фактически получит тип указателя, а не тип массива,Поскольку указатели не знают размер области, на которую они указывают, вам придется передавать размер массива в качестве отдельного параметра.