You are on page 1of 37

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I.

Gestin/Sistemas

10

MDULOS

Contenido
_____________________________________________________________________
10.1.- Introduccin.
10.1.1.- Ventajas de la modularizacin de programas.
10.1.2.- Creacin de un proyecto con Dev-C++.
10.2.- Mdulos de biblioteca.
10.2.1.- Espacios de nombres.
10.2.2.- Mdulos de Definicin.
10.2.3.- Mdulos de Implementacin.
10.2.4.- Ejemplo. El mdulo Mcomplejo.
10.3.- Compilacin separada.
10.4.- Estructuras de Datos Avanzadas.
10.4.1.- Pilas.
10.4.2.- Colas.
10.4.3.- rboles Binarios.
10.5.- Un Ejemplo Completo.
Ejercicios
_____________________________________________________________________

10.1.- Introduccin
Para entender el concepto de mdulo, pinsese que se nos encargara disear un automvil.
Seguramente lo haramos definiendo las distintas partes independientes que lo constituyen
(carrocera, motor, sistema elctrico, transmisin, etc.) as como la manera de conectar estos
sistemas entre s. La definicin de estos sistemas (mdulos) se hace de manera que sean lo
ms independientes posible unos de otros. Esta es la esencia de una buena modularidad.
Igualmente, cualquier programa real est compuesto por varias partes separadas.
Hasta ahora hemos utilizado los procedimientos y funciones para escribir estas partes en las
que dividimos la solucin a un problema. El uso de mdulos pretende ser un paso ms en la
metodologa del diseo descendente, permitiendo definir por separado las distintas partes de
un programa y las interfaces entre ellas. Adems, un mdulo permite agrupar elementos que
compartan alguna afinidad.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 1

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Algunos lenguajes de programacin ofrecen directamente el concepto de mdulo.


Aunque C++ no es uno de ellos, s que ofrece las herramientas necesarias para poder enfocar
un problema mediante la modularidad. Estas herramientas son la divisin de un programa en
distintos ficheros fuente y los espacios de nombres.
10.1.1.- Ventajas de la modularizacin de programas
Escribir un programa como una coleccin de mdulos ofrece muchas ventajas:

Los mdulos son una herramienta potente para crear grandes programas. Un
programador puede disear un programa grande como un conjunto de mdulos,
relacionados entre s mediante interfaces definidas apropiadamente. Escribir y depurar
el programa es ms fcil porque el programador puede trabajar con un mdulo cada
vez, usando los servicios facilitados por otros mdulos pero ignorando los detalles de
cmo estos mdulos trabajan (principio de abstraccin). Este tipo de diseo modular
es particularmente necesario cuando el programa se est desarrollando entre un
conjunto de programadores.

Ayudar a que el programa sea ms fcil de modificar. Puesto que los detalles de
implementacin de un mdulo se ocultan al resto de mdulos se pueden cambiar
detalles de un mdulo sin afectar al resto.

Hacer los programas ms portables. El programador puede ocultar los detalles


dependientes de la mquina en un mdulo, de forma que cuando se transporte a otro
ordenador, slo debe preocuparse de dichos aspectos.

Hacer posible la compilacin separada. El programa se divide en trozos, que el


compilador puede procesar separadamente. De esta forma, un cambio en un mdulo
solo requiere volver a compilar dicho mdulo, no el programa completo.

Permiten desarrollar bibliotecas1 con cdigo reutilizable. Ello conlleva no solo un


ahorro de trabajo, sino adems un aumento de la fiabilidad del programa, pues dichas
bibliotecas estarn ms probadas que si la parte de la biblioteca que se usa se
codificara de nuevo.

10.1.2.- Creacin de un proyecto con Dev-C++.


Nosotros escribiremos cada uno de los mdulos con los que trabajemos en un fichero fuente
distinto. Para hacer esto es necesario conocer cmo poder combinar varios ficheros fuentes
para crear un programa.
Para poder trabajar con varios ficheros fuente en Dev-C++ es necesario crear
previamente un proyecto. Para ello se utiliza la opcin New Project del men File. Al
seleccionarla nos sale una ventana como la de la Figura 1. Para nuestros ejemplos utilizaremos
la opcin Empty Project y pulsaremos OK, tras lo cual se nos pedir el nombre del proyecto.
Una vez elegido un nombre se nos pregunta el directorio donde se desea guardar el fichero de
proyecto. Este fichero, que tiene extensin dev , es el que usa el compilador para guardar toda
la informacin sobre el proyecto (ficheros fuente que lo componen, opciones de compilacin
del proyecto, etc.).

Puesto que su nombre en ingls es library en ocasiones se traduce como librera.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 2

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Figura 1

Una vez guardado el fichero de proyecto se nos muestra una pantalla como la de la
Figura 2. En ella se puede observar que a la izquierda aparece una pequea ventana con el
nombre del proyecto (en este caso complejos) del cual sale el nombre de cada uno de los
ficheros fuente que forman el proyecto. Como acabamos de crearlo solo hay un fichero por
defecto que se denomina Untitled.
Figura 2

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 3

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Podemos crear nuevos ficheros fuente dentro del proyecto con la opcin New Unit in
Project del men Project. La Figura 3 muestra un proyecto que consta de tres ficheros fuentes:
principal.cpp, complejo.h y complejo.cpp. Con las opciones respectivas del men
Project tambin se pueden agregar ficheros fuente ya existentes o eliminar del proyecto un
fichero fuente.

Figura 3

Una vez creado el proyecto se puede compilar con la opcin Compile del men Execute
tal como lo habamos hecho hasta ahora cuando slo usbamos un fichero fuente. Una vez
compilados todos los ficheros, se procede al enlazado automtico de los distintos ficheros
objeto que se han generado para crear el ejecutable.
Un programa consistir en un mdulo de programa (el programa principal) y
cualquier nmero de mdulos de biblioteca desde los cuales el mdulo de programa importa
entidades (constantes, tipos, variables y procedimientos). Estos mdulos de biblioteca a su vez
pueden importar de otros mdulos de biblioteca. El compilador proporciona una coleccin
bsica de mdulos de biblioteca (stdlib, iostream, etc.) adems de los cuales, el
programador tambin puede escribir sus propios mdulos de biblioteca adicionales, para
usarlos en uno o en varios programas. Esto es precisamente lo que vamos a estudiar en este
tema. Tendremos por tanto:

Mdulos de programa: son unidades de programa completas que pueden importar


recursos (constantes, variables, procedimientos..) desde mdulos de biblioteca. Son
mdulos de programa aquellos con los que hemos estado practicando hasta el
momento ya que contienen la funcin main().

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 4

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Mdulos de Biblioteca: estn constituidos por dos partes, el mdulo de definicin y


el mdulo de implementacin.

Los mdulos usan listas de importacin para controlar los recursos externos que van
a utilizar.

