Ferramentas do usuário

Ferramentas do site


prog2:unioes

Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.

Link para esta página de comparações

Ambos lados da revisão anterior Revisão anterior
prog2:unioes [2019/05/21 14:53]
maziero
prog2:unioes [2019/05/21 14:54] (atual)
maziero
Linha 1: Linha 1:
 +====== Uniões ======
 +
 +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:
 + 
 +<code c union.c>
 +#include <​stdio.h>​
 +
 +// guarda um inteiro OU um vetor de 4 bytes
 +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 ;
 +}
 +</​code>​
 +
 +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:
 +
 +<code c>
 +typedef union
 +{
 +  short  shortVal ;
 +  int    intVal ;
 +  long   ​longVal ;
 +  float  floatVal ;
 +  double doubleVal ;
 +} numericValue ;
 +</​code>​
 +
 +Entretanto, como saber qual o tipo do último valor armazenado, ou seja, qual o valor corrente?
 +
 +<note warning>
 +Se armazenarmos um ''​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.
 +</​note>​
 +
 +<code c union2.c>​
 +#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 ;
 +}
 +</​code>​
 +
 +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:
 +
 +<code c>
 +typedef struct
 +{
 +  char type ;
 +  union                    // ATTENTION: "​anonymous"​ union
 +  {
 +    short  shortVal ;
 +    int    intVal ;
 +    long   ​longVal ;
 +    float  floatVal ;
 +    double doubleVal ;
 +  } ;
 +} numericValue ;
 +
 +numericValue a ;
 +
 +a.intVal = 345 ;
 +a.type = '​i'​ ;
 +
 +...
 +
 +a.doubleVal = 3.141592653589793 ;
 +a.type = '​d'​ ;
 +</​code>​
 +
 +<note tip>
 +O exemplo acima traz uma união **anônima**,​ ou seja, sem nome. Nesse caso, os membros da união são considerados como membros do ''​struct''​ externo que contém a união. Structs também podem ser anônimos.
 +</​note>​
 +
 +Um outro uso interessante de união, no qual as moedas podem ser acessadas com nomes individuais ou como elementos de um vetor:
 +
 +<code c>
 +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 ;
 +</​code>​
 +
 +===== Exercícios =====
 +
 +  - Utilizando uma única variável ''​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.
 +  - Variáveis de 32 bits do tipo ''​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''​.
 +  - Utilizando unions, crie um programa capaz de receber um determinado valor e calcular o módulo de 256 desse valor (dica: utilize ''​char[sizeof(int)]''​).
  
prog2/unioes.txt · Última modificação: 2019/05/21 14:54 por maziero