Laboratorio de Programación Orientada a Objetos (Grupo C) 1

Anuncio
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
1
LABORATORIO 1: Proyectos (Makefile)
Objetivo. Conceptuar e implementar aplicaciones claramente modularizadas y controladas por
el programador.
CONCEPTUALIZACIÓN
MODULARIZACIÓN. La modulación es un concepto que se ha trabajado en la formación
académica desde el primer semestre, por esos hay que verla desde dos perspectivas básicas:
-
-
La estimación de reducir un gran problema en pequeños segmentos bien definidos, con
el respectivo refinamiento por pasos, esto es la aplicación de funciones y
procedimientos (recordemos que C solo admite funciones).
La construcción de bloques de abstracciones altamente cohesivos y débilmente
acoplados por medio de la implementación de clases, identificando una interfaz y una
implementación.
¿Por qué modularizar en archivos fuente separados? Profundizar en:
http://www-etsi2.ugr.es/depar/ccia/mp2/old/apoyo/comsep/comsep.html
Dado que la organización de los archivos conlleva a una separación adecuada de todo el código,
se tiene que:
- Un archivo nombre.h donde se incluye el tipo abstracto de dato a manejar (más
adelante veremos que una clase es la representación de un Tad), junto con la
información administrativa (Comentarios que incluyen el nombre del autor, descripción
de la aplicación, fecha, asignatura y plataforma operativa).
- Un archivo nombre.cpp que implementa cada uno de las funciones miembro definidas
dentro de la(s) clase(s) del archivo .h.
- Un archivo principa.cpp que posee la función main() y que se restringe a solicitar
“servicios” a los archivos complementarios.
La asociación de estos tres archivos se denomina Proyecto y se entenderá que el header
(nombre.h) denotas las restricciones básicas para poder invocar cada uno de los métodos
implementados en nombre.cpp, mientras principa.cpp representará las solicitudes que haga el
cliente.
Ahora se evidencia un programa dividido en tres segmentos, ¿qué se debe hacer para
unificarlo y que corra adecuadamente?, para responder este interrogante, deberemos revisar si
deseamos una compilación y enlazamiento desde un IDE (como Turbo C++ o Rhide) o desde
la interfaz de línea de comandos.
Compilación y enlazamiento desde:
-
IDE –Entorno de Desarrollo Integrado- (Como turbo C++, DevC++,Rhide): Se
direcciona el directorio al que posee los tres archivos, luego en el menú Proyecto
(Project) se crea un nuevo proyecto (nombre.prj) y se adicionan cada uno de los
archivos con extensión .cpp. De tal manera que al producir la compilación sobre
cualquiera de los tres archivos fuente, se estará produciendo la compilación común de
los tres pues ya se encuentran enlazados (linked). Si se hacen las modificaciones sobre
alguno de los tres archivos, la opción Rebuild All (Reconstruir todo) permitirá
recompilar y enlazar nuevamente los archivos del proyecto.
-
Interfaz de Línea de Comandos: Hay que garantizar que todos los archivos fuente se
encuentren en la misma ruta (obviamente en el mismo directorio preferiblemente),
luego brindar el siguiente comando:
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
2
g++ -c -g -Wno-deprecated nombre.cpp principa.cpp
donde:
g++ es el comando de compilación de C++.
-c Realiza solamente el preprocesamiento y la compilación de los archivos fuente. No se lleva a
cabo la etapa de enlazado.
-g Incluirá en el ejecutable la información necesaria para poder trazarlo empleando un
depurador.
-Wno –deprecated No despliega aquellos warnings derivadas de la desaprobación del archivo
.h particularmente.
Luego:
g++ -o nombresalida principa.o nombre.o
-o especifica el nombre del archivo de salida, resultado de la tarea solicitada al compilador, al
compilar se procede al enlazamiento y generación de la salida.
¿Como largo el proceso?, pues reduzcámoslo con la creación de un makefile!.
MAKEFILE
Profundicemos la temática en: http://decsai.ugr.es/~jmbs/MP2/Introgcc_2003.pdf
La utilidad make proporciona los mecanismos adecuados para la gestión de proyectos software,
makefile contiene las especificaciones necesarios para la operación de make. En una visión
simple, el uso de make conjuntamente con los archivos makefile proporciona el mecanismo para
realizar una gestión inteligente, sencilla y precisa de un proyecto software, ya que permite: a)
Una forma sencilla de especificar la dependencia entre los módulos de un proyecto software, b)
La recompilación únicamente de los módulos que han de actualizarse, c) Obtener siempre la
versión última que refleja las modificaciones realizadas, y d) Un mecanismo casi estándar de
gestión de proyectos software, independiente de la plataforma en la que se desarrolla.
Los elementos con que cuenta un archivo makefile (note que no tiene extensión) son:
Comentarios, Reglas explícitas, Órdenes y Destinos simbólicos.
Comentarios: Tienen como objeto clarificar el contenido del archivo makefile. Una línea del
comentario tiene en su primera columna el símbolo #. Los comentarios tienen el ámbito de una
línea, que no será contada dentro del proceso de reconocimiento de sentencias propias de
makefile.
Reglas: Constituyen el mecanismo por el que se indica a make los destinos, las listas de
dependencias y cómo construir los destinos. Como puede deducirse, son la parte fundamental de
un archivo makefile. Las reglas que instruyen a make son de dos tipos: explícitas e implícitas y
se definen de la siguiente forma:


