uso da union

Programação C em geral

Moderadores: 51, guest2003

uso da union

Mensagempor esorato » 07 Jan 2011 09:50

Olá a todos,

Estou estudando um pouco de linguagem C e pintou uma dúvida:

Quando utilizo union a mesma área de memória é compartilhada pela variáveis definidas na union. Se eu definir na union um int e um char, em que posição da memória será alocado o char, no MSB ou no LSB do int ?
esorato
 
Mensagens: 3
Registrado em: 09 Jan 2007 12:31

Mensagempor B-EAGLE » 07 Jan 2011 10:01

qual ferramenta tá usando?
B-EAGLE
Word
 
Mensagens: 847
Registrado em: 19 Out 2006 14:12
Localização: Campo Grande - MS

Mensagempor esorato » 07 Jan 2011 10:10

Bom...não estou utilizando uma ferramenta específica. Estou lendo um livro e pintou essa dúvida.
esorato
 
Mensagens: 3
Registrado em: 09 Jan 2007 12:31

Mensagempor andre_luis » 07 Jan 2011 10:21

Particularmente, acredito que isso possa variar conforme o nível de otimização configurada no compilador, se por velocidade, ou consumo de memória.

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor barboza » 07 Jan 2011 10:23

Isso vai depender da arquitetura que esta trabalhando, 8, 16 ou 32 bits.


My Guest.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor esorato » 07 Jan 2011 10:34

Depende da arquitetura ou do compilador ?
Vamos imaginar uma arquitetura de 8 bits. Um int deve ocupar duas posições de memória e um char uma só.
Ainda fica a possíbilidade do compilador alocar o que seria o MSB ou o LSB do int.
esorato
 
Mensagens: 3
Registrado em: 09 Jan 2007 12:31

Mensagempor barboza » 07 Jan 2011 10:36

esorato escreveu:Depende da arquitetura ou do compilador ?
Vamos imaginar uma arquitetura de 8 bits. Um int deve ocupar duas posições de memória e um char uma só.
Ainda fica a possíbilidade do compilador alocar o que seria o MSB ou o LSB do int.


Considerando que o compilador vai alocar a memória da forma que o MCU execute, a dependência esta na arquitetura.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor vtrx » 07 Jan 2011 10:44

Provavelmente vai ficar no LSB,pois no seu caso o tamanho da Union é equivalente ao Int e seguindo padrão comumente usado,o LSB é que seria preenchido.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor barboza » 07 Jan 2011 10:47

vtrx escreveu:Provavelmente vai ficar no LSB,pois no seu caso o tamanho da Union é equivalente ao Int e seguindo padrão comumente usado,o LSB é que seria preenchido.


Na arquitetura little endian sim.

x = LSB + MSB
char1 = LSB (int)
char2 = MSB (int)


union
{
int x;
char char1;
char char2;
}
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor msamsoniuk » 07 Jan 2011 11:07

a ideia do union eh armazenar as duas ou mais diferentes variaveis no mesmo endereco. entao segundo esse conceito temos a seguinte alocacao a partir de um endereco:

endereco+0: int char
endereco+1: int
endereco+2: int
endereco+3: int

eu apostaria 1 centavo que o char sempre fica no endereco zero, ou seja, eh um conceito que nao deveria mudar de compilador para compilador. nao seria otimizado vc ter um union no endereco do int e ter que somar um offset para acessar o char.

agora, se tomarmos isso como verdade, surge um problema de arquitetura: o endereco zero eh o byte mais significativo nas maquinas big-endian e eh byte menos significativo nas maquinas little-endian.

se vc armazenar 0x12345678 e fizer um dump da memoria, vai ter:
cpu 68k: 0x12345678
cpu x86: 0x78563412

assim, no big-endian o char vai ter valor 0x12 e no little-endian vai ter valor 0x78.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor chipselect » 07 Jan 2011 11:38

se quiser testar na prática, faz assim (para 32 bits):

//---------------------------------------------------------------------------

#include <stdio.h>

typedef union {
int inteiro;
char caracter[4];
}Teste;

int main(int argc, char* argv[])
{
Teste test;
Teste2 test2;

test.inteiro = 0x00010203;
test2.inteiro = 0x00010203;

printf("valor dos chars: 0x%02x 0x%02x 0x%02x 0x%02x\n",
(unsigned int) test.caracter[0],
(unsigned int) test.caracter[1],
(unsigned int) test.caracter[2],
(unsigned int) test.caracter[3]);

printf("\n\nTeste 2: 0x%02x\n", (unsigned int) test2.caracter);
getchar();
return 0;
}
//---------------------------------------------------------------------------
chipselect
Word
 
Mensagens: 744
Registrado em: 16 Out 2006 18:50

Mensagempor RobL » 10 Jan 2011 17:02

Tanto faz ser Litle ou Big Endian. Por exemplo, considerando um unsigned int com 2 bytes e um char em uma union, o char estará sempre no byte de menor ordem.
Portanto o char, se litle endian, estará no de menor endereço da memo, dessa variável. Se big endian, estará no maior endereço na memo desse inteiro, mas no byte de menor ordem.

Por que ?
Já que a Union tem como principal ideia, reservar um único espaço, na memória, para todos os seus membros, visto ainda que, somente um membro por vez estará no espaço reservado para a union, toda a compatibilidade de outros tipos de dados, especialmente ponteiros, exigirão que em uma union, um char esteja no byte de mais baixa ordem, ou seja, para onde um ponteiro para essa Union estaria apontando.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56


Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x