Union em C

1. Union em C

Perfil removido
removido

(usa Nenhuma)

Enviado em 18/01/2016 - 21:30h

O comando union possui utilidade em C em quais circunstâncias?

----------------------------------------------------------------------------------------------------------------
http://24.media.tumblr.com/tumblr_m62bwpSi291qdlh1io1_250.gif

# apt-get purge systemd

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



  


2. Re: Union em C

Arthur J. Hoch
Arthur_Hoch

(usa FreeBSD)

Enviado em 18/01/2016 - 21:34h

Eu uso pra fazer isso:

net.send("Teste");

Crio ponteiros que apontam para funções. :D


3. Re: Union em C

Alexandre Mulatinho
mulatinho

(usa Slackware)

Enviado em 18/01/2016 - 23:31h

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:

union Dado {
char a;
short b;
long c;
};

int main(void) {
union Dado dado1;

dado1.a = 20;
dado1.b = 16422;
dado1.c = 242312533;

printf("resultado %d %d %ld\n", dado1.a, dado1.b, dado1.c);

return 0;
}


O resultado pode parecer estranho a primeira vista:

MacMini:~ alex$ ./tmp/test1 
resultado 85 25941 242312533


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.


4. Re: Union em C

Perfil removido
removido

(usa Nenhuma)

Enviado em 19/01/2016 - 00:03h

Está ficando mais claro.

----------------------------------------------------------------------------------------------------------------
http://24.media.tumblr.com/tumblr_m62bwpSi291qdlh1io1_250.gif

# apt-get purge systemd

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

Paulo
paulo1205

(usa Ubuntu)

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).

#include <inttypes.h>
#include <stdio.h>
#include <string.h>

union teste {
uint8_t bytes[4];
uint32_t word;
uint64_t long_word;
char string[40];
} union_var;

int main(void){
printf("sizeof union_var: %zd\n", sizeof union_var); // imprime 40
printf("sizeof union_var.bytes: %zd\n", sizeof union_var.bytes); // imprime 4
printf("sizeof union_var.word: %zd\n", sizeof union_var.word); // imprime 4
printf("sizeof union_var.long_word: %zd\n", sizeof union_var.long_word); // imprime 8
printf("sizeof union_var.string: %zd\n\n", sizeof union_var.string); // imprime 40

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.

union fp_test_f {
float f;
uint8_t bytes[sizeof(float)];
uint32_t i32s[sizeof(float)/sizeof(uint32_t)>0? sizeof(float)/sizeof(uint32_t): 1];
};

union fp_test_d {
double d;
uint8_t bytes[sizeof(double)];
uint32_t i32s[sizeof(double)/sizeof(uint32_t)>0? sizeof(double)/sizeof(uint32_t): 1];
};


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 int value), 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;
};




  



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts