Стандарт C99 добавил всевозможные полезные способы инициализации структур, но не предоставил оператора повторения (который был в Фортране с незапамятных времен, но, возможно, именно поэтому он почему не был добавлен).
Если вы используете достаточно новую версию GCC и можете позволить себе использовать непереносимое расширение, тогда GCC предоставляет расширение. В руководстве GCC 8.1.0 (§6.27 Назначенные инициализаторы), в нем говорится:
Чтобы инициализировать диапазон элементов одним и тем же значением, напишите «[first ... last] = value». Это расширение GNU. Например,
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
Если значение в нем имеет побочные эффекты, побочные эффекты произойдут только один раз, а не для каждого поля, инициализированного инициализатором диапазона.
Итак, используя это в вашем примере:
struct memPermissions memPermissions[numBoxes] =
{
[0..numBoxes-1] = {-1, -1}, // GCC extension
};
Я бы хотел, чтобы это было в стандарте C; это было бы так полезно!
Без использования этого или других подобных механизмов, специфичных для компилятора, единственным выбором будет цикл. Для сложного инициализатора со многими полями, а не с одинаковыми значениями, вы, вероятно, можете использовать:
#include <string.h>
#include "memperm.h" // Header declaring your types and variables
static int initialized = 0;
// -2 so the initialization isn't uniform and memset() is not an option
static const struct memPermissions initPermissions = { -1, -2 };
struct memPermissions memPermissions[numBoxes];
void initialize_permissions(void)
{
if (initialized == 0)
{
for (int i = 0; i < numBoxes; i++)
memmove(&memPermissions[i], &initPermissions, sizeof(initPermissions));
initialized = 1;
}
}
Вы также можете использовать здесь memcpy()
— нет опасности перекрытия двух переменных.
Теперь вам просто нужно убедиться, что initialize_permissions()
вызывается перед использованием массива - желательно только один раз. Это также могут быть специфичные для компилятора механизмы.
Вы можете использовать локальную переменную в функции initialize_permissions()
вместо инициализированной статической постоянной переменной — просто убедитесь, что ваш компилятор не инициализирует ее каждый раз, когда вызывается функция.
Если у вас есть компилятор C99, вы можете использовать составной литерал вместо константы:
void initialize_permissions(void)
{
if (initialized == 0)
{
for (int i = 0; i < numBoxes; i++)
memmove(&memPermissions[i],&(struct memPermissions){ -1, -2 },
sizeof(memPermissions[0]));
initialized = 1;
}
}
20.11.2011