Мне нравится ответ Нейта, так что не меняйте свой выбор, но есть небольшая вариация с использованием анонимного объединения, которое позволит вам обращаться к членам союза напрямую, без необходимости использовать тег объединения дляссылка на элемент.
Это было введено со стандартом C11 в 6.7.2.1 Спецификаторы структуры и объединения (p13) .Это просто обеспечивает немного синтаксического сокращения.Например, используя анонимный союз в структуре, например,
typedef struct { /* struct containing tag and union between int/char[] */
int tag;
union { /* anonymous union allow you to refer */
char str[MAXC]; /* to members as members of the struct */
int number;
};
} mytype;
...
mytype array[] = {{ISSTR, {"helo"}}, {ISINT, {{2}}}, {ISSTR, {"watkins"}}};
Ваш доступ к членам объединения будет:
printf ("The string is: %s\n", array[i].str);
или
printf ("The number is: %d\n", array[i].number);
(снет тега объединения между array[i]
и str
или number
)
Если поместить его в целом, ваш пример будет:
#include <stdio.h>
#define MAXC 16 /* if you need a constant, #define one (or more) */
enum { ISSTR, ISINT }; /* enum can provide global constants as well */
typedef struct { /* struct containing tag and union between int/char[] */
int tag;
union { /* anonymous union allow you to refer */
char str[MAXC]; /* to members as members of the struct */
int number;
};
} mytype;
int main (void) {
mytype array[] = {{ISSTR, {"helo"}}, {ISINT, {{2}}}, {ISSTR, {"watkins"}}};
int array_len = sizeof array/sizeof *array;
for (int i=0; i<array_len; i++) {
// how to do this in C?
if (array[i].tag == ISSTR) /* if tag ISSTR element is string */
printf ("The string is: %s\n", array[i].str);
else if (array[i].tag == ISINT) /* if ISINT, element holds an int */
printf ("The number is: %d\n", array[i].number);
else
fputs ("As Nate put it, things are horribly wrong...\n", stderr);
}
}
Пример использования / вывода
$ ./bin/structunion
The string is: helo
The number is: 2
The string is: watkins
Имейте в виду, что это было введено в C11, в C99 вы не найдете анонимную структуру или анонимное объединение (хотя некоторые компиляторы предоставили в качестве расширения)