[RESOLVIDO] (C) Como a union consegue compartilhar um espaço de memória com muitas variáveis?

2 respostas
Erick_Ribeiro

Olá galera.
Em C, existe um comando chamado union, que cria um tipo de dado e permite que suas variáveis compartilhem o mesmo espaço na memória . Exemplo de definição de uma union:

union u_type { int i; char ch; } my_union;

Quando a union é declarada, o compilador cria uma variável para conter o maior tipo de variável da union, e armazena todas as variáveis nesse espaço.

Supondo que um int tenha 4 bytes e um char tenha 1 byte, serão reservados 4 bytes na memória, e o 1º byte será usado tanto pela variável do tipo int quanto a variável char.

int main(void) {
    cnvt.i = 12;
    cnvt.ch = 'e';
    
    
    printf("%lu\n", sizeof(cnvt.i); //imprime 4
    printf("%lu\n", sizeof(cnvt.ch); //imprime 1

    printf("%lu", sizeof(cnvt)); //imprime 4
    return 0;
}

A minha dúvida é: como a union consegue gravar e manter a integridade desses dados?

2 Respostas

ViniGodoy

Para o computador, TUDO são apenas bytes na memória. O union simplesmente reserva os bytes e faz com que apontem para o mesmo endereço de memória.

Não há dificuldade nenhuma em "manter integridade". Se o valor vai ser coerente ou não, é problema do programador.

Há coisas bem interessantes que se pode fazer com unions, como isso aqui:

public union Color { unsigned int value; struct { unsigned char r; unsigned char g; unsigned char b; unsigned char a; }; unsigned char values[4]; }

Isso permite manipular os canais individuais de uma cor, sem a necessidade de fazer shift. Também permite usar a cor como um vetor quando conveniente. Ou obter seu valor inteiro completo. Por exemplo:

Color color;
int i;
color.r = 255;
color.g = 127;
color.b = 200;
color.a = 255;

for (i = 0; i < 4; i++) {
   printf("Canal de cor: %d", color.values[i]);
}

printf("Valor inteiro da cor: %d", color.value);

color.value = 0x00FF0AFA;
for (i = 0; i < 4; i++) {
   printf("Canal de cor: %d", color.values[i]);
}
Erick_Ribeiro
ViniGodoy:
Para o computador, TUDO são apenas bytes na memória. O union simplesmente reserva os bytes e faz com que apontem para o mesmo endereço de memória.

Não há dificuldade nenhuma em "manter integridade". Se o valor vai ser coerente ou não, é problema do programador.

Há coisas bem interessantes que se pode fazer com unions, como isso aqui:

public union Color {
   unsigned int value;
   struct {
      unsigned char r;
      unsigned char g;
      unsigned char b;
      unsigned char a;
  };
  unsigned char values[4];
}

Isso permite manipular os canais individuais de uma cor, sem a necessidade de fazer shift. Também permite usar a cor como um vetor quando conveniente. Ou obter seu valor inteiro completo. Por exemplo:

Color color;
int i;
color.r = 255;
color.g = 127;
color.b = 200;
color.a = 255;

for (i = 0; i < 4; i++) {
   printf("Canal de cor: %d", color.values[i]);
}

printf("Valor inteiro da cor:", color.value);

color.value = 0x00FF0AFA;
for (i = 0; i < 4; i++) {
   printf("Canal de cor: %d", color.values[i]);
}

Nossa, muito interessante isso! Com esse exemplo(uso mais claro do que o que eu vi no livro) agora entendi o funcionamento da union. Muito obrigado, Vini :)
Eu pensava que eu poderia alterar o valor de uma variável sem mudar as outras.

Criado 1 de novembro de 2013
Ultima resposta 1 de nov. de 2013
Respostas 2
Participantes 2