Uma união (union
) é um tipo especial de estrutura (struct
) no qual todos os campos internos iniciam na mesma posição da memória. Em outras palavras, os campos internos são sobrepostos e somente podem armazenar um valor válido de cada vez.
Uniões são uma forma eficiente de armazenar valores de diferentes tipos em uma mesma posição de memória. A quantidade de memória ocupada por uma união corresponde ao tamanho de seu maior campo.
Exemplo de união que permite “enxergar” os bytes individuais de um inteiro sem necessidade de operações de bits ou aritmética de ponteiros:
#include <stdio.h> typedef union { int value ; unsigned char byte[sizeof(int)] ; } intParts ; int main () { intParts a ; int i ; a.value = 653459 ; for (i=0; i< sizeof(int); i++) printf ("%02x ", a.byte[i]) ; printf ("\n") ; return 0 ; }
Uniões podem ser usadas para armazenar valores de diversos tipos em uma única locação de memória. Por exemplo, a união a seguir pode ser usada para armazenar números de diversos tipos:
typedef union { short shortVal ; int intVal ; long longVal ; float floatVal ; double doubleVal ; } numericValue ;
Entretanto, como saber qual o tipo do último valor armazenado, ou seja, qual o valor corrente?
int
e tentarmos ler um float
teremos um valor errado, pois os valores são lidos byte a byte diretamente da área de memória da união, sem conversões.
#include <stdio.h> typedef union { short shortVal ; int intVal ; long longVal ; float floatVal ; double doubleVal ; } numericValue ; int main () { numericValue a ; a.shortVal = 741 ; printf ("short : %d\n\n", a.shortVal) ; a.floatVal = 327.5432 ; printf ("float : %f\n", a.floatVal) ; printf ("short : %d\n\n", a.shortVal) ; a.doubleVal = 327.5432 ; printf ("double: %lf\n", a.doubleVal) ; printf ("float : %f\n", a.floatVal) ; printf ("short : %d\n", a.shortVal) ; return 0 ; }
Para resolver esse problema pode ser usado um struct
contendo a união e uma variável que indique o tipo do último valor armazenado:
typedef struct { char type ; union { short shortVal ; int intVal ; long longVal ; float floatVal ; double doubleVal ; } ; // anonymous union } numericValue ; numericValue a ; a.intVal = 345 ; a.type = 'i' ; ... a.doubleVal = 3.141592653589793 ; a.type = 'd' ;
struct
externo que contém a união. Structs também podem ser anônimos.
Um outro uso interessante de união, no qual as moedas podem ser acessadas com nomes individuais ou como elementos de um vetor:
typedef union { struct { int quarter; int dime; int nickel; int penny; }; int coins[4]; } Coins ; Coins a ; // equivalent operations! a.dime = 34 ; a.coins[1] = 34 ;
union
, crie uma função que receba um inteiro e calcule seu quadrado, em seguida, receba um caractere e, caso maiúsculo, imprima minúsculo, caso minúsculo, imprima maiúsculo, e por último, receba uma string de no máximo 8 caracteres e imprima seu inverso.int
podem representar valores entre −2,147,483,647 e +2,147,483,647, enquanto variáveis de 32 bits do tipo unsigned int
podem representar valores entre 0 e +4,294,967,295. Crie um programa que receba um valor negativo do tipo int
e mostre qual o valor resultante da conversão para o tipo unsigned int
.char[sizeof(int)]
).