Ajude nosso projeto a se manter online.

Union em C++

 Neste pequeno tutorial de nosso curso de C++, vamos aprender sobre uma estrutura de dados chamada union.

O que é uma UNION

UNION é mais ou menos parecido com uma estrutura. Mas vamos entender melhor como funcionam as estruturas, para entender como funcionam as unions.

Quando temos uma struct com um char, um int e um float, essas três variáveis tem espaços reservados na memória e estão em posições sequenciais.

Ou seja, tem um local pro char, os bytes do lado são reservados pro inteiro e os bytes seguintes são alocados pro float, e ponto final.

No caso de uma union, as variáveis não ocupam regiões diferentes e muito menos sequenciais, elas ocupam a mesma posição.

As unions são usadas quando queremos usar uma informação OU outra, da estrutura de dado. Na struct, podemos usar quantas e quais quisermos. Na union, podemos declarar várias variáveis dentro dela, mas somente uma, de cada vez, vai ocupar a memória.

Na prática, elas são usadas para economizar memória, principalmente em sistemas que tem poucos recursos ou quando você quer fazer algum software bem otimizado.

Como declarar e usar UNION em C++

A declaração se faz da seguinte maneira:

union Name
{
   //variables
};

Ou seja, idêntico a maneira como definimos structs, mas usamos a palavra-chave union.

Por exemplo, vamos declarar uma union que vai ser usada para definir um item de um supermercado. Os itens podem ser definidos tanto por volume (água, cerveja, produtos de limpeza etc) como por unidades (papel higiênico, biscoito etc).

Então, podemos fazer:

#include <iostream>
using namespace std;

union Item
{
   float volume;
   int unit;
};


int main()
{
    Item item;
    item.volume = 1.1;

    cout << item.volume <<endl;

    return 0;
}

Ao redor, vemos que aparece o valor correto: 1.1
Agora rode o código abaixo:

#include <iostream>
using namespace std;

union Item
{
   float volume;
   int unit;
};


int main()
{
    Item item;
    item.volume = 1.1;
    item.unit = 3;

    cout << item.volume <<endl;

    return 0;
}

Aparece: 4.2039e-45 como resultado.
Estranho?

Ocorre o seguinte. Nossa union tem um float e um int. Como o float ocupa mais espaço, o tamanho da union é o tamanho de uma variável do tipo float na sua máquina.

Quando fizemos: item.volume = 1.1
Estamos colocando o valor '1.1' no bloco de memória da union.

Depois, colocamos o inteiro '3', nesse bloco de memória. Porém, quando vamos imprimir o resultado no cout, imprimimos o bloco de float. O correto seria fazer:
cout << item.unit <<endl;

Pois foi colocado um inteiro, por último, na union.

Vamos para um exemplo mais prático e realista. Vamos definir uma union que vai representar um Token, onde você vai pedir para o usuário um dígito numérico ou uma letra do alfabeto, vamos armazenar essa informação na variável 'var' do tipo char.

Usamos a função isdigit() pra saber se é digito ou não. Se for, armazenamos o valor na union como um inteiro, transformando a variável 'var' em inteiro (var-'0'), em mytoken.number

Se não for dígito, é letra, então armazenamos o valor digitado em mytoken.letter

E prontinho. O que o usuário escrever vai ser armazenado na 'number' OU na 'letter', jamais nas duas, economizando assim, memória. Veja o código:

#include <iostream>
using namespace std;

union Token
{
   int number;
   char letter;
};


int main()
{
    Token mytoken;
    char var;

    cout << "Digite um dígito ou caractere: ";
    cin >> var;

    if(isdigit(var)){
        mytoken.number =var-'0';
        cout << "Numero: " << mytoken.number<<endl;
    }
    else{
        mytoken.letter = var;
        cout << "Letra: " << mytoken.letter<<endl;
    }

    return 0;
}
E como dissemos, as unions se parecem muito com as structs. Assim, podemos criar um array de unions, passar union para função, fazer return de union, colocar ponteiro dentro de union e usar o operador ->, e tudo mais que você desejar.

Se um dia precisar fazer um código para um timer de Microondas ou sistema de um relógio digital ou calculadora, onde a memória é recurso SUPER escasso, você pode usar union.

Nenhum comentário:

Postar um comentário