10.2.- Mdulos de biblioteca


Los mdulos de biblioteca se usan para exportar recursos a otros mdulos. Un mdulo
de biblioteca consta de dos partes, la parte de definicin y la parte de implementacin. La
parte de definicin contiene slo las definiciones de entidades o servicios que el mdulo
exporta, es decir, define la interfaz del mdulo de biblioteca con el resto del programa. La
parte de implementacin describe cmo implementar los servicios o entidades indicados en la
parte de definicin. La primera es tambin llamada fichero de cabecera y, aunque no es
obligatorio, lo normal es darle a este fichero la extensin .h (header en ingls). La segunda, la
parte de implementacin, tienen extensin .cpp y tambin es llamada cuerpo del mdulo.
El fichero de cabecera contiene definiciones, no declaraciones. Las definiciones son
similares a las declaraciones, pero proporcionan menos informacin. La definicin de un
procedimiento consiste nicamente en la cabecera del procedimiento seguido de punto y
coma, omitiendo su cuerpo.
Ejemplo: Los parmetros de las funciones trigonomtricas en la biblioteca <math.h>
deben ser expresados en radianes, no en grados. Los programas que miden ngulos en grados
necesitan convertir de grados a radianes y viceversa (llamaremos a estas funciones
gradosAradianes y radianesAgrados). Debido a que estas funciones pueden ser tiles en
ms de un programa, tiene sentido crear un mdulo de biblioteca llamado
conversinAngulos que exporte las dos funciones. El fichero de cabecera sera:
conversionAngulos.h
/* declara funciones para la conversion entre angulos */
#ifndef _conversionangulos_h_
// para evitar inclusin duplicada
#define _conversionangulos_h_
double gradosAradianes (double grad);
/* convierte un ngulo de grados a radianes */
double radianesAgrados (double rad);
/* convierte un ngulo de radianes a grados */
#endif

El fichero de cabecera especifica qu servicios proporciona el mdulo, en nuestro


caso, las funciones gradosAradianes y radianesAgrados.
La lneas:
#ifndef _conversionangulos_h_
#define _conversionangulos_h_

Son directivas de compilacin, es decir, no son sentencias ejecutables sino informacin


adicional que se le proporciona al compilador. En este caso, lo que se est diciendo es:
___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 5

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Si no esta definida la macro _conversionangulos_h_ defnela. Si ya lo estaba