Las reglas explícitas dan instrucciones a make para que construya los archivos
especificados.
Las reglas implícitas dan instrucciones generales que make sigue cuando no puede
encontrar una regla explícita.
Las reglas tienen este formato general:
Línea de dependencia
orden(es)
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
3
La línea de dependencia es diferente para las reglas explícitas e implícitas, pero las
instrucciones aplicables son las mismas.
El formato habitual de una regla explícita es el siguiente:
destino: lista de dependencia
ordenes(es)
donde:



destino especifica el archivo a crear.
lista de dependencia especifica los archivos de los que depende destino. La lista se
especifica separando los nombres de los archivos con espacios en blanco. Si alguno de
los archivos especificados en esta lista se ha modificado, se busca una regla que
contenga a ese archivo como destino y se construye. Una vez se han construido las
últimas versiones de los archivos especificados en lista de dependencia se construye
destino.
órden(es) son órdenes válidas para el sistema operativo en el que se ejecute la utilidad
make (en nuestro caso serán habitualmente llamadas al compilador en línea g++).
Pueden incluirse cuantas instrucciones se requieran como parte de una regla, cada uno
en una línea distinta. Usualmente estas instrucciones sirven para construir el destino,
aunque no tiene porque ser así.
MUY IMPORTANTE: Cada línea de órdenes empezará con un TABULADOR. Si no
es así, make mostrará un error y no continuará procesando el archivo makefile.
Ordenes: Se puede incluir cualquier orden válida del sistema operativo en el que se ejecute la
utilidad make. Pueden incluirse cuantas órdenes se requieran como parte de una regla, cada una
en una línea distinta. Las órdenes pueden ir precedidas por prefijos como:
@ Desactivar el eco durante la ejecución de esa orden.
- Ignorar los errores que puede producir la orden a la que precede.
Destinos simbólicos: Un destino simbólico se especifica en un fichero makefile en la primera
línea operativa del mismo. En su sintaxis se asemeja a la especificación de una regla, con la
diferencia que no tiene asociada alguna orden. El formato es el siguiente:
destino simbólico: lista de destinos
donde:


