Стандарт C99 добавил всевозможные полезные способы инициализации структур, но не предоставил оператор повтора (который у Фортрана был с тех пор навсегда - но, возможно, это было , почему не было добавлено).
Если вы используете достаточно свежую версию GCC и можете позволить себе использовать непереносимое расширение, то GCC предоставляет расширение.В руководстве GCC 8.1.0 ( §6.27 Назначенные инициализаторы ) говорится:
Чтобы инициализировать диапазон элементов одним и тем же значением, напишите '[first ...последний] = значение '.Это расширение 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;
}
}