no hagas nada (puesto que no hay nada despus de la directiva #endif).
Esta macro suele consistir en el nombre del fichero pero empezando y acabando por
_ y sustituyendo el . del nombre del fichero por otro _ .
Este tipo de sentencias se suele incluir en todos los ficheros de cabecera para impedir
que se produzcan errores de compilacin cuando un fichero de cabecera es importado dos
veces por el mismo mdulo (esto suele ocurrir cuando un mdulo importa un fichero de
cabecera que a su vez importa otro fichero de cabecera). De esta forma, la segunda vez que se
incluye el fichero de cabecera el compilador se salta todas las definiciones puesto que ya est
declarada la macro correspondiente.
A un mdulo que importa una entidad exportada por un mdulo de biblioteca se le
denomina cliente del mdulo de biblioteca. El siguiente programa, calculaTercerLado, es
un cliente del mdulo de biblioteca conversionAngulos, del cual importa la funcin
gradosARadianes (calculaTercerLado es tambin cliente de los mdulos de biblioteca
iostream, stdlib y math).
Esto se puede representar grficamente de la siguiente forma:
calculatercerlado

conversionAngulos

iostream

stdlib

math

Donde las flechas indican utiliza. Sin embargo, el uso de las bibliotecas estndar no
se suele representar, con lo que quedara:
calculatercerlado

conversionAngulos

Para poder utilizar las funciones que ofrece el fichero de cabecera, el programa cliente
debe incluir dicho fichero de cabecera. Esto se hace de forma similar a como lo habamos
hecho hasta ahora con los ficheros de biblioteca estndar como iostream o stdlib pero
sustituyendo los parntesis angulares por comillas dobles. Esto indica al compilador que ese
fichero de cabecera es nuestro y que, por tanto, debe buscarlo en otros directorios distintos a
los directorios en los que busca los ficheros de cabecera estndar. En general, los ficheros de
cabecera se buscan en el mismo directorio donde est el archivo que los incluya excepto que
se diga lo contrario en las opciones de compilacin del proyecto.
El programa principal de la aplicacin es el que se muestra a continuacin:

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 6

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


calculaTercerLado.cpp
/*calcula la longitud del tercer lado de un tringulo a partir de la
longitud de los otros dos lados y el ngulo formado entre ellos*/
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include "conversionangulos.h"
void main ()
{
double lado1, lado2, lado3, angulo;
cout << "Introduce la longitud de un lado ";
cin >> lado1;
cout << "Introduce la longitud del otro lado ";
cin >> lado2;
cout << "Introduce el angulo que forman en grados ";
cin >> angulo;
lado3 = sqrt (lado1*lado1 + lado2*lado2
-2.0 * lado1*lado2 * cos (gradosAradianes(angulo)));
cout << "La longitud del lado 3 es " << lado3 << endl;
system ("pause");
return 0;
}

Hemos de darnos cuenta de que calculaTercerLado no sabe nada de como funciona


gradosAradianes. La parte de implementacin de un mdulo de biblioteca "llena los huecos"
dejados por la parte de definicin. Los procedimientos cuyas definiciones aparecen en la parte
de definicin deben tener declaraciones completas en la parte de implementacin. La parte de
implementacin de conversionangulos sera:
conversionAngulos.cpp
#include "conversionangulos.h"
const double pi=3.14159;
double gradosAradianes (double grad)
/* convierte un ngulo de grados a radianes */
{
return (pi * grad) / 180.0;
}
double radianesAgrados (double rad)
/* convierte un ngulo de radianes a grados */
{
return 180 * rad / pi;
}

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 7

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Lo primero que se debe hacer al escribir la parte de implementacin es incluir el


fichero de cabecera mediante la directiva #include "conversionangulos.h". De esta forma
nos aseguramos que todas las definiciones del fichero de cabecera estn accesibles en la parte
de implementacin. Adems de "llenar los huecos" dejados en la parte de definicin del
mdulo, la parte de implemetacin puede declarar entidades no mencionadas en la parte de
definicin (en nuestro caso la constante pi). Estas entidades son locales al mdulo de
implementacin: no son visibles fuera del mdulo.
10.2.1.- Espacios de nombres.
Un espacio de nombres se utiliza para expresar una agrupacin lgica. Es decir, si
algunas declaraciones pertenecen, de forma lgica, al mismo grupo, de acuerdo con algn
criterio, se pueden poner en el mismo espacio de nombres. Un espacio de nombres es un
mbito, por lo cual, si un nombre se declara dentro de un espacio de nombres podr ser visible
dentro de ese espacio de nombres con las reglas habituales de mbitos. Sin embargo, para usar
ese nombre fuera del espacio de nombres hay que utilizar el nombre del espacio de nombres
seguido de la expresin :: a la cual seguir el nombre que queremos utilizar. Esto es muy
til para programas grandes donde puede ser que tengamos varios subprogramas con el
mismo nombre. Poner delante el nombre del espacio de nombres (lo que se denomina,
cualificar el nombre) nos evitara entrar en conflictos.
Para definir un espacio de nombres se utilizar la palabra namespace seguida del
identificador que queramos asignarle. A continuacin encerramos entre llaves todo el espacio
de nombres.
Los espacios de nombres proporcionan una herramienta excelente para la
programacin modular. De esta forma nuestro ejemplo se escribira de la siguiente forma:
/* declara funciones para la conversin entre ngulos */
#ifndef _conversionangulos_h_
// para evitar inclusin duplicada
#define _conversionangulos_h_
namespace Mconversionangulos {
double gradosAradianes (double grad);
/* convierte un ngulo de grados a radianes */
double radianesAgrados (double rad);
/* convierte un ngulo de radianes a grados */
}
#endif

Donde hemos introducido el espacio de nombres Mconversionangulos para indicar


que es el espacio de nombres donde se encuentran las declaraciones del mdulo
conversionangulos.
En el programa principal tenemos tres opciones a la hora de llamar a la funcin
gradosAradianes. La primera es simplemente poner el espacio de nombres delante de la
funcin: Mconversionangulos::gradosAradianes con lo que la sentencia correspondiente
quedara como:
___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 8

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


lado3 = sqrt (lado1*lado1 + lado2*lado2
-2.0 * lado1*lado2 *cos (Mconversionangulos::gradosAradianes(angulo)));

La segunda opcin es hacer una declaracin de uso mediante la instruccin using:


using Mconversionangulos::gradosAradianes; /* importa del mdulo
Mconversionangulos la funcin gradosAradianes */

Con lo cual, ya podemos utilizar la funcin sin tener que cualificarla. Esto es
particularmente til cuando el nombre que se est usando se utiliza muchas veces.
La tercera opcin es importar con una sola sentencia todo el espacio de nombres. Es
ese caso tendramos que poner using namespace Mconversionangulos; con lo que ahora
todos los identificadores del espacio de nombres son visibles sin tener que estar cualificados.
Esta opcin, aunque cmoda, puede no ser la ms aconsejable puesto que si importamos dos
espacios de nombres que exportan el mismo identificador volveramos a entrar en conflicto
(con lo cual los espacios de nombres perderan su sentido).
Por ltimo, en el mdulo de implementacin, se puede volver a definir el mismo
espacio de nombres para implementar cada una de las operaciones definidas en el fichero de
cabecera:
conversionangulos.cpp
#include "conversionangulos.h"
namespace Mconversionangulos{
const double pi=3.14159;
double gradosAradianes (double grad)
/* convierte un ngulo de grados a radianes */
{
return (pi * grad) / 180.0;
}
double radianesAgrados (double rad)
/* convierte un ngulo de radianes a grados */
{
return 180 * rad / pi;
}
}
// fin del mdulo

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 9

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

10.2.2.- Mdulos de definicin.


Un mdulo de definicin contiene definiciones de constantes, tipos, variables y
procedimientos. Las definiciones son similares a las declaraciones, pero pueden tener menos
informacin.
- Constantes.
Son idnticas a las declaraciones de constantes normales.
- Tipos.
Nosotros nos ceiremos a los denominados tipos transparentes, en los cuales, la
estructura del tipo es visible en los mdulos que lo importen. Por ejemplo:
struct Complejo {
float p_real, p_imag;
};

Un mdulo que importe el tipo complejo importa automticamente los nombres de sus
campos p_real y p_imag. Sin embargo, para seguir una metodologa de diseo correcta, es
conveniente que cuando se defina un tipo, tambin se definan todos los procedimientos o
funciones que manejen ese tipo. De esta forma, el mdulo cliente de este tipo es independiente
de su implementacin, de forma que si realiza un cambio en la implementacin del tipo o de
sus operaciones, el mdulo cliente no se vea afectado.
- Variables.
Las definiciones de variables son idnticas a las declaraciones de variables normales.
Estas variables son globales, por lo que se uso slo es recomendable en casos muy concretos.
- Procedimientos y funciones.
La definicin de un procedimiento o funcin consta de la cabecera del mismo. La
declaracin completa debe aparecer en el mdulo de implementacin. No es necesario ponerle
nombre a los parmetros, basta con indicar su tipo.
10.2.3.- Mdulos de implementacin.
Al igual que los mdulos de programa, los mdulos de implementacin pueden
contener tanto listas de importacin como declaraciones. Mediante listas de importacin un
mdulo de implementacin puede importar entidades de otros mdulos de biblioteca.
Las declaraciones sirven para dos propsitos:

Especificar los aspectos indefinidos en el mdulo de definicin.

Declarar entidades que sean estrictamente locales al mdulo de implementacin.

Cualquier entidad declarada en la parte de definicin de un mdulo de biblioteca es


visible en la parte de implementacin al incluir el fichero de cabecera.
Un mdulo de implementacin puede tener declaraciones de 4 clases de entidades:

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 10

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

- Constantes.
Las constantes definidas en la parte de definicin son visibles en la parte de
implementacin. Todas las constantes declaradas en un mdulo de implementacin son locales
a dicho mdulo; no son visibles fuera del mdulo de implementacin.
- Tipos.
Los tipos definidos en la parte de definicin del mdulo son visibles en la parte de
implementacin. Si es necesario, se pueden definir nuevos tipos que son locales al mdulo de
implementacin.
- Variables.
Las variables declaradas en la parte de definicin no pueden volver a ser declaradas en
la parte de implementacin puesto que son visibles en sta. Todas las variables declaradas en
la parte de implementacin son locales a sta.
- Procedimientos y funciones.
La parte de implementacin de un mdulo debe contener una declaracin completa de
todos los procedimientos y funciones cuya definicin aparece en el fichero de cabecera. Habr
que respetar estrictamente la forma en que se definieron, es decir, habr que declarar el mismo
nmero de parmetros y los mismos tipos para ellos.
10.2.4.- Ejemplo. El mdulo Mcomplejo.
A continuacin se muestra un programa que utiliza un mdulo de biblioteca
denominado Mcomplejo que exporta el tipo de datos complejo as como algunas operaciones
que se pueden realizar con este tipo de datos. La estructura del programa sera la siguiente:

principal

Mcomplejo

La parte de definicin del mdulo complejo (Mcomplejo.h) sera:

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 11

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

// declara el tipo de datos Complejo y algunas operaciones


#ifndef _Mcomplejo_h_
#define _Mcomplejo_h_
namespace Mcomplejo{
struct Complejo {
float p_real, p_imag;
};
// nmeros complejos
void asignar (Complejo& c, float real, float imag);
// asigna a c el nmero complejo formado por real e imag
void sumar (Complejo& res, Complejo x, Complejo y);
// suma x + y asignado el resultado a res
void escribir (Complejo x);
// escribe por pantalla el valor de x
}
#endif

La parte de implementacin (Mcomplejo.cpp) quedara como:


#include "Mcomplejo.h"
#include <iostream.h>
namespace Mcomplejo{
void asignar (Complejo& c, float real, float imag)
// asigna a c el nmero complejo formado por real e imag
{
c.p_real = real;
c.p_imag = imag;
}
void sumar (Complejo& res, Complejo x, Complejo y)
// suma x + y asignado el resultado a res
{
res.p_real = x.p_real + y.p_real;
res.p_imag = x.p_imag + y.p_imag;
}
void escribir (Complejo x)
// escribe por pantalla el valor de x
{
cout << x.p_real << " + " << x.p_imag << "i";
}
} // fin del mdulo

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 12

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

El programa principal (principal.cpp) sera el siguiente:


#include <stdlib.h>
#include <iostream.h>
#include "complejo.h"
// programa cliente del modulo Mcomplejo.
// Lista de importacin:
using Mcomplejo::Complejo;
using Mcomplejo::asignar;
using Mcomplejo::sumar;
using Mcomplejo::escribir;
// equivalente a using namespace Mcomplejo;
int main()
{
Complejo c1, c2, c3; // declara 3 nmeros complejos
asignar (c1, 1.0, 2.0);
asignar (c2, 2.0, 4.5);
sumar (c3, c1, c2);
// c3 = c1 + c2
escribir (c3);
cout << endl;
system("pause");
return 0;
}

10.3.- Compilacin Separada


Una de las ventajas del diseo modular es poder compilar mdulos de programa y de
biblioteca de forma separada. El compilador chequea que cada entidad importada de un
mdulo de biblioteca sea usada de forma consistente con su definicin en el mdulo (para ello
usa la informacin contenida en la parte de definicin del mdulo de biblioteca).
La compilacin separada nos proporciona la ventaja de que cuando cambiamos un
programa slo necesitamos recompilar los mdulos afectados, no todos los mdulos del
programa.
Cuando cambiemos un mdulo de programa slo necesitamos recompilar dicho
mdulo y volver a enlazar (linkar) el programa completo; sin embargo, si cambiamos la
parte de definicin de un mdulo debemos recompilar la parte de implementacin de ste y
todos los mdulos que importen algo de dicha biblioteca. En Dev C++ todo este proceso est
simplificado de modo que es el sistema el que determina qu mdulos necesitan ser
recompilados como resultado de los cambios hechos al programa. La opcin Rebuild All del
men Execute recompila todos los ficheros fuente del proyecto tanto si han sido modificados
como si no.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 13

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

10.4.- Estructuras de Datos Avanzadas.


En el tema de gestin dinmica de memoria se estudi como implementar una lista
enlazada. En este tema estudiaremos otros tipos de estructuras de datos as como su
implementacin mediante mdulos de biblioteca.
10.4.1. Pilas.
Una pila es una estructura de datos homognea (elementos del mismo tipo), secuencial
y de tamao variable. Slo es posible un modo de acceso a esta estructura: a travs de la
cabeza de la pila. De este modo podemos aadir un elemento a la cabeza de la pila o extraer
un elemento de la cabeza de la pila. Debido a que las operaciones de extraccin e insercin se
realizan por el mismo extremo, el ltimo elemento en ser aadido ser el primero en ser
extrado; por ello a estas estructuras se las conoce con el nombre de LIFO (last-in, first-out;
ltimo en entrar, primero en salir).

Insertar

Extraer

Cabeza

Pila
Otras operaciones posibles sobre la pila son la creacin de una pila vaca, la
interrogacin de la misma para determinar si contiene o no algn elemento y la destruccin de
la pila.
Para implementar una pila como una estructura dinmica de datos se usan listas
enlazadas, las operaciones de extraccin e insercin en la lista (pila) se hacen siempre sobre la
cabeza de la misma.
La estrucutura de datos usada para representar una pila que almacene elementos de
tipo int es la siguiente:

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 14

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

#ifndef _MPila_h_
// para evitar inclusin duplicada
#define _MPila_h_
// Modulo MPila
// Exporta el tipo TPila, pila de enteros y los procedimientos
// crearPila, destruirPila, pilaVacia, meterPila y sacarPila
namespace MPila{
struct NodoPila {
int elemento;
NodoPila * sig;
};
typedef NodoPila* TPila;
TPila crearPila (); // Crea la Pila
void destruirPila (TPila& pila); // libera la memoria
bool pilaVacia (TPila pila); // comprueba si la pila est vaca
void meterPila (TPila& pila, int valor);
// introduce valor en la pila
void sacarPila (TPila& pila, int & valor);
// saca el valor de la cima de la pila
}
#endif

En este caso se mantiene un slo puntero de tipo TPila que apunte a la cabeza de la
pila de elementos. A continuacin se muestra el mdulo de implementacin del tipo de datos
pila.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 15

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

#include <stdlib.h>
#include <iostream.h>
#include "mpila.h"
// Implementa las operaciones para manejar el tipo TPila
namespace MPila{
TPila crearPila ()
{
return NULL;
}
bool pilaVacia (TPila pila)
{
return (pila == NULL);
}
void destruirPila (TPila & pila)
{
TPila ptr;
while (pila != NULL)
{
ptr = pila;
pila= pila->sig;
delete ptr;
}
}
void meterPila (TPila& pila, int valor)
{
TPila ptr;
ptr = new NodoPila;
ptr->elemento = valor;
ptr->sig = pila;
pila = ptr;
}
void sacarPila (TPila& pila, int& valor)
{
TPila ptr;
if (pilaVacia (pila))
{
cout << "Error en la pila. Pila Vacia " << endl;
}
else
{
ptr = pila;
valor = pila->elemento;
pila= pila->sig;
delete ptr;
}
}
}

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 16

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Por ltimo mostramos un programa sencillo que usa el tipo de datos pila. Simplemente
lee nmeros enteros hasta leer un cero y a continuacin los muestra en orden inverso:

#include <stdlib.h>
#include <iostream.h>
#include "mpila.h"
using namespace MPila;
int main()
{
TPila p;
int n;
p= crearPila ();
cout <<"Introduzca un numero (0 para terminar)" <<endl;
cin >> n;
while (n != 0)
{
meterPila (p,n);
cout <<"Introduzca un numero (0 para terminar)" <<endl;
cin >>n;
}
cout <<"Los numeros al reves son:" <<endl;
while ( !pilaVacia(p) )
{
sacarPila (p,n);
cout << n << endl;
}
destruirPila (p);
system ("pause");
return 0;
}

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 17

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

10.4.2. Colas.
En muchas aplicaciones se cumple el hecho de que el primer proceso que solicita un
servicio o recurso es el primero en ser servido. Para retirar elementos (servicios, recursos) en
el mismo orden en que fueron solicitados, se necesitan unas estructuras de datos abstractas
que mantengan una secuencia de valores y permitan aadir nuevos elementos por un extremo
y retirarlos por el otro. Esta estructura recibe el nombre de cola.
En las colas el elemento que entr el primero sale tambin el primero, por ello se le
conoce tambin como listas FIFO (first-in, first-out; primero en entrar, primero en salir.)
Se define la cola, como una estructura de datos homognea de tamao variable que
soporta el siguiente modo de acceso: insercin por un extremo y extraccin por el opuesto.
Operaciones posibles sobre la cola son la creacin de una cola vaca, la determinacin de s la
cola est o no vaca y la destruccin de la cola.
De igual modo que se ha visto para la pila, una cola se puede implementar haciendo
uso de las estructuras dinmicas de datos. En este caso, se simula mediante una lista enlazada
que mantiene dos punteros, uno llamado frente por donde se van extrayendo los elementos
ms antiguos de la cola, y otro llamado final, que seala al extremo por el cual se irn
aadiendo elementos a la cola. De esta forma, el puntero final nos garantiza que cada vez que
se tenga que extraer un elemento de la cola, no sea necesario recorrer sta desde el principio,
lo cual sera altamente ineficiente para colas largas. Las operaciones de insertar y extraer de la
cola tienen acceso directo a los nodos de la cola en los que se van a realizar estas operaciones.
La diferencia con las pilas reside en el modo de entrada y salida de los datos, en las
colas las inserciones se realizan al final de la lista, no al principio.

Aadir

Extraer

Cola
FrenteFinal

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 18

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

#ifndef _MCola_h_
// para evitar inclusin duplicada
#define _MCola_h_
// Modulo MCola
// Exporta el tipo TCola, Cola de enteros y los procedimientos
// crearCola, destruirCola, ColaVacia, meterCola y sacarCola
namespace MCola{
struct NodoCola {
int elemento;
NodoCola * sig;
};
typedef NodoCola * TPuntero ;
struct TCola {
TPuntero frente, final;
};
TCola crearCola (); // Crea la Cola
void destruirCola (TCola& cola); // libera la memoria
bool colaVacia (TCola cola); // comprueba si la Cola est vaca
void meterCola (TCola& cola, int valor);
// introduce valor al final de la Cola
void sacarCola (TCola& cola, int & valor);
// saca el valor del frente de la Cola
}
#endif

MCola.h

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 19

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

La implementacin de las operaciones de la cola (MCola.cpp) seran las siguientes:


#include <stdlib.h>
#include <iostream.h>
#include "MCola.h"
// Implementa las operaciones para manejar el tipo TCola
namespace MCola{
TCola crearCola ()
{
TCola cola;
cola.frente = NULL;
cola.final = NULL;
}
void destruirCola (TCola & cola)
{
TPuntero ptr;
while ( cola.frente != NULL )
{
ptr = cola.frente;
cola.frente = cola.frente->sig;
delete ptr;
}
}
bool colaVacia (TCola cola)
{
return (cola.frente == NULL);
}
void meterCola (TCola& cola, int valor)
{
TPuntero ptr;
ptr = new NodoCola;
ptr->elemento = valor;
ptr ->sig = NULL;
if (colaVacia(cola) )
{
// si es el primero frente y final lo apuntan
cola.frente = ptr;
}
else
{
___________________________________________________________________________
cola.final->sig = ptr;
Laboratorio de} Programacin
Mdulos
Pg 20
cola.final = ptr;
}

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

void sacarCola (TCola& cola, int& valor)


{
TPuntero ptr;
if (colaVacia (cola))
{
cout << "Error en la Cola. Cola Vacia " << endl;
}
else
{
ptr = cola.frente;
valor = ptr->elemento;
cola.frente= cola.frente->sig;
delete ptr;
if (cola.frente == NULL)
// era el ltimo
{
cola.final = NULL;
}
}
}
}// fin del mdulo MCola

10.4.3. rboles Binarios.


Las estructuras dinmicas vistas hasta ahora son lineales (listas enlazadas, pilas, colas).
Estas estructuras tienen grandes ventajas en cuanto a flexibilidad sobre las representaciones
contiguas, pero tienen un punto dbil: son listas secuenciales, es decir, estn dispuestas de
forma que es necesario recorrer cada posicin al menos una vez (cada elemento tiene un
sucesor). Mediante los rboles binarios se introduce el concepto de estructura de bifurcacin,
donde cada elemento puede tener ms de un posible 'siguiente', con lo cual es posible resolver
algunos problemas de difcil solucin cuando se usan estructuras dinmicas lineales.
El rbol es una estructura muy usada en todos los mbitos de la informtica ya que se
adapta a la representacin natural de informaciones homogneas organizadas y de una gran
comodidad y rapidez de manipulacin. Las estructuras tipo rbol se usan para representar
datos con una relacin jerrquica entre sus elementos, como son rboles genealgicos, tablas,
etc.
Un rbol se define como un conjunto finito de uno o ms nodos relacionados de la
siguiente forma:
___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 21

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Hay un nodo especial llamado raz del rbol, que proporciona un punto de entrada a
la estructura.
Los nodos restantes se subdividen en m>=0 conjuntos disjuntos, cada uno de los
cuales es a su vez un rbol. Estos rboles se llaman subrboles del raz.
Ntese que esta definicin es recursiva, se define un rbol en funcin de otros rboles.
La representacin y terminologa de los rboles se realiza con las tpicas notaciones de
las relaciones familiares en los rboles genealgicos: padre, hijo, hermano, ascendiente,
descendiente. Junto a estos conceptos se definen otros tales como raz, nodo, hoja, camino,
nivel, profundidad, etc., con los cuales se supone familiarizado al alumno.

1
2
4

3
6

9
Un rbol Binario se define como un conjunto de 0 ms nodos tales que:
Existe un nodo llamado raz del rbol.
Cada nodo puede tener 0,1, 2 subrboles conocidos como subrbol izquierdo y
subrbol derecho.
Un rbol binario puede ser representado fcilmente eligiendo las estructuras de datos
adecuadas. Un rbol general puede transformarse en un rbol binario aplicando determinados
algoritmos de conversin, el resto del epgrafe se centrar en el estudio de los rboles binarios.
La representacin dinmica de un rbol binario utiliza variables punteros y asignacin
dinmica de espacios de memoria. Cada nodo del rbol contiene al menos los siguientes
campos:
Campo de datos que almacena el tipo de datos.
Puntero al subrbol izquierdo.
Puntero al subrbol derecho.
Una implementacin en C++ es la que se muestra a continuacin:
struct NodoArbol {
int elemento;
NodoArbol * izq, * der;
};
typedef NodoArbol * TArbol;

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 22

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Se llama recorrido de un rbol binario al proceso que permite acceder una sola vez a
cada uno de los nodos del rbol. Cuando un rbol se recorre, el conjunto completo de nodos
se examina. Los algoritmos de recorrido de un rbol realizan las siguientes tareas comunes:
Procesar el nodo raz.
Recorrer el subrbol izquierdo.
Recorrer el subrbol derecho.
El orden en que se realizan estas acciones da nombre a los tres algoritmos ms
usuales: pre-orden, in-orden y post-orden:
void inOrden(TArbol a)
{
if (! arbolVacio(a)) {
inOrden(Izda(a));
procesar(a);
inOrden(Decha(a));
}
}

void preOrden(TArbol a)
{
if (! arbolVacio(a)) {
procesar(a);
preOrden(Izda(a));
preOrden(Decha(a));
}
}

void postOrden(TArbol a)
{
if (! arbolVacio(a)) {
postOrden(Izda(a));
postOrden(Decha(a));
procesar(a);
}
}

En cuanto a las operaciones aplicables a un rbol binario se muestran en el mdulo de


implementacin Marbol las siguientes:
- crearVacio: Devuelve un rbol binario vaco.
- crearRaiz: Crea el nodo raz de un rbol, y almacena en este nodo el valor que se le
pasa como parmetro a la funcin.
- crearIzda: Dado un rbol binario que no tiene desarrollada su rama izquierda, esta
funcin crea un nodo con el valor que se recibe como argumento, y se asigna a la rama
izquierda del rbol binario original.
- crearDcha: Es similar al procedimiento anterior pero aplicable a la rama derecha.
- sacarRaiz: Esta funcin devuelve el valor de la raz de un rbol binario.
- arbolVacio: Determina si un rbol binario est o no vaco.
- destruirArbol. Libera la memoria utilizada por el rbol. Hace un recorrido en
postorden.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 23

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

#include <stdlib.h>
#include <iostream.h>
#include "Marbol.h"
// Implementa las operaciones para manejar el tipo TArbol
namespace MArbol{
TArbol crearVacio ()
{
return NULL;
}
void crearRaiz (TArbol &arbol, int valor)
{
TArbol nodo;
nodo = new NodoArbol;
nodo->elemento = valor;
nodo->izq=crearVacio();
nodo->der=crearVacio();
arbol = nodo;
}
void crearIzda (TArbol &arbol, int valor)
{
TArbol nodo;
crearRaiz (nodo,valor);
arbol->izq = nodo;
}
void crearDcha (TArbol &arbol, int valor)
{
TArbol nodo;
crearRaiz (nodo,valor);
arbol->der = nodo;
}
int sacarRaiz (TArbol a)
{
return a->elemento;
}
void destruirArbol (TArbol & arbol)
{
if (arbol != NULL)
{
destruirArbol(arbol->izq);
destruirArbol(arbol->der);
delete arbol;
}
}

___________________________________________________________________________
}
Laboratorio de Programacin

Mdulos

Pg 24

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

10.5. Un Ejemplo Completo.


A continuacin vamos a ver una aplicacin relativamente sencilla que hemos
descompuesto en varios mdulos distintos. Consiste en un men que nos permite aadir
empleados a una lista para posteriormente poder visualizar dicha lista. Por cada empleado se
almacena su nombre, apellidos y su sueldo. Tanto el nombre como los apellidos deben tener
una longitud que no est delimitada por ninguna constante. Los mdulos en que hemos
dividido la aplicacin son los siguientes:
menu

MListaEmpleado

MEmpleado

MCadena

El primero de ellos, menu, es el programa principal, muestra el men por pantalla y


llama a las distintas opciones. El mdulo MListaEmpleado exporta una lista enlazada en la
que se insertan los empleados. Para hacer la implementacin de la lista enlazada lo ms
independiente posible del tipo base de la lista1, se implementa el tipo TEmpleado en otro
mdulo distinto (MEmpleado) junto con las operaciones necesarias para escribirlo, leerlo de
teclado y liberar la memoria que consume. Por ltimo, el mdulo MCadena ofrece las
operaciones de lectura y escritura de una cadena de caracteres implementada mediante una
lista enlazada.

Las plantillas de C++ quedan fuera de los objetivos de la asignatura.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 25

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


menu.cpp
#include <stdlib.h>
#include <iostream.h>
#include <ctype.h>
#include "MEmpleado.h"
#include "MListaEmpleado.h"
using MEmpleado::TEmpleado;
using MEmpleado::leeEmpleado; // importa TEmpleado y leeEmpleado de MEmpleado
using namespace MListaEmpleado; // importa todo el modulo
char menu()
{
char opc;
cout
cout
cout
cout

<<
<<
<<
<<

"A: Introducir Empleado" << endl;


"B: Mostrar empleados" << endl;
"S: Salir" << endl;
"Introduzca opcion:";

cin>> opc;
cin.ignore(); // limpia el buffer de teclado.
return opc;
}
int main ()
{
TEmpleado emp;
TListaEmpleado lista;
char opcion, seguro;
bool salir= false;
lista =crearLista(); // inicializa la lista
while (! salir)
{
opcion = toupper (menu());
switch ( opcion )
{
case 'A':
cout <<"Introduce un empleado\n";
leeEmpleado (emp);
insertaEmpleado (lista, emp);
break;
case 'B':
muestraLista (lista);
break;

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 26

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

case 'S':
cout << "Esta seguro (S/N)" << endl;
cin >> seguro;
if (toupper (seguro) == 'S' )
{
salir = true;
}
break;
default:
cout << "Opcion incorrecta " <<endl;
break;
}
}
borraLista (lista); // libera la memoria
system ("pause");
return 0;
}

MListaEmpleado.h
#ifndef _MListaEmpleado_h_
#define _MLislaEmpleado_h_

// para evitar inclusin duplicada

#include "MEmpleado.h"
// Parte de definicion del modulo Lista de Empleado
namespace MListaEmpleado {
using MEmpleado::TEmpleado; //importa el tipo TEmpleado
struct TNodoEmpleado
{
TEmpleado emp;
TNodoEmpleado * sig;
};
typedef TNodoEmpleado * TListaEmpleado;
TListaEmpleado crearLista();
// crea la lista vaca
void insertaEmpleado(TListaEmpleado &lista, TEmpleado emp);
// inserta un empleado en la lista (por el principio)
void muestraLista(TListaEmpleado lista); // muestra la lista completa
void borraLista (TListaEmpleado &lista); // libera la memoria consumida
}
#endif

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 27

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


MListaEmpleado.cpp
#include <stdlib.h>
// para incluir NULL
#include "MListaEmpleado.h"
#include "MCadena.h"
// implementacin del mdulo de Lista de Empleado
namespace MListaEmpleado {
using MEmpleado::destruirEmpleado;
TListaEmpleado crearLista ()
{
return NULL;
}

// crea la lista vaca

void insertaEmpleado(TListaEmpleado &l, TEmpleado emp)


// inserta un empleado en la lista (por el principio)
{
TListaEmpleado nuevo;
nuevo = new TNodoEmpleado;
nuevo->emp = emp;
nuevo->sig = l;
l = nuevo;
}
void muestraLista(TListaEmpleado l)
{
TListaEmpleado ptr;
ptr = l;
while (ptr != NULL)
{
escribeEmpleado(ptr ->emp);
ptr = ptr->sig;
}
}
void borraLista (TListaEmpleado &l)
{
TListaEmpleado ptr;
while (l != NULL)
{
ptr = l;
l = l->sig;
destruirEmpleado(ptr->emp);
delete ptr;
}
}

// muestra la lista completa

// libera la memoria

} // fin del mdulo

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 28

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


MEmpleado.h
#ifndef _MEmpleado_h_
#define _MEmpleado_h_

// para evitar inclusin duplicada

#include "MCadena.h"
namespace MEmpleado{
// parte de definicion del mdulo Empleado
using MCadena::TCadena ; // importa el tipo TCadena de MCadena
struct TEmpleado
{
TCadena nombre;
TCadena apellidos;
float sueldo;
};
void escribeEmpleado(TEmpleado emp); // escribe un empleado
void leeEmpleado(TEmpleado &emp);
// lee un empleado
void destruirEmpleado(TEmpleado &emp);
// libera la memoria de un
empleado
}
#endif

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 29

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


MEmpleado.cpp
#include_MCadena_h_
<iostream.h>
#ifndef
// para evitar inclusin duplicada
#include
"MEmpleado.h"
// incluimos la parte de definicin
#define _MCadena_h_
// implementacin del mdulo de Empleado
namespace
MEmpleado
{ del modulo MCadena
//
Parte de
definicion
namespace MCadena {
using MCadena::escribeCadena;
using
MCadena::leeCadena;
struct
TNodo
using
MCadena::borraCadena;
// importa de MCadena
{
char car;
void TNodo
escribeEmpleado(TEmpleado
emp)
// escribe un empleado
* sig;
{ };
cout << TNodo
"Nombre:
";
typedef
* TCadena;
escribeCadena(emp.nombre);
cout leeCadena
<< endl; (TCadena &c); // Lee una cadena de teclado
void
cout escribeCadena
<< "Apellidos:(TCadena
";
void
c); // muestra la cadena
escribeCadena(emp.apellidos);
void borraCadena (TCadena &c); // libera la memoria consumida
} cout << endl;
cout << "Sueldo: " << emp.sueldo << endl;
}
#endif
void leeEmpleado(TEmpleado & emp)
{
cout << "Nombre: " ;
leeCadena (emp.nombre);
cout << "Apellidos: " ;
leeCadena (emp.apellidos);
cout << "Sueldo: " ;
cin >> emp.sueldo;
}

// lee un empleado

void destruirEmpleado(TEmpleado &emp)


{
borraCadena (emp.nombre);
borraCadena (emp.apellidos);
}

// libera la memoria de un empleado

} // fin del mdulo

