C Tipos Intermediário
Unions e enums
Em C, union e enum são ferramentas poderosas para modelar dados de forma eficiente e expressiva. Uma union permite que diferentes tipos compartilhem o mesmo espaço de memória, enquanto um enum cria um conjunto de constantes inteiras nomeadas, melhorando a legibilidade do código.
Uma tagged union (união etiquetada) combina os dois conceitos: um enum atua como etiqueta indicando qual membro da union está ativo no momento. Isso é essencial para criar tipos variantes seguros, como os usados em interpretadores, formatos de arquivo e protocolos de rede.
Neste card, você aprenderá a declarar unions e enums, a usá-los juntos para criar tagged unions e verá exemplos práticos de como essa combinação resolve problemas reais de programação em C.
Pontos-chave
unionarmazena diferentes tipos no mesmo endereço de memória; apenas um membro é válido por vez.enumdefine constantes inteiras nomeadas, tornando o código mais legível e menos propenso a erros.- Uma
tagged unionusa umenumcomo etiqueta para indicar qual membro daunionestá ativo. - Tagged unions são úteis para representar valores heterogêneos, como em interpretadores ou protocolos.
- O acesso ao membro errado de uma
unioncausa comportamento indefinido; sempre verifique a etiqueta.
#include <stdio.h>
#include <string.h>
// Enum que define os tipos possíveis
typedef enum {
TIPO_INT,
TIPO_FLOAT,
TIPO_STRING
} Tipo;
// Union que armazena diferentes tipos
typedef union {
int i;
float f;
char s[20];
} Valor;
// Tagged union: combina enum e union
typedef struct {
Tipo tipo;
Valor valor;
} Variante;
// Função que imprime o valor com base na etiqueta
void imprimir(Variante v) {
switch (v.tipo) {
case TIPO_INT:
printf("Inteiro: %d\n", v.valor.i);
break;
case TIPO_FLOAT:
printf("Float: %.2f\n", v.valor.f);
break;
case TIPO_STRING:
printf("String: %s\n", v.valor.s);
break;
}
}
int main() {
Variante v1 = { .tipo = TIPO_INT, .valor.i = 42 };
Variante v2 = { .tipo = TIPO_FLOAT, .valor.f = 3.14 };
Variante v3 = { .tipo = TIPO_STRING, .valor.s = "Olá, C!" };
imprimir(v1);
imprimir(v2);
imprimir(v3);
return 0;
}