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

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?

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]);
}

[quote=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:

[code]
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]);
}
[/code][/quote]

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 :slight_smile:
Eu pensava que eu poderia alterar o valor de uma variável sem mudar as outras.