MCadena.h

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 30

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

MCadena.cpp

#include <iostream.h>
#include <ctype.h>
#include "MCadena.h"

// incluimos la parte de definicin

// implementacin del mdulo de Cadena


namespace MCadena {
const char ENTER = '\n';
void escribeCadena (TCadena c)
{
TCadena ptr;
ptr = c;
while (ptr != NULL)
{
cout << ptr->car;
ptr = ptr->sig;
}
}

// muestra la cadena

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 31

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

void leeCadena (TCadena &c)


{
char letra;
TCadena ptr;

// Lee una cadena de teclado

cin.get (letra);
if (letra == ENTER)
{
c = NULL;
// cadena vaca
}
else
{
c = new TNodo; // inserta la primera letra
c->car = letra;
c->sig = NULL;
ptr = c;
cin.get (letra);
while (letra != ENTER)
{
ptr->sig = new TNodo;
ptr = ptr->sig;
ptr->car = letra;
cin.get (letra);
}
ptr ->sig = NULL;

// inserta el resto

}
}
void borraCadena(TCadena &c)
{
TCadena ptr;
while (c != NULL)
{
ptr = c;
c = c->sig;
delete ptr;
}
}
}

// libera la memoria consumida

// fin del mdulo MCadena

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 32

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

EJERCICIOS
1. Escribe un mdulo de implementacin llamado

