Если вы хотите получить доступ к своей структуре, используя оба индекса элемента:
int getval(struct Element *ep, int n)
и по имени:
ep->a1
тогда вы застряли с каким-то трудно поддерживаемым методом переключения, который предлагали все.
Если, однако, все, что вам нужно - это доступ по индексу, а не по имени, тогда вы можете быть немного более креативным.
Прежде всего, определите тип поля:
typedef struct _FieldType
{
int size_in_bits;
} FieldType;
, а затем создайте определение структуры:
FieldType structure_def [] = { {1}, {1}, {1}, {4}, {1}, {0} };
Выше определяется структура с пятью элементами размером 1, 1, 1, 4 и 1 бит. Финал {0} обозначает конец определения.
Теперь создайте тип элемента:
typedef struct _Element
{
FieldType *fields;
} Element;
Чтобы создать экземпляр Element
:
Element *CreateElement (FieldType *field_defs)
{
/* calculate number of bits defined by field_defs */
int size = ?;
/* allocate memory */
Element *element = malloc (sizeof (Element) + (size + 7) / 8); /* replace 7 and 8 with bits per char */
element->fields = field_defs;
return element;
}
А затем для доступа к элементу:
int GetValue (Element *element, int field)
{
/* get number of bits in fields 0..(field - 1) */
int bit_offset = ?;
/* get char offset */
int byte_offset = sizeof (Element) + bit_offset / 8;
/* get pointer to byte containing start of data */
char *ptr = ((char *) element) + byte_offset;
/* extract bits of interest */
int value = ?;
return value;
}
Установка значений аналогична получению значений, только конечная часть нуждается в изменении.
Вы можете улучшить вышеперечисленное, расширив структуру FieldType
, включив в нее информацию о типе хранимого значения: char, int, float и т. Д., А затем напишите методы доступа для каждого типа, которые проверяют требуемый тип на соответствие указанному типу.