Массивы в Си - это в основном указатели. Единственная реальная разница в том, что компилятор знает, на сколько элементов он указывает.
Это означает, что везде, где ваш код ожидает указатель, вы можете использовать вместо него имя массива, поскольку он будет неявно преобразован в указатель на его первый элемент.
Как уже упоминалось, важное различие между массивами и указателями является результатом оператора sizeof()
: для указателей он возвращает количество байтов, необходимое для хранения указателя, для массивов он возвращает количество необходимых байтов хранить элементы!
Следовательно, можно определить количество элементов в массиве с помощью следующего макроса:
#define count(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))
Вместо *ARRAY
вы также можете использовать ARRAY[0]
.
В любом случае, чтобы передать массив функции, просто обработайте его как указатель. Поскольку компилятор не будет знать количество элементов, которые он содержит (он теряет эту информацию во время преобразования), передайте также другой аргумент, указывающий это:
void func(struct ABC * array, size_t elementCount) {...}
struct ABC anArray[2] = {...};
func(anArray, count(anArray));
Мы используем наш макрос count()
, поэтому нам нужно изменить размер массива только в одном месте.
Итак, почему ваша функция ожидает двойной указатель? Скорее всего, чтобы элементы массива произвольно помещались в память. Поэтому, если вы сохранили свои элементы в простом старом массиве, вы должны преобразовать его:
struct ABC array[2] = {...};
struct ABC * parray[count(array)];
for(size_t i = 0; i < count(array); ++i)
parray[i] = &array[i];
Кроме того, если func
действительно не принимает второй аргумент для размера массива, это может означать, что он принимает только массивы определенного размера (тогда сигнатура функции должна была выглядеть примерно как func(struct ABC * array[5])
) или что он ожидает, что определенный элемент будет обозначать конец массива (скорее всего, NULL
). В этом случае вы должны сделать
struct ABC * parray[count(array) + 1];
parray[count(array)] = NULL;
Также еще одним решением будет использование двумерного массива:
struct ABC parray[][1] = {
{ {/* first struct's initializer */} },
{ {/* second struct's initializer */} },
{ {/* third struct's initializer */} }
};
func(parray, count(parray));