MComplejo.cpp parecido al visto en este


tema pero que exporte el tipo de dato nmero complejo y las operaciones suma, resta,
producto, divisin, lectura y escritura sobre dicho tipo. El tipo y las operaciones estn
definidas en el fichero MComplejo.h, dado a continuacin:

// declara el tipo de datos Complejo y algunas operaciones


#ifndef _Mcomplejo_h_
#define _Mcomplejo_h_
namespace Mcomplejo{
struct Complejo {
float p_real, p_imag;
};
// nmeros complejos
Complejo leerCMP ();
void EscribirCMP (Complejo c);
Complejo asignarCMP (float real, float imag);
Complejo sumar (Complejo x, Complejo y);
Complejo restar (Complejo minuendo, Complejo sustraendo);
Complejo multiplicar (Complejo x, Complejo y);
Complejo dividir (Complejo x, Complejo y);
}
#endif

Probarlo sobre el siguiente programa ejemplo:


/*----------------------------------------------------------------*/
/*
Programa ejemplo para prctica de mdulos. Usa el tipo de */
/*
de datos Complejo que se encuentra definido en el fichero
*/
/*
Mcomplejo.h.
*/
/*----------------------------------------------------------------*/
#include <stdlib.h>
#include <iostream.h>
#include "complejo.h"
// programa cliente del modulo Mcomplejo.
// Lista de importacin:
using namespace Mcomplejo;
int main()

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 33

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas


