Функции C не могут возвращать типы массивов. Типы возвращаемых функций могут быть чем угодно, кроме «массив из T» или «функция, возвращающая T». Обратите внимание, что вы не можете назначать типы массивов; код, подобный следующему, не будет работать:
int a[10];
a = foo();
Массивы в Си обрабатываются иначе, чем другие типы; в большинстве контекстов тип выражения массива неявно преобразуется («распадается») из «массива N-элемента T» в «указатель на T», и его значение устанавливается для указания на первый элемент в массиве. Исключениями из этого правила являются случаи, когда выражение массива является операндом операторов sizeof
или address-of (&
) или когда выражение является строковым литералом, используемым для инициализации другого массива в объявлении.
С учетом декларации
T a[N];
для любого типа T, тогда выполняются следующие условия:
Expression Type Decays to Notes
---------- ---- --------- -----
a T [N] T * Value is address of first element
&a T (*)[N] n/a Value is address of array (which
is the same as the address of the
first element, but the types are
different)
sizeof a size_t n/a Number of bytes (chars) in array =
N * sizeof(T)
sizeof a[i] size_t n/a Number of bytes in single element =
sizeof(T)
a[i] T n/a Value of i'th element
&a[i] T * n/a Address of i'th element
Из-за правила неявного преобразования, когда вы передаете аргумент массива функции, функция получает значение указателя, а не значение массива:
int a[10];
...
foo(a);
...
void foo(int *a)
{
// do something with a
}
Обратите внимание, что делать что-то вроде
int *foo(void)
{
int arr[N];
...
return arr;
}
не работает; после выхода из функции массив arr
технически больше не существует, и его содержимое может быть перезаписано, прежде чем вы сможете его использовать.
Если вы не распределяете буферы динамически, вам лучше всего передать массивы, которые вы хотите изменить, в качестве аргументов функции вместе с их размером (поскольку функция получает только значение указателя, она не может определить, насколько велик массив есть):
int a[10];
init(a, sizeof a / sizeof a[0]); // divide the total number of bytes in
... // in the array by the number of bytes
void init(int *a, size_t len) // a single element to get the number
{ // of elements
size_t i;
for (i = 0; i < len; i++)
a[i] = i;
}