[C con Clase] Cuestion sobre las Uniones.

Salvador Pozo salvador en conclase.net
Jue Sep 23 13:07:07 CEST 2010


El pasado 2010-09-23 09:43:40, Alejandro escribió:
 
A> En el curso de la web, en el tema que trata las uniones, Ando perdido  por
A> mas que lo leo, no entiendo, como es posible que si tenemos una union como
A> esta:
A> union unEjemplo {
A>    int A;
A>    char B;
A>    double C;
A> } UnionEjemplo;
A> Se almacene en memoria en el mismo espacio? no se pisan unas a otras?
A> En la explicacion dice:
A> Supongamos que en nuestro ordenador, *int* ocupa cuatro bytes, *char* un
A> byte y *double* ocho bytes. La forma en que se almacena la información en la
A> unión del ejemplo sería la siguiente:
A> Y pone un grafico que de 7 bytes.
A> Miren el grafico: http://c.conclase.net/curso/index.php?cap=016#inicio

Hola:

Efectivamente, se pisan unas a otras, ya que ocupan la misma memoria física.

El gráfico al que te refieres es de ocho bytes (numerados de 0 a 7).

Las uniones tienen muchas aplicaciones, aunque generalmente se usan para tratar la misma información de formas diferentes. El ejemplo es sólo eso, un ejemplo.

La aplicación típica es, por ejemplo, esta que he extraído del API de Windows:

----8<------
typedef union _LARGE_INTEGER {  
    struct {
        DWORD LowPart;  
        LONG  HighPart; 
    };
    LONGLONG QuadPart;
} LARGE_INTEGER; 
----8<------

En esta unión se superpone una estructura y un LONGLONG.

La estructura a su vez se compone de dos valores, un DWORD y un LONG.

DWORD y LONG ocupan 32 bits, y están definidos así:

typedef unsigned long DWORD;
typedef long LONG;
typedef __int64 LONGLONG;

El tamaño de los dos componentes de la unión es el mismo: 64 bits.

Esta unión permite manipular el mismo objeto de dos formas posibles: bien como un entero de 64 bits o como dos enteros de 32 bits, uno con signo y otro sin él.

Los datos almacenados no se "pisan", ya que en ambos casos es el mismo dato. Sólo cambia el modo en que lo observamos.

Imagina otra unión:

union ejemplo {
    struct {
        char A;
        char B;
        char C;
        char D;
    };
    int x;
};

En este caso tenemos dos objetos superpuestos: cuatro caracteres y un valor entero de 32 bits. (suponiendo que int ocupa 32 bits).

La misma información almacenada en un objeto de este tipo puede ser un entero, o podemos acceder a cada uno de sus bytes como un carácter.

Por supuesto, hay otras aplicaciones, en las que los valores almacenados no pueden ser tratados de las dos maneras. Por ejemplo:

enum tipo {cadena, numero, vector};

struct ejemplo2 {
    tipo t;
    union {
        char cadena[32];
        double valor;
        int array[4];
    };
};

Esta estructura puede usarse para almacenar distintos tipos de datos. El tipo de dato se determina en función del valor de t:
- Si t vale cadena, trataremos los datos en la unión como una cadena de caracteres.
- Si t vale numero, lo trataremos como un número en coma flotante.
- Si vale vector, como un array de cuatro enteros.

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net


Más información sobre la lista de distribución Cconclase