{
Complejo a, b, c; // declara 3 nmeros complejos
a = asignarCMP (4.5, 5.0);
b = asignarCMP(2.45, -3.0);
c = leerCMP();
escribirCMP(a) ;
escribirCMP(b) ;
escribirCMP(c) ;
b = sumarCMP(a, c) ;
a = restarCMP(b, c) ;
c = multiplicarCMP(a, b) ;
escribirCMP(a) ;
a = dividirCMP(c, b) ;
escribirCMP(a) ;
escribirCMP(b) ;
escribirCMP(c) ;
cout << endl;
system("pause");
return 0;
}

2. Implementar el programa prbMod3.cpp, similar al del ejercicio 1, pero en lugar de


nmeros complejos importar un mdulo llamado MPolinon.h que contenga el tipo de dato
TPolinomio y las mismas operaciones que se aplican a los complejos. El grado mximo de
los polinomios es 10.

3. Escribe un mdulo llamado UNIDADES, que defina un nmero de identificadores


constantes que sean tiles en formulas para convertir de un conjunto de unidades a otro.
Necesitamos saber que:
-. 1 pulgada son 2.54 centmetros.
-. 1 milla son 1.6093 Kilmetros.
-. 1 galn son 4.5461 litros.
-. 1 libra son 0.4536 Kilogramos.
-. La formula para pasar de grados Celsius a Fahrenheit es:
celsius = (fahrenheit - 32.0) * 5.0 / 9.0
Tu mdulo debera exportar identificadores apropiados para los valores 2.54, 1.0693,
4.5461, 0.4536, 32.0 y 5.0/9.0. Escribe a continuacin un mdulo separado llamado
CONVERSIONESUNIDADES, que defina funciones para convertir de un conjunto de
unidades a otras. Se habran de incluir dos funciones (una en cada direccin), para cada
una de las siguientes parejas:
- pulgadas y centmetros.
- millas y kilmetros.
- galones y litros.
- libras y kilogramos.
-grados celsius y grados fahrenheit.
___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 34

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

