Da trilha de C Este conceito ainda não saiu como card do dia. ir para o card de hoje

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

  • union armazena diferentes tipos no mesmo endereço de memória; apenas um membro é válido por vez.
  • enum define constantes inteiras nomeadas, tornando o código mais legível e menos propenso a erros.
  • Uma tagged union usa um enum como etiqueta para indicar qual membro da union está ativo.
  • Tagged unions são úteis para representar valores heterogêneos, como em interpretadores ou protocolos.
  • O acesso ao membro errado de uma union causa comportamento indefinido; sempre verifique a etiqueta.
tagged_union.c
#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;
}

Exercícios

  1. 1
    Fácil

    Criando e usando uma union simples

    Declare uma union chamada Numero que pode armazenar um int ou um float. No main, atribua um valor inteiro, imprima-o, depois atribua um valor float e imprima-o. Observe que apenas um valor é válido por vez.

    Resolver
  2. 2
    Médio

    Enum e switch para dias da semana

    Defina um enum chamado DiaSemana com os dias de segunda a domingo. Escreva uma função imprimir_dia que recebe um DiaSemana e imprime o nome do dia usando switch. No main, teste com três dias diferentes.

    Resolver
  3. 3
    Desafio

    Tagged union para formas geométricas

    Crie uma tagged union chamada Forma que pode representar um círculo (com raio float), um retângulo (com base e altura float) ou um triângulo (com base e altura float). Use um enum para a etiqueta. Implemente funções para calcular a área de cada forma e uma função area que recebe uma Forma e retorna a área correta. No main, crie uma forma de cada tipo e imprima suas áreas.

    Resolver

Continue estudando