Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden
o union serve especificamente para agrupar dados em um mesmo espaço de memória, os dados podem ser desde bits e bytes simples até estruturas de dados complexas.
Suponha que você está em uma CPU de 32 bits em que um char vale 1 byte, um short 2 bytes e um long 4 bytes, então:
Isso significa que o dado1 foi alinhado no maior tipo de dado, no caso o long de 4 bytes, e como o último valor setado foi o membro c da estrutura, todos os outros valores receberam os valores com o espaço que eles reservaram
32 24 16 8 bits
00000000 00100100 11111001 01010101
-------- -------- -------- -------- c = 242312533
-------- -------- b = 25941
-------- a = 85
É muito usado em conjunto com enum's para identificar qual o campo foi setado.
Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden
5. Re: Union em C
paulo1205usa Ubuntu
Post recolhido
Enviado em 19/01/2016 - 00:52h
union é usado em casos em que você pode sobrepor dados em memória, permitindo interpretá-los de mais de um modo diferente.
O tamanho de um union é igual ao tamanho do maior dos seus membros, e todos os membros são alinhados em memória pelo primeiro endereço. Por exemplo, veja o código abaixo (a saída assumem que se esteja usando uma máquina little-endian).
printf("&union_var: %p\n", &union_var); // todos vão imprimir o mesmo endereço
printf("&union_var.bytes: %p\n", &union_var.bytes); // todos vão imprimir o mesmo endereço
printf("&union_var.word: %p\n", &union_var.word); // todos vão imprimir o mesmo endereço
printf("&union_var.long_word: %p\n", &union_var.long_word); // todos vão imprimir o mesmo endereço
printf("&union_var.string: %p\n\n", &union_var.string); // todos vão imprimir o mesmo endereço
strcpy(union_var.string, "paulo1205");
printf("union_var.bytes[0]: %02hhX\n", union_var.bytes[0]); // imprime "70" (p)
printf("union_var.word: %08X\n", union_var.word); // imprime "6C756170" (l, u, a, p)
printf("union_var.long_word: %016" PRIX64 "\n", union_var.long_word); // imprime "3032316F6C756170" (0, 2, 1, o, l, u, a, p)
printf("union_var.string: %s\n\n", union_var.string); // imprime "paulo1205"
union_var.bytes[0]++; // incrementa primeiro byte
union_var.word++; // incrementa palavra de 32 bits
union_var.long_word++; // incrementa palavra de 64 bits
printf("union_var.string: %s\n", union_var.string); // imprime "saulo1205"
return 0;
}
Outro exemplo didático, para brincar de examinar como é a forma interna de representar números de ponto flutuante da máquina.
Poucas vezes usei union em programas meus. No entanto, uma vez eu fiz um programa para controle de um no-break, e ele tinha uma palavra de status a que às vezes era melhor aceder de uma vez (membro do tipo intvalue), e noutras através dos flags individuais (bit fields de uma estrutura chamada flags). Eu acabei definindo uma union com a seguinte cara (o tratamento de little e big endian é porque o programa rodava tanto em PCs como em um servidor Sun/SPARC).
union UPS_PSW {
int value;
struct {
#if BYTE_ORDER == LITTLE_ENDIAN
int alarm:1; /* Alarm sound enabled */
int shutdown:1; /* Shutdown sequence initiated */
int selftest:1; /* Self test active */
int outputpower:1; /* Power on outputs active (?) */
int reserved:1; /* Reserved (unused) */
int badbat:1; /* Battery is bad or needs to be replaced (?) */
int lowbat:1; /* Battery voltage is low */
int powerfail:1; /* Power failure */
int space:sizeof(int)*8-8; /* padding space */
#elif BYTE_ORDER == BIG_ENDIAN
int space:sizeof(int)*8-8; /* padding space */
int powerfail:1; /* Power failure */
int lowbat:1; /* Battery voltage is low */
int badbat:1; /* Battery is bad or needs to be replaced (?) */
int reserved:1; /* Reserved (unused) */
int outputpower:1; /* Power on outputs active (?) */
int selftest:1; /* Self test active */
int shutdown:1; /* Shutdown sequence initiated */
int alarm:1; /* Alarm sound enabled */
#endif
} flags;
};
Usamos cookies essenciais para manter o site funcionando e Google Analytics para métricas de audiência. Cookies de anúncios só serão carregados se você permitir.