destino simbólico es el nombre del destino simbólico. El nombre particular no tiene
alguna importancia.
lista de destinos especifica los destinos que se construirán cuando se invoque a make.
La finalidad de incluir un destino simbólico en un fichero makefile es la de que se construyan
varios destinos sin necesidad de invocar a make tantas veces como destinos se desee construir.
Al estar en la primera línea operativa del fichero makefile, la utilidad make intentará construir el
destino simbólico. Para ello, examinará la lista de dependencia (llamada ahora lista de destinos)
y construirá cada uno de los destinos de esta lista: debe existir una regla para cada uno de los
destinos.
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
4
Funcionamiento de make. El funcionamiento de la utilidad make es el siguiente:
1. En primer lugar, busca el archivo makefile que debe interpretar. Si se ha especificado la
opción -f archivo, busca ese archivo. Si no, busca en el directorio actual un archivo llamado
makefile ó Makefile. En cualquier caso, si lo encuentra, lo interpreta; si no, da un mensaje de
error y termina.
2. Intenta construir el(los) destino(s) especificado(s). Si no se proporciona algún destino, intenta
construir solamente el primer destino que aparece en el archivo makefile. Para construir un
destino es posible que deba construir antes otros destinos: el destino especificado depende de
otros que no están construidos. Si es así, los construye examinando las listas de dependencias.
Esta reacción en cadena se llama dependencia encadenada.
3. Si en cualquier paso falla al construir algún destino, se detiene la ejecución, muestra un
mensaje de error y borra el destino que estaba construyendo.
las siguientes órdenes:
% make
% make -f makefile
% make saludo.exe
% make -f makefile saludo.exe
tienen el mismo efecto. En los dos últimos casos se ha especificado el destino a crear, aunque no
hace falta ya que éste es el primero del archivo makefile.
¿Qué ocurre cuando se dice que se compila y se enlaza? Gráficamente:
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
5
APLICACIÓN
Construyamos unos cuantos ejemplos donde sea posible verificar lo aprendido:
Recordando nuestro pasado laboratorio, construyamos un Proyecto (para nuestro caso, los
archivos fuente separados o módulos) para producir la clasificación de 20 estudiantes como
aprobados o reprobados, cada estudiante posee un nombre, código, fecha de nacimiento y nota
final. Trabajémoslo con Registros (struct) –dado que aún no conocemos el concepto de clases
(class)-. A partir de la implementación que posee cada estudiante:
Ejemplo1: (Compilación simple)
1. Cree el directorio Ejemplo1 dentro de la carpeta /home/sistemas/labpooC para trabajar
los siguientes archivos.
2. Edite un archivo estudiante.h y en este:
o Posicione la información administrativa
o Defina el registro estudiante (struct estudiante)
o Especifique los prototipos de las funciones a emplear (lectura, calcular,
visualizar)
3. Edite un archivo estudiante.cpp y en este implemente cada una de las funciones
definidas en el punto anterior. Su primera línea debe ser #include “estudiante.h”
4. Edite un archivo principa.cpp que posea únicamente la función main() y su respectivo
cuerpo. Su primera línea debe ser #include “estudiante.h”
5. Habiendo salvado los anteriores archivos (obviamente), ahora probemos una primera
forma de compilación y enlazamiento:
- En la línea de comando escriba gcc -c -g -Wno-deprecated estudiante.c principa.c
- No debieron salir errores, si fue así, corrijamos e intente nuevamente.
- Ahora escriba gcc -o estudiante.exe principa.o estudiante.o
6. De realizarse el procedimiento exitosamente, ahora podemos ejecutar el archivo de salida
denominado estudiante.exe, para ello escriba ./estudiante.exe (y pulse enter) para que
funcione su programa.
7. De esta manera hemos compilado de una primera forma (la más larga!!!)
8. Una forma de haber logrado la compilación y enlace de manera más reducida sería:
gcc –o estudiante.exe estudiante.c principa.c
Ejemplo2: (Un makefile básico)
1. Cree el directorio Ejemplo2 dentro de la carpeta /home/sistemas/labpooC para trabajar
los siguientes archivos.
2. Copie a la Carpeta Ejemplo2 los archivos estudiante.h, estudiante.c, principa.c.
3. Edite un archivo makefile y en este digite (respete los tabuladores):
estudiante.exe: estudiante.c principa.c
@echo Hola mundo, estoy ejecutando mi primer makefile …
gcc -o estudiante.exe: estudiante.c principa.c
4.
5.
6.
7.
8.
9.
Guarde los cambios en el archivo
Escriba en la interfaz de línea de comando el comando make (y pulse enter).
Verifique la no existencia de errores, si es así repita los pasos 3, 4, 5.
Verifique los archivos que se encuentran el nuestro directorio
Observe que ya cuenta con el ejecutable (estudiante.exe)
Ejecute el archivo
Ejemplo3: (Makefile avanzado I)
1. Cree el directorio Ejemplo3 dentro de la carpeta /home/sistemas/labpooC para trabajar
los siguientes archivos.
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
6
2. Copie a la Carpeta Ejemplo3 los archivos estudiante.h, estudiante.c, principa.c.
3. Edite un archivo makefile y en este digite (respete los tabuladores):
procesos: ejem1.exe mueveexe
estudiante.exe: estudiante.c principa.c
@echo Hola mundo, estoy ejecutando mi segundo makefile …
gcc -o estudiante.exe: estudiante.c principa.c
mueveexe:
@echo Creando directorio de copia...
mkdir DirectorioCopia
@echo Copiando los .exe a DirectorioCopia...
cp ejem1.exe DirectorioCopia/
@Listo papa, Mendoza copió el ejecutable...
4.
5.
6.
7.
8.
9.
Guarde los cambios en el archivo
Escriba en la interfaz de línea de comando el comando make (y pulse enter).
Verifique la no existencia de errores, si es así repita los pasos 3, 4, 5.
Verifique los archivos que se encuentran el nuestro directorio
Observe que ya cuenta con el ejecutable (estudiante.exe)
Ejecute el archivo
Ejemplo4: (Makefile avanzado II)
1. Cree el directorio Ejemplo4 dentro de la carpeta /home/sistemas/labpooC para trabajar
los siguientes archivos.
2. Copie a la Carpeta Ejemplo4 los archivos estudiante.h, estudiante.c, principa.c.
3. Edite un archivo makefile y en este digite (respete los tabuladores):
#Archivo makefile1
#Para compilar otros archivos modifique el contenido de FTES, OBJS, CAB,
#EJEC
FTES = estudiante.c principa.c
OBJS = principa.o estudiante.o
CAB = cadena.h
EJEC = estudiante.exe
#Banderas
CC = gcc
CFLAGS = -g -Wno-deprecated
#Comandos para compilación
#El ejecutable depende de los .o
$(EJEC):$(OBJS)
$(CC) -o $@ $(OBJS)
#Los .o dependen de los archivos .h y .c
@echo Lab POO GrupoC MIGUEL MENDOZA
$(OBJS): $(CAB) $(FTES)
$(CC) -c $(CFLAGS) $(FTES)
clean:
@echo creando carpeta destino
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
7
mkdir Carpeta
@echo moviendo toda la información a directorio Carpeta...
cp *.c ./Carpeta
cp *.h ./Carpeta
cp makefile ./Carpeta
@echo borrando puntos o...
rm -i -f *.o
# end
4.
5.
6.
7.
8.
9.
Guarde los cambios en el archivo
Escriba en la interfaz de línea de comando el comando make clean (y pulse enter).
Verifique la no existencia de errores, si es así repita los pasos 3, 4, 5.
Verifique los archivos que se encuentran el nuestro directorio
Observe que ya cuenta con el ejecutable (estudiante.exe)
Ejecute el archivo
APLICACIÓN
Dado el siguiente problema, realice la respectiva implementación empleando registros
(strcuts) y estableciendo claramente los módulos y funciones propias. Genere el respectivo
makefile en la carpeta Aplicación.
En un hotel se procesa la información sobre las habitaciones y huéspedes en los siguientes arreglos de
registros:
Habitaciones
Num
Tipo
Precio
disp
….
Num
tipo
Precio
disp
Donde:
HABI[i] representa al registro que contiene información de la habitación i.
Los campos del registro son los siguientes:
Num: representa el número de habitación
Tipo: Indica el tipo de habitación.
Se ingresa: SI: si la habitación es simple,
DO: si la habitación es doble,
TR: si la habitación es triple,
SU: si la habitación es suite.
Precio: Representa el precio de la habitación.
Disp: Indica si la habitación esta disponible o no. Se ingresa:
SI: Si la habitación esta disponible.
NO: Si la habitación no esta disponible.
Nota: El arreglo está ordenado teniendo en cuenta el número de la habitación.
Huéspedes
Num
nom
Fecarr
…..
Num
nom
Fecarr
HUES[I] representa al registro que contiene la información del huésped i.
Los campos del registro son los siguientes:
Num: Indica el número de habitación.
Nom: expresa el nombre del huésped.
Fecarr: Indica la fecha del arribo del cliente.
Construya un algoritmo en el que se pueda efectuar las siguientes operaciones:
a. Leer la información de las habitaciones.
b. Dado el nombre de un huésped y la fecha actual, regrese lo que debe pagar dicho huésped
(asuma que la diferencia entre las fechas la da número de días de alojamiento y que cada mes
tiene 30 días).
Laboratorio de Programación Orientada a Objetos (Grupo C)
Miguel Angel Mendoza Moreno
c.
d.
e.
8
Determine el número de habitaciones simples, dobles, triples y suites que hay disponibles.
Dado el nombre de un huésped, lo elimine del arreglo correspondiente y se libere su habitación.
Dado el nombre de un huésped que desea una habitación tipo X, ésta le sea asignada siempre
que esté disponible, haciendo la actualización en los arreglos correspondientes.
***
Analice los resultados y las implicaciones de lo programado!!!
En este nivel Usted ya está en capacidad de compilar cualquier tipo de
proyecto seleccionando la forma que considere más adecuada a su
gusto.
Descargar