El mdulo de implementacin de CONVERSIONESUNIDADES, debera importar del


mdulo UNIDADES y debera usar los identificadores constantes exportados desde ese
mdulo. Escribe un programa para comprobar este mdulo.

4. Escriba un mdulo llamado Mcadenas similar al del apartado 10.5 que exporte las
operaciones leeCadena, escribeCadena, comparaCadenas, concatenaCadenas,
longitudCadena, copiaCadena y posicionCadena (toma dos parmetros, c1 y
c2 y si c2 est contenida en c1, devuelve la posicin de c1, donde
comienza c2; en caso de que c2 no este contenida en c1 devuelve 1).

Disea tambin un mdulo cliente para probar el mdulo Mcadena.

5. Implementar un mdulo de librera que trabaje con una pila de nmeros cardinales. Las
operaciones que tendr que incluir son las vistas en este tema, as como las operaciones de
comparar dos pilas para determinar si son iguales y copiar una pila en otra.
6. Supngase que se modifica la definicin de implementacin de la cola de forma que se
declare un slo puntero cola que apunte al frente de la cola. A su vez la lista enlazada que
simula la cola es circular tal y como se muestra en la figura inferior. Se pide redefinir el
mdulo de implementacin Mcola mostrado en el tema en base a esta nueva definicin.
Aadir una funcin que calcule la longitud de una cola.
Cola
Final

