Article View: es.comp.os.linux.programacion
Article #15341Re: Uniones
From: Xavier Montero
Date: Mon, 10 Jul 2000 00:00
Date: Mon, 10 Jul 2000 00:00
234 lines
8630 bytes
8630 bytes
kuantiko escribi�:
>
> Hola a todos.
>
> �Podr�a alguien darme una breve explicaci�n de lo que es una uni�n
> en C? Nunca las he usado, y lo �nico que he le�do es que son como una
> estrcutura en la que todos los elementos comparten direcci�n de
> memoria. �Qu� utilidad tienen?
Sup�n que quieres gestionar un museo que contiene 3 tipos de obras
de arte: Pinturas, esculturas y literatura escrita.
Hay una parte com�n a cada obra de arte: T�tulo, autor, lugar de
creaci�n,
fecha de inicio, fecha de acabado, estado de conservaci�n, etc.
Pero hay una serie de datos que son pertenecientes a cada tipo de
obra, por ejemlo, de las pinturas podemos almacenar el tipo de
pintura usado, la tonalidad general del cuadro, el tipo de tela,
si est� barnizado o no y las dimensiones X * Y. Para las esculturas
podemos almacenar
la materia prima (madera, yeso, m�rmol, etc) y las dimensiones X * Y *
Z.
Para las obras literarias podr�amos almacenar el n�mero de p�ginas,
el tipo de papel usado y si las tapas son de cart�n, cartulina o
cart�n reforzado.
Para gestionar el muso, vamos a asumir que hay que carga un n�mero
grande de obras en memoria para almacenarlas, clasificarlas, ordenarlas,
etc. Por ello no queremos desperdiciar demasiados bytes no usados.
[Nota: Cuando declare tipos siempre les preceder� con t para
evitar posteriores confuciones, por ejemplo un tipo "d�a de
semana" le llamar�a tdia. Es costumbre personal, cada uno que programe
a su gusto, evidentemente.]
Usaremos algunos enums:
tobra ------> {pintura, escultura, literatura}
testado ----> {muy_bueno, bueno, regular, malo, muy_malo}
tpintura ---> {acuarela, �leo, carb�n}
ttela ------> {tela_a, tela_b, etc} (No tengo ni p**a idea de nombres de
telas)
tbool ------> {true = -1, false}
tescultura -> {madera, yeso, marmol}
tpapel -----> {normal, satinado/*, etc*/}
ttapas -----> {carton_reforzado, carton, cartulina}
y as� construyes todos los tipos necesarios para luego escribir
lo que piensas.
Por ejemplo, si el tipo de obra se almacena en una variable
llamada t, la declaraci�n debe ser del tipo:
tobra t;
al estilo "int t;", pero es m�s l�gico escribir "tobra t;" puesto
que �se es su tipo de dato y no otro.
Repasemos: para clasificar una obra necesito:
T�tulo, autor, lugar de creaci�n, fecha de inicio, fecha de acabado,
estado de conservaci�n, etc.
Para el t�tulo, autor, lugar de creaci�n usaremos cadenas. Asumo que hay
un typedef que define el tipo "tcadena" para que sea un char[100] o un
char*
o lo que m�s te guste. Para el ejemplo da igual. Lo mismo para las
fechas.
Ahora me es igual si est� en formato dd/mm/yyyy en un string o es una
estructura o lo que sea. Asumo que hay un tipo tfecha.
Adem�s necesitar� almacenar con los datos de la obra el propio tipo de
obra y sus datos adicionales. Ah� viene el union. Como una obra
no puede ser literatura y estatua a la vez, reutilizo sus datos
extras.
El tipo de obra es del tipo tobra. Los datos adicionales todav�a
no los he analizado, pero les llamar� textra.
/*Aqu� rellenar� el c�digo necesario para textra*/
struct tobra_con_todo
{
tobra tipo; /* Importante saber de qu� tipo es */
tcadena titulo;
tcadena autor;
tcadena lugar
tfecha inicio;
tfecha fin;
testado estado;
textra infoadicional; /* Hasta que definamos textra infoadicional
contiene algo que no sabemos qu� es pero que
va a representar todo lo "raro" que no
es com�n a los tipos de obras */
};
Si nos fijamos, la info adicional de las pinturas podr�a ser as�:
struct tinfoextrapintura
{
tpintura pintura;
ttonalidad tonalidad; /* no he definido ttonalidad
pero ser�a un tipo capaz de contener
los datos que representen una tonalidad
determinada */
ttela tela;
tbool barnizado;
int x;
int y;
}
Para las esculturas:
struct tinfoextraescultura
{
tescultura material;
int x;
int y;
int z;
}
Para las obras literarias:
struct tinfoextraliteratura
{
int numeropaginas;
tpapel papel;
ttapas tapas;
}
Entonces, a diferencia de una estructura donde, por ejemplo almacenamos
numero de p�ginas _Y_ papel _Y_ tapas, ahora necesitamos una estructura
especial tinfoextra donde almacenamos inofpintura _O_ infoescultura
_O_ infoliteratura
y se hace con la union:
union tinfoextra
{
struct tinfoextrapintura infopintura;
struct tinfoextraescultura infoescultura;
struct tinfoextraliteratura infoliteratura;
}
con alg�n typedef puedes convertir "struct tinfoextra" a "textra", o en
el momento de definirla, as�:
typedef union tinfoextra
{
struct tinfoextrapintura infopintura;
struct tinfoextraescultura infoescultura;
struct tinfoextraliteratura infoliteratura;
} textra;
As�, la declaraci�n
textra i;
declara una variable llamada "i" de tipo "textra", pero "textra", seg�n
el typedef, no es m�s que un alias de "union tinfoextra".
De tal forma, i tiene tres miembros:
i.infopintura, i.infoescultura e i.infoliteratura, y cada uno, los
suyos pertiunentes. As�, si i es informaci�n extra relativa a una
novela, podemos saber su n�mero de p�ginas as�:
npag = i.infoliteratura.numeropaginas;
Lo �nico que sucede es que si escribo en i.infopintura.pintura, siendo
i infomaci�n de literatura, destrozo la info de la literatura porque
est�n en las mismas posiciones de memoria. Por eso, durante todo el
ejemplo, he supuesto que es informaci�n disjunta. Si almaceno datos
de pintura en una obra de literatura, es porque el programa funciona
mal. Por ello una union suele usarse dentro de una estructura m�s
grande que mantiene, entre otras cosas, el tipo de datos mantenidos
en la uni�n. Por ejemplo en nuestra estructura tobra_con_todo se
mantiene un dato tobra, para saber si es pintura, escultura o literatura
y poder tratar la infoemraci�n extra adecuadamente.
Hay numerosos ejemplos donde poder usar uniones:
Si almaceno un n�mero complejo puede hacerlo guardando "parte real +
parte
imaginaria" _O_ "m�dulo y �ngulo"
Si almaceno componentes de ordenador puede almacenar n�meros de serie
y en funci�n del tipo de compoennete unas u otras cosas: Monitores y
targetas
gr�ficas: Resoluci�n, _O_ cpu's y placas base: velocidad de proceso _O_
memoria y discos duros: Capacidad en bytes
Si almaceno fichas de "personas" en una empresa puedo poner en el
denominador
com�n el nombre, cif, poblaci�n, etc, y si es cliente almaceno unas
cosas _O_
si es proveedor otras _O_ si es trabajador otras (Este ejemplo no est�
muy
acertado porque un trabajador puede ser un cliente, o un cliente puede a
la
vex proveer materiales o servicios, pero si una persona pudiera ser S�LO
proveedor
o cliente o trabajador ser�a acertado).
Si almaceno fichas de alumnos que han terminado el curso, en la uni�n
puedo
almacenar la nota sacada para los aprobados y la fecha de repetici�n del
examen para los suspendidos.
Si un sat�lite almacena fotos de la tierra puede almacenar en una parte
com�n
si la foto es de infrarrojos o de luz normal y en cada caso almacenar
datos
distintos en una uni�n, por ejemplo, para infrarrojos, almacenar la
longitud
de onda captada y otras cosas que afecten a la captaci�n mediante
infrarrojos y
en caso de ser luz solar, almacenar si es de dia o de nocha (o lo que
sea
necesario) para fichar correctamente un foto sacada con luz natural.
Y asi, podr�amos poner un sinf�n de ejemplos m�s.
[Nota: Para los puristas:
Donde pongo "tobra" deber�a poner "ttipoobra"
Donde pongo "tobra_con_todo" deber�a poner "tobra"
pero no deseaba usar m�s de lo necesario las letras "*tipo*" para no
liar]
--
--------------------------------------------------------------
Chao!
Xavi
http://www.dsitelecom.com/ (Digital Sound Items)
--------------------------------------------------------------
Technical Details
Message-ID:
<3969265B.884389C2@dsitelecom.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<39683D85.4A4E4957@teleline.es>Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII X-Google-Thread: f86c8,d9e2de11a81b412f X-Google-Attributes: gidf86c8,public From: Xavier Montero <xmontero@dsitelecom.com> Subject: Re: Uniones Date: 2000/07/10 Message-ID: <3969265B.884389C2@dsitelecom.com> X-Deja-AN: 644401302 Content-Transfer-Encoding: 8bit References: <39683D85.4A4E4957@teleline.es> X-Accept-Language: en Content-Type: text/plain; charset=iso-8859-1 Organization: Digital Sound Items Mime-Version: 1.0 Newsgroups: es.comp.os.linux.programacion