Curso de C++ v2.0
Consultas, lista de correo 'C++ Con Clase' 'C++ Con Clase' página de entrada Librerías estándar C Tabla de contenido Contactar con Webmaster
*Introducción
*1 Toma de contacto
*2 Variables I
*3 Funciones I: Declaración y definición
*4 Operadores I
*5 Sentencias
*6 Declaración de variables
*7 Normas para la notación
*8 Cadenas de caracteres
*9 Conversión de tipos
*10 Variables II: Arrays
*11 Variables III: Estructuras
*12 Variables IV: Punteros 1
*13 Operadores II: Más operadores
*14 Operadores III: Precedencia
*15 Funciones II: Parámetros por valor y referencia
*16 Variables V: Uniones
 . Estructuras anónimas
*17 Variables VI: Punteros 2
*18 Operadores IV: De bits y condicional
*19 Definición de tipos
*20 Funciones III
*21 Funciones IV: Sobrecarga
*22 Operadores V: Sobrecarga
*23 El preprocesador
*24 Funciones V: Recursividad
*25 Variables VII: Modificadores
*26 Espacios con nombre
*27 Clases I: Definiciones
*28 Declaración de clases
*29 Constructores
*30 Destructores
*31 El puntero this
*32 Sistema de protección
*33 Modificadores para miembros
*34 Más sobre funciones
*35 Operadores sobrecargados
*36 Herencia
*37 Funciones virtuales
*38 Derivación múltiple
*39 Trabajar con ficheros
*40 Plantillas
*41 Punteros a miembros
*42 Castings
*43 Excepciones
*Ejemplos capítulos 1 a 6
*Ejemplos capítulos 8 y 9
*A Palabras reservadas C/C++
*B Trigrafos y símbolos alternativos
*C Librerías estándar
*D Streams
<< < > >>

16 Tipos de variables V: Uniones

Las uniones son un tipo especial de estructuras que permiten almacenar elementos de diferentes tipos en las mismas posiciones de memoria, aunque evidentemente no simultáneamente.

Sintaxis:

union [<tipo unión>] {
[<tipo> <nombre de variable>[, <nombre variable>, ...]] ;
 } [<variable de unión>[,<variable union>...]] ; 

El nombre de la unión es un nombre opcional para referirse a la unión.

Las variables de unión son variables declaradas del tipo de la unión, y su inclusión también es opcional.

Sin embargo, al menos uno de estos elementos debe existir, aunque ambos sean opcionales.

En el interior de una unión, entre las llaves, se pueden definir todos los elementos necesarios, del mismo modo que se declaran las variables. La particularidad es que cada elemento comenzará en la misma posición de memoria.

Las uniones pueden referenciarse completas, usando su nombre, como hacíamos con las estructuras, y también se puede acceder a los elementos en el interior de la unión usando el operador de selección (.), un punto.

También pueden declararse más variables del tipo de la unión en cualquier parte del programa, de la siguiente forma:

[union] <nombre_de_unión> <variable>[,<variable>...]; 

La palabra "union" es opcional en la declaración de variables en C++. En C es obligatoria.

Ejemplo:

#include <iostream>
using namespace std;
 
union unEjemplo { 
   int A; 
   char B; 
   double C; 
} UnionEjemplo;
 
int main() { 
   UnionEjemplo.A = 100; 
   cout << UnionEjemplo.A << endl; 
   UnionEjemplo.B = 'a'; 
   cout << UnionEjemplo.B << endl; 
   UnionEjemplo.C = 10.32; 
   cout << UnionEjemplo.C << endl; 
   cout << &UnionEjemplo.A << endl; 
   cout << (void*)&UnionEjemplo.B << endl; 
   cout << &UnionEjemplo.C << endl; 
   cout << sizeof(unEjemplo) << endl; 
   cout << sizeof(UnionEjemplo.A) << endl; 
   cout << sizeof(UnionEjemplo.B) << endl; 
   cout << sizeof(UnionEjemplo.C) << endl; 
   
   cin.get();
   return 0; 
}

Suponiendo que int ocupa dos bytes, char un byte y double 4 bytes, la forma en que se almacena la información en la unión del ejemplo es la siguiente:

[BYTE1][BYTE2][BYTE3][BYTE4]
[<----A----->]
[<-B->]
[<-----------C------------>]

Por el contrario, las mismas variables en una estructura tendrían la siguiente disposición:

[BYTE1][BYTE2][BYTE3][BYTE4][BYTE5][BYTE6][BYTE7]
[<----A----->][<-B->][<-----------C------------>]

Nota: Unas notas sobre el ejemplo:

• Observa que hemos hecho un "casting" del puntero al elemento B de la unión. Si no lo hiciéramos así, cout encontraría un puntero a char, que se considera como una cadena, y por defecto intentaría imprimir la cadena, pero nosotros queremos imprimir el puntero, así que lo convertimos a un puntero de otro tipo.
• Para averiguar el tamaño de cada campo usando "sizeof" tenemos que usar el operador de ámbito (::), y no el punto.
• Observa que el tamaño de la unión es el del elemento más grande.

Otro ejemplo, éste más práctico. Algunas veces tenemos estructuras que son elementos del mismo tipo, por ejemplo X, Y, y Z todos enteros. Pero en determinadas circunstancias, puede convenirnos acceder a ellos como si fueran un array: Coor[0], Coor[1] y Coor[2]. En este caso, la unión puede ser útil:

struct stCoor3D { 
   int X, Y, Z; 
};
 
union unCoor3D { 
   struct stCoor3D N; 
   int Coor[3]; 
} Punto; 

Podemos referirnos a la coordenada Y de estas dos formas:

Punto.N.Y
Punto.Coor[1]

Estructuras anónimas:  

Como ya vimos en el capítulo sobre estructuras, una estructura anónima es la que carece de identificador de tipo de estructura y de identificador de variables del tipo de estructura.

Por ejemplo, la misma unión del último ejemplo puede declararse de este otro modo:

union unCoor3D { 
   struct { 
      int X, Y, Z; 
   }; 
   int Coor[3]; 
} Punto;

Haciéndolo así accedemos a la coordenada Y de cualquiera de estas dos formas:

Punto.Y 
Punto.Coor[1]

Usar estructuras anónimas dentro de una unión tiene la ventaja de que nos ahorramos escribir el identificador de la estructura para acceder a sus campos. Esto no sólo es útil por el ahorro de código, sino sobre todo, porque el código es mucho más claro.

Palabras reservadas usadas en este capítulo

union.

<< < > >>
Free Web Hosting