Frente

Disea un mdulo cliente para probar el mdulo cola. En dicho mdulo se habr de
crear una cola de elementos de tipo INTEGER. Los elementos que se insertarn en la
cola (esta se crear a base de llamadas sucesivas a InsertarCola), sern ledos de un
fichero de texto. Adems de esta operacin en el mdulo cliente se habrn de probar
todas las restantes operaciones de la cola (sacarCola, colaVacia, crearCola,
longitudCola, destruirCola).
Si el fichero de texto fuera el siguiente:
25 35 40 45 50

La cola a crear sera la siguiente:

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 35

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

Cola

50

45

40

35

25

Final

Frente

7. Aadir los siguientes procedimientos al mdulo Marbol:


- Buscar un elemento en el rbol y devolver el nodo de tipo rbol que lo contiene.
- Insertar un nodo en el subrbol derecha (o izquierda) a partir del nodo que contiene
un elemento pasado como parmetro. Esta operacin slo es posible si el subrbol
donde se va insertar est vaco.
- Calcular el nivel de un nodo.
- Devolver el nodo padre de un nodo.
- Eliminar un nodo y todos sus descendientes de un rbol binario.

8. Disea una aplicacin para la gestin del personal de una empresa. De cada uno de los
empleados de la empresa se ha de almacenar la siguiente informacin:
- Nombre
- DNI
-Ao de Contratacin
-Nmina
Para gestionarlos de una forma eficiente, y minimizar en lo posible el Tiempo de
bsqueda, se decide almacenarlos en una Tabla Hash, que utilice el mtodo de
encadenamiento para la resolucin de colisiones. La funcin hash, sera el primer carcter
del nombre de cada empleado (campo clave). De modo que nuestra tabla hash tendra 26
posiciones, correspondientes a las 26 letras del alfabeto ingls.
Disea un men que permita llevar a cabo las siguientes operaciones, con la estructura
anteriormente definida:
A.- Insertar un nuevo Empleado.
B.- Eliminar un Empleado.
C.- Buscar un Empleado.
D.- Visualizar los datos de todos los Empleados.
___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 36

Departamento de Lenguajes y Ciencias de la Computacin. I.T.I. Gestin/Sistemas

E.- Salir.
- Seleccione una opcion:
A.- Insertar un nuevo Empleado. Pedir los datos del empleado a insertar, y lo
insertar en la tabla.
Nombre:
DNI:
Anyo:
Nmina:
B.- Eliminar un Empleado. Pedir el campo clave (nombre) del empleado a eliminar, lo
buscar y posteriormente lo eliminar de la tabla.
C.- Buscar un Empleado. Pedir el campo clave (nombre) del empleado a buscar y lo
buscar en la tabla, devolviendo true o false segn el resultado de la bsqueda.
D.- Visualizar los datos de todos los Empleados. Recorrer toda la tabla, imprimiendo
por pantalla toda la informacin relativa a cada uno de los empleados, su nombre, DNI,
ao de contratacin y nmina.
Para implementar la aplicacin, disea primero el mdulo MTabla con sus partes de
definicin (define el tipo TEmpleados (la tabla hash), de acuerdo a la definicin
anterior) y cada una de las operaciones a llevar a cabo sobre dicho tipo
(Insertar_Tabla, Eliminar_Tabla, Visualizar_Tabla, Buscar_Tabla, Crear_Tabla). Por
Ultimo disea un mdulo de prueba (cliente), donde se encontrar implementado el
men y que importar el tipo de datos TEmpleados, junto con las operaciones que
necesite del mdulo MTabla.
NOTA: Recuerda que has de hacer un procedimiento para crear (inicializar) la
estructura; este habr de ejecutarse al comienzo, antes de ejecutar cualquiera de las
operaciones anteriores del mdulo de prueba.

___________________________________________________________________________
Laboratorio de Programacin

Mdulos

Pg 37

You might also like