Минимально необходимые изменения
Вы не можете смешивать typedef
с инициализаторами - по крайней мере, не в C. У вас также не может быть типов структур, размер которых изменяется в зависимости от данных в структуре - по крайней мере, без их использования ( и только один) элемент гибкого массива (FAM), но ваш код пытается использовать два переменных массива (поэтому они не могут быть FAM).
Вам нужно что-то похожее на:
typedef struct ytxModule{
uint8_t nEncoders;
uint8_t nDigital;
uint8_t nAnalog;
uint8_t nLedsPerControl;
} ytxModule; // Add name for typedef
typedef struct{
ytxModule components;
uint8_t encPins[4][2];
uint8_t encSwitchPins[4];
} ytxE41Module;
ytxE41Module module = {
.components = {4, 0, 0, 16},
.encPins = {
{1, 0},
{4, 3},
{14, 15},
{11, 12}
},
.encSwitchPins = { 2, 5, 13, 10 },
};
Это не изменит форму, если вы инициализируете .components.nEncoders
значением, отличным от 4
. В зависимости от ваших потребностей, вы можете подумать о замене жестко запрограммированного 4
изменяемым значением во время компиляции, но вам также понадобится способ изменить размеры массивов инициализатора, чтобы они соответствовали, что в лучшем случае, вероятно, было бы непростым, непостижимым в худшем случае. Не ясно, как устанавливаются значения инициализатора.
Использование члена гибкого массива
Если вы хотите использовать член гибкого массива, вам придется организовать тип для хранения массива данных encSwitchPins
и encPins
и использовать разные обозначения для доступа к элементам FAM.
typedef struct ytxModule{
uint8_t nEncoders;
uint8_t nDigital;
uint8_t nAnalog;
uint8_t nLedsPerControl;
} ytxModule;
typedef struct
{
ytxModule components;
struct
{
uint8_t encPins[2];
uint8_t encSwitchPins;
} pins[];
} ytxE41Module;
Вы больше не можете использовать инициализатор для этого типа данных; вы будете динамически распределять память, а затем назначать значения выделенным данным:
// Data used for initializing structure
int n_pins = 4;
uint8_t encPins[][2] = {
{ 1, 0 },
{ 4, 3 },
{ 14, 15 },
{ 11, 12 },
};
uint8_t switchPins[] = { 2, 5, 13, 10 };
// Allocate and check allocation
ytxE41Module *mp = malloc(sizeof(*mp) + n_pins * sizeof(mp->pins[0]));
if (mp == NULL)
return NULL;
// Assign values to allocated structure
mp->components = (ytxModule){ n_pins, 0, 0, 16};
for (int i = 0; i < n_pins; i++)
{
for (int j = 0; j < 2; j++)
mp->pins[i].encPins[j] = encPins[i][j];
mp->pins[i].encSwitchPins = switchPins[i];
}
Если вы пометите тип встроенной структуры, вы можете инициализировать массив этого типа и использовать memmove()
(или memcpy()
), чтобы переместить копию отдельного массива в структуру FAM. И т. Д. Гораздо проще, если объем данных в структуре фиксирован (например, в 4 элементах массива), как показано в первой части ответа.