david arroyo guardeno˜ primera semana: makefile, …arantxa.ii.uam.es/~darroyo/prog2/s1.pdf · 7...
TRANSCRIPT
Practicas de Programacion II
David Arroyo Guardeno
Escuela Politecnica Superior de la Universidad Autonoma de Madrid
Primera semana: Makefile, gdb, valgrind,POINT
1 Makefile2 gdb3 valgrind4 SHELL5 GIT
BitbucketComandos basicos
6 Primera PracticaPrimer ejercicioSegundo ejercicio
7 EjemplosPunteros opacosManejo de ficheros
Primera practicaPrimera semana P1 E1 y funciones mas
importantes de P1 E2Segunda semana Todos los ejercicios
Ø Requisitos y normativa: leercuidadosamente el enunciadoØ Se entregara un fichero makefile
que permita la correctacompilacion de la entrega☠⇔ correccion practica⇔ ☠
� Lunes 19 de febrero
gcc compiler
Ø Given main.c generate the executableprogram basico1Ø Generate calculator from main.c and
functions.c
gcc compiler
Ø Given main.c generate the executableprogram basico1
7 gcc main.c -o basico17 Execution→ ./basico1
Ø Generate calculator from main.c andfunctions.c
gcc compiler
Ø Given main.c generate the executableprogram basico1Ø Generate calculator from main.c and
functions.c1 gcc -ocalculator main.c functions.c2 Compiling & Linking
(a) gcc -c main.c(b) gcc -c functions.c(c) gcc -ocalculator main.o functions.o
Important gcc flags-ansi To enforce ANSI C standards
-pedantic To issue all the warnings demanded bystrict ISO C
-Wall Enables all the warnings about construc-tions
-g Generates debug information to be usedby GDB debugger
-l< library > links with a library file-L looks in directory for library files-c Compiles source files without linking-I adds include directory of header files-O Set the compiler’s optimization level
-help Show help
Make
1 Macros declarations7 Global constants
2 Targets7 A target includes a set of dependencies
3 Dependencies7 If one dependence does not exist, make
looks for a target to generate it
Structure of a makefile
#Macros d e c l a r a t i o nMACRO1=value
#Rules de c la ra t i ons
ta rge t1 : dependence1 dependence2 dependenceNcommand1 dependence1 dependence2command2 dependence2 dependenceN
makefile script I
CC = gccCFLAGS = −OOBJS = par t1 . o par t2 . ol i b c l a s s d l l : $ (OBJS)
ar −rv l i b c l a s s d l l . a $ (OBJS)myprogram : $ (OBJS)
$ (CC) −o myprogram $ (CFLAGS) main . o −L . − l c l a s s d l lpar t1 . o : par t1 . c par t1 . h header . h
$ (CC) $ (CFLAGS) −c par t1 . cpar t2 . o : par t2 . c header . h
$ (CC) $ (CFLAGS) −c par t2 . cmain . o : main . c header . h
$ (CC) $ (CFLAGS) −c main . cclean :
rm − f l i b c l a s s d l l . a $ (OBJS) main . o@echo ” a l l cleaned up ! ”
Local macros
$ ˆ A l l the dependencies o f a r u l e$< F i r s t dependence of a r u l e$@ Target o f a r u l e
executable : module1 . o module2 . o module3 . ogcc −o$@ $ ˆ
ins tead ofgcc −oexecutable moudule1 . o module2 . o module3 . o
CC = gccCFLAGS = −g −Wall −O3BUILD = . / b u i l d /DIST = . / d i s t /TEST = . / t e s t /
EXECUTABLES = $ ( DIST ) ex1 $ ( DIST ) ex2CLIENTS = $ (TEST) t e s t s
a l l : $ (EXECUTABLES) $ (TESTS)
$ ( DIST ) ex1 : $ ( BUILD ) dep1 . o $ ( BUILD ) dep2 . o
. . .
$ ( BUILD ) dep1 . o : dep1 . c@echo Generat ing $@$ (CC) $ (CFLAGS) −c $< −o $@
Ejemplo
ejecutable (exe)
main.o modulo1.o
main.c modulo1.h modulo1.c
Makefile
3 Reglase jecu tab le : main . o modulo1 . o
gcc −o e jecu tab le main . o sum. o
main . o : main . c modulo1 . hgcc −c main . c
modulo1 . o : modulo1 . c modulo1 . hgcc −c modulo1 . c
*.o: *.c dependencias
Ø Un fichero *.o depende (por defecto) delcorrespodiente fichero *.c
Ø Ejemplo: foo.o: foo.h
7 Accion implıcita: $(cc) −c foo.c −o foo.oe jecu tab le : main . o modulo1 . o
gcc −o e jecu tab le main . o modulo1 . o#ERROR: main . o no se compila aunque main . c sea mas rec i en te ! ! !
main . o : modulo1 . hgcc −c main . c
modulo1 . o : modulo1 . c modulo1 . hgcc −c modulo1 . c
*.o: *.c dependencias
Ø Un fichero *.o depende (por defecto) delcorrespodiente fichero *.c
Ø Ejemplo: foo.o: foo.h
7 Accion implıcita: $(cc) −c foo.c −o foo.oe jecu tab le : main . o modulo1 . o
gcc −o e jecu tab le main . o modulo1 . o
main . o : main . c modulo1 . hgcc −c main . c
modulo1 . o : modulo1 . c modulo1 . hgcc −c modulo1 . c
Makefile equivalentesOBJS=main . o modulo1 . o
e jecu tab le : $ (OBJS)gcc −o $@ $ (OBJS)
%.o : %.c modulo1 . hgcc −c $∗ . c
Ø OBJS : definicion de variable
Ø $(OBJS) : obetenemos el valor de la variable
Ø %.o : patron de regla
Ø $∗.c : evalua el correspondiente fichero *.c
Makefile: otro ejemploCOMMON DIR = . . / common dirSRC = . . / s rcSRC FILES = $ (SRC) / foo . c $ (COMMON DIR) / bar . c main . cOBJ FILES = $ ( patsubst %.c ,%.o , $ ( SRC FILES ) )CFLAGS = −Wall −g −ans iCC = gccINCLUDES = −I$ (SRC).PHONY: cleane jecu tab le : $ ( OBJ FILES )
$ (CC) $ (CFLAGS) $ ( OBJ FILES ) −lm −o $@%.o:%.c
$ (CC) $ (CFLAGS) $ (INCLUDES) −c $∗ . c −o $∗ . o
clean :−rm $ ( OBJ FILES ) e jecu tab le
depend :@echo −e ’ \n ’ >> makef i le$ (CC) $ (INCLUDES) −MM $ ( C FILES ) >> makef i le
$(patsubst patron,sustituto,texto) : Funcion para lasustitucion de patrones en el texto dado como tercerargumento Identifica un objetivo que no refiere elnombre de un fichero. Si tenemos
Makefile: otro ejemploCOMMON DIR = . . / common dirSRC = . . / s rcSRC FILES = $ (SRC) / foo . c $ (COMMON DIR) / bar . c main . cOBJ FILES = $ ( patsubst %.c ,%.o , $ ( SRC FILES ) )CFLAGS = −Wall −g −ans iCC = gccINCLUDES = −I$ (SRC).PHONY: cleane jecu tab le : $ ( OBJ FILES )
$ (CC) $ (CFLAGS) $ ( OBJ FILES ) −lm −o $@%.o:%.c
$ (CC) $ (CFLAGS) $ (INCLUDES) −c $∗ . c −o $∗ . o
clean :−rm $ ( OBJ FILES ) e jecu tab le
depend :@echo −e ’ \n ’ >> makef i le$ (CC) $ (INCLUDES) −MM $ ( C FILES ) >> makef i le
.PHONY Identifica un objetivo que no refiere elnombre de un fichero. Si tenemos
h e l l o : h e l l o . cgcc h e l l o . c −o h e l l o
y se crea un fichero de texto hello despues de crearhello.c , el primer fichero siempre sera posterior: nose lanza nunca el objetivo. Si se usa .PHONY.PHONY: h e l l o
h e l l o : h e l l o . cgcc h e l l o . c −o h e l l o
al hacer make hello se ignora si existe un ficherohello en PWD
Generando pre-requisitos I
Ø Si main.c usa types.h vıa #include , senecesita la siguiente regla en el Makefile paracompilar el fichero fuente si cambia la cabecera
main . o : types . h
Ø Hay que modificar el Makefile cada vez que seincorpora una nueva dependencia vıa fichero .h
Ø Cada vez que se cree un fichero .o , vamos acrear un fichero .d con los ficheros necesariospara crear dicho fichero objeto
Generando pre-requisitos IIOBJS=main . o− i nc lude $ (OBJS : . o=.d )
main . o : main . cgcc −c $ (CFLAGS) $∗ . c −o $∗ . ogcc −MM $ (CFLAGS) $∗ . c > $∗ . d
Ø −include $(OBJS:.o=.d)
1 Toma el valor del $(OBJS)2 Remplaza la extension .o por .d3 − indica que si algun fichero .d no existe,
make continua ejecutandose (si no existe elfichero .d , tampoco existe elcorrespondiente .o ⇒ se ejecuta el objetivoasociado)
Debugging I
1 Compile with the flag -g
2 ulimit -a→ to check restrictions
3 ulimit -c unlimited→ to disable restrictions
4 gdb name-executable
7 run < input−arguments >7 Add a break-point
⇒ b < file name.c >: line number⇒ function name⇒ line number⇒ file:line number⇒ c→ continuing execution
Debugging II
⇒ n→ next code line⇒ s→ show next code line or function (line by line)
7 bt→ print a backtrace of the entire stack7 p < variable >→ print variable content
More usefule options I
Ø info locals : Print the local variables in thecurrently selected stack frame
Ø whatis variable name : Print type of namedvariable
Ø list : shows the current (or given) source context
7 list <filename>:<function>7 list <filename>:<line number>7 list <first>,<last>
Ø info args : Print the arguments to the function ofthe current stack frame
More usefule options II
Ø info breakpoints : Print informations about thebreak- and watchpoints
Ø info locals : Print the local variables in thecurrently selected stack frame
Ø break/watch <where> if <condition>
Ø watch <where> : set a new watchpoint
7 function name7 line number7 file:line number
More usefule options III
Ø Create your own gdbinit: https://github.com/cyrus-and/gdb-dashboard,https://github.com/gdbinit/Gdbinit/blob/master/gdbinit, etc.
Comments on ˜/. gdbinit
set breakpo in t pending on #avoid messages i n case breakpo in t cannot bep rope r l y l o c a l i z e d
f i l e f1 # i . e . , ” gdb . / f1 ”set args −−dummy1 # Set f1 ’ s arguments ( i f any )
b some funct ion # Set a breakpo in t
# b 42 # Commented−out breakpo in t . This f i l e can be# q u i c k l y ed i ted to avoid remembering a l l the# po in t s o f i n t e r e s t .
r # Run the program
In order to store the command historyset h i s t o r y f i lename ˜ / . gdb h i s to r y
set h i s t o r y save onset h i s t o r y s ize 666
Valgrind
Ø Instrumentation framework for building dynamicanalysis tools
Ø valgrind −−leak−check=full ./test arg1 arg2
Ø Para comprobar si hay ficheros abiertos,valgrind −−track=fds=yes −−leak−check=full ./test
Example 00: is this correct?
#include <s t d l i b . h>#define NMAX 12
void t e s t ( i n t ∗a ) {a [NMAX] = 0;
}
i n t main ( void ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;t e s t ( a r ray ) ;f r ee ( ar ray ) ;return 0;
}
#include <s t d l i b . h>#define NMAX 12
void t e s t ( i n t ∗a ) {i n t i ;for ( i =0; i<NMAX; i ++){
a [ i ] = 0 ;}
}
i n t main ( void ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;t e s t ( a r ray ) ;f r ee ( ar ray ) ;return 0;
}
Example 01: what is the problem?
#include <s t d l i b . h>#include <s t d i o . h>#define NMAX 12
i n t main ( i n t argc , char ∗∗ argv ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;
i f ( ! a r ray ) return −1;
p r i n t f ( ”%d ” , a r ray [ 0 ] ) ;
f r ee ( ar ray ) ;return (EXIT SUCCESS) ;
}
#include <s t d l i b . h>#include <s t d i o . h>#define NMAX 12
void t e s t ( i n t ∗a ) {i n t i ;for ( i =0; i<NMAX; i ++){
a [ i ] = 0 ;}
}
i n t main ( i n t argc , char ∗∗ argv ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;
i f ( ! a r ray ) return −1;t e s t ( a r ray ) ;p r i n t f ( ”%d ” , a r ray [ 0 ] ) ;
f r ee ( ar ray ) ;return (EXIT SUCCESS) ;
}
Example 03: what is the problem?
#include <s t d l i b . h>#include <s t d i o . h>#define NMAX 12
void t e s t ( i n t ∗a ) {i n t i ;for ( i =0; i<NMAX; i ++){
a [ i ] = 0 ;}
}
i n t main ( i n t argc , char ∗∗ argv ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;i f ( ! a r ray ) return −1;
t e s t ( a r ray ) ;
return (EXIT SUCCESS) ;}
#include <s t d l i b . h>#include <s t d i o . h>#define NMAX 12
void t e s t ( i n t ∗a ) {i n t i ;for ( i =0; i<NMAX; i ++){
a [ i ] = 0 ;}
}
i n t main ( i n t argc , char ∗∗ argv ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;
i f ( ! a r ray ) return −1;t e s t ( a r ray ) ;p r i n t f ( ”%d ” , a r ray [ 0 ] ) ;
f r ee ( ar ray ) ;return (EXIT SUCCESS) ;
}
#include <s t d l i b . h>#include <s t d i o . h>#define NMAX 12
void t e s t ( i n t ∗a ) {i n t i ;for ( i =0; i<NMAX; i ++){
a [ i ] = 0 ;}
}
i n t main ( i n t argc , char ∗∗ argv ) {i n t ∗ ar ray = mal loc (NMAX ∗ sizeof ( i n t ) ) ;
i f ( ! a r ray ) return −1;t e s t ( a r ray ) ;p r i n t f ( ”%d ” , a r ray [ 0 ] ) ;
f r ee ( ar ray ) ;f r ee ( ar ray ) ;
return (EXIT SUCCESS) ;}
�SHELL �https://explainshell.com/
Ayuda→ man
Ø man man
Ø man −k <palabra clave>
Ø man n sec <orden obtener ayuda>
7 Ej.: man passwd
NavegacionØ Cambiar de directorio: cd
7 /7 ˜7 ./7 ../
Ø Listar el contenido de un directorio: ls7 -l7 -a
Ø Buscar ficheros7 find7 locate
Visualizacion de ficheros
Ø Concatenar e imprimir ficheros: cat
Ø Imprimir las primeras lıneas de un fichero: head
Ø Imprimir las ultimas lıneas de un fichero: tail
Ø Visualizador de archivos: less
Gestion de procesos y sistemaØ Mostrar informacion sobre procesos: top
Ø Mostrar el estado de los procesos: ps7 -a7 -l7 -e7 -f
Ø Mostrar espacio disponible en disco: df
Ø Mostrar el tamano de un cierto fichero: du
Ø Lista de ficheros abiertos: lsof7 Ver conexiones puerto 80: lsof −i :807 Ver conexiones ssh: lsof −i :22
Ø Consumo de memoria: free
Trabajo con ficheros I
Ø Encontrar un patron en un fichero: grep
7 Buscar < keyword > en todos los ficheroscon extension .c
7 find ./ −name ∗.c −type f | xargs −I{} grep <keyword> {}
Ø Contar el numero de palabras en un fichero: wc
Ø Ordernar las lıneas de un fichero: sort
Ø Eliminar filas repetidas de un fichero: uniq
Ø Crear fichero tar con el contenido del actualdirectorio ( PWD )
Trabajo con ficheros II
7 tar cvf backup.tgz ∗7 Repetir la operacion cada 2 minutos:
watch −n 120 tar cvf backup.tgz ∗
Ø Backup de todos los ficheros con una ciertaextension. El nombre, incluye fecha de backup
f i n d . / \ ( −name ” ∗ . sh ” −or −name ” ∗ .m” \ ) −type f | t a r zcv fbackup sc r ip t s $ ( date ”+%d−%m−%Y %H:%M:%S” ) . tgz −T −
Redireccionamiento del flujo de datos I
Ø Enviar a segundo plano un proceso: escribirdetras del comando &
Ø Tuberıa: comando1|comando2
7 Redirige la salida del comando1 a la entradadel comando2
7 sort file | uniq | wc -l
Ø Redireccionar la salida estandar a un fichero: >
7 sort file | uniq > file uniq
Ø Redireccionar la entrada estandar de forma quese lee la informacion desde un fichero: <
Redireccionamiento del flujo de datos II
Ø Redireccionar la salida estandar anadiendo alfinal de un fichero: >>
Ø Redireccionar la salida estandar de error a unfichero: 2 >
Expresiones regulares* Elemento precedente debe aparecer 0 o mas
veces+ Elemento precedente debe aparecer 1 o mas
veces. Cualquier caracter excepto salto de lınea? El elemento precedente es opcional| Operador binario: aparece uno u otro ele-
mentoˆ Comienzo de lınea[. . . ] Caracteres admitidos[ˆ. . . ] Caracteres no admitidos$ Fin de lınea- Conjunto de caracteres: [a-zA-Z0-9]
Ejemplos de expresiones regulares
Ø man -k read | grep ˆread
Ø grep -r eth0 /etc/*
Ø grep -r etho /etc/* 2> salida.txt
Ø ps aux | grep xterm | grep -v grep
Ø ps aux | grep ’[x]term’
Ø ps aux | grep ’xterm$’
Crear un repositorio en BitBucketØ https://bitbucket.org/
Subir codigo a bitbucket: primeros pasos I
1 Desde la terminal: git init
2 echo “David Arroyo” >> contributors.txt
3 git add contributors.txt
4 git commit -m “First commit”
5 git remote add originhttps://dadm [email protected]/dadm darg/dadm-davidarroyoguardeno.git
6 git push -u origin –all
7 git push -u oriing –tags
Subir codigo a bitbucket: primeros pasosII
8 git add .
9 git commit -a -m “Second commit”
10 git push
Creacion de un proyecto en Bitbucket
1 Creacion de un equipo (e.g.,PROG2-NombreApellidos) en Bitbucket
2 Creacion de un proyecto para ese equipo
3 Creacion de repositorios dentro del proyecto
A Practica 1A Practica 2A Practica 3A Practica 4
Instrucciones basicas de git I
Ø Descargar el repositorio para trabajar en local(e.g., en el laboratorio)
ëgit clone <url proyecto: mirar overview >
Ø Obtener la ultima version en el repositorio remoto
7 git pull
Ø Enviar ultima version al repositorio local
7 git commit −a −m ‘‘Comentario sobre version’’
Ø Enviar ultima version al repositorio remoto
Instrucciones basicas de git II7 git push
Ø Ver las referencia de los commits
7 git log
Ø Ver los cambios del ultimo commit
7 git log −p
Ø Ver todas las ramas existentes
7 git branch −a7 Una rama representa un estado de evolucion
de proyecto7 Puedo tener multiples ramas de desarrollo
Instrucciones basicas de git III7 Se crea una nueva nueva rama cuando
quiero mantener un estado (normalmenteestable) del proyecto antes de realizarcambios importantes
Ø Crear una rama nueva
7git checkout −b [nombre de la rama nueva]
Ø Cambiar de rama
7 git checkout [nombre de la nueva rama detrabajo]
Primera Practica: Implementacion de unmapa de puntos
1 Definicion de tipo PUNTO, Point
2 Definicion del TAD MAPA, Map
Ejercicio 1
Ø Un PUNTO = caracter + coordenadas
Ø Existen varios tipos de sımbolos1
(a) entrada #define INPUT ’i’(b) salida #define OUTPUT ’o’(c) barrera #define BARRIER ’+’(d) espacio #define SPACE ’ ’
Ø Las coordenadas no podran ser negativas
Ø (0,0) es el vertice superior izquierdo
1se pueden crear otros si es necesario
Declaracion del TAD PUNTO point.h Itypedef struct Po in t Po in t ;
cuya definicion debe ir en el fichero point.cstruct Po in t {
char symbol ;i n t x ;i n t y ;
}
Se sigue una implementacion mediante puntero opaco
Ø Creacion (reserva de memoria) de un instancia dePUNTO point ini ()
Argumentos de entrada coordenda x , coordenaday , sımbolo
Salida puntero a Point
Declaracion del TAD PUNTO point.hII
Ø Destruccion (liberacion de recursos) point free()
Argumento de entrada puntero a Point
Fichero p1 e1.c I
1 Declarar dos puntos.
2 Inicializarlos de modo que el primero sea un puntocon sımbolo ’+’ y coordenadas (x,y) iguales a (1,2)y el segundo uno con sımbolo ’o y coordenadas(3,4)
3 Imprimir ambos puntos e imprimir despues unsalto de lınea
4 Comprobar si los dos puntos son iguales
5 Imprimir el sımbolo del primer punto junto con unafrase explicativa (ver ejemplo mas abajo)
Fichero p1 e1.c II
6 Imprimir la coordenada X del segundo punto (verejemplo mas abajo)
7 Copiar el primer punto en el segundo
8 Imprimir ambos puntos
9 Comprobar si los dos puntos son iguales
10 Liberar ambos puntos
Ejercicio P1 E2
1 Definir una estructura de datos para representarel TAD MAPA
Declaracion map.hDefinicion map.c
2 Dicho TAD almacena datos de tipo Point
7 Tamano maximo del TAD: 4096 elementos(de tipo Point )
3 Almacena dos puntos especiales:(input, output)
map.h I/∗ Movimientos pos ib les en un mapa ∗ /typedef enum {
RIGHT=0 ,UP=1 ,LEFT=2 ,DOWN=3 ,STAY=4
} Move ;
Gestion de memoria asociada a una instancia de MapMap ∗ map in i ( ) ;void map free (Map ∗ ) ;
Getters, i.e., funciones para recuperar el valor de loscampos de la estructura asociada al TAD Mapi n t map getNrows ( const Map ∗ ) ;i n t map getNcols ( const Map ∗ ) ;Po in t ∗ map getInput ( const Map ∗ ) ;Po in t ∗ map getOutput ( const Map ∗ ) ;
map.h II
Setters, i.e., funciones para asignar un valor a loscampos de la estructura asociada al TAD MapStatus map setSize (Map ∗ , i n t nrow , i n t ncol ) ;Status map setPoint (Map ∗ , const Poin t ∗ ) ;
Devuelve el punto vecino a uno dado como argumentode entrada y de acuerdo con la direccion indicadatambien como argumento de la funcionPoin t ∗ map getNeighborPoint ( const Map ∗ , const Poin t ∗ , const Move) ;
Funcion para imprimir en un fichero el mapa: devuelveel numero de caracteres escritos con exitoi n t map pr in t ( FILE ∗pf , const Map ∗ ) ;
Cliente de pruebas para el TAD Map
1 Definir un fichero p1 e1.c ⇒ ejecutable p1 e2
2 Leer un fichero que contiene el mapa
7 Primera fila: numero de filas + numero decolumnas
3 Cargar el mapa en memoria
4 Imprimir el numero de filas y columnas
5 Imprimir el mapa
⇒ La salida debe ser igual que el contenido delfichero desde el que se ha leıdo el mapa
Status map read ( FILE ∗pf , Map ∗ p l ) {char b u f f [MAX] ;i n t i , j , nrows , ncols , i n d i c e ;Po in t ∗temp ;Status s t = ERROR;
i f ( p l ==NULL | | pf==NULL) return NULL;
/∗ creamos punto que se u t i l i z a como b u f f e r ∗ /temp = p o i n t i n i (0 , 0 , ERRORCHAR) ;
i f ( temp==NULL) return NULL;
/∗ asignamos dimension a l mapa ∗ /f ge t s ( bu f f , MAX, p f ) ;sscanf ( bu f f , ”%d %d ” , &nrows , &ncols ) ;s t = map setSize ( pl , nrows , ncols ) ;i f ( s t == ERROR) return ERROR;
/∗ leemos e l f i c h e r o l i n e a a l i n e a ∗ /for ( i =0; i < nrows ; i ++) {
f ge t s ( bu f f , MAX, p f ) ;for ( j =0; j < ncols ; j ++) {
/∗ ajustamos los a t r i b u t o s de l punto l e ı do ( f a l t a a nad i r c o n t r o l deer ro res ) ∗ /
po in t se tCoord ina teX ( temp , j ) ;
po in t se tCoord ina teY ( temp , i ) ;po in t setSymbol ( temp , b u f f [ j ] ) ;
/∗ insertamos e l punto en e l mapa ( f a l t a a nad i r c o n t r o l de er ro res )∗ /
map setPoint ( p l , temp ) ;}
}
/∗ l i b e r a recursos ∗ /p o i n t d e s t r o y ( temp ) ;
/∗ no cerramos e l f i c h e r o ya que l o han a b i e r t o fuera ∗ /return OK;
}
Preguntas sobre la practica I
1 ¿Serıa posible implementar la funcion de copia de puntosempleando el siguiente prototipoSTATUS point copy(Point pDest, const Point pOrigin); ? ¿Porque?
2 ¿Es imprescindible el puntero Point ∗ enint point print(FILE ∗ pf, const Point∗ p); o podrıa serint point print(FILE ∗ pf, const Point p); ?
7 Si la respuesta es sı: ¿Por que?7 Si la respuesta es no: ¿Por que se utiliza?
Preguntas sobre la practica II3 ¿Que cambios habrıa que hacer en la funcion de copiar puntos si
quisieramos que recibiera un punto como argumento dondehubiera que copiar la informacion? Es decir, ¿como se tendrıaque implementar si en lugar dePoint ∗ point copy(const Point∗ pOrigin) , se hubiera definidocomoSTATUS point copy(const Point ∗ pSource, Point ∗ pDest) ?¿Lo siguiente serıa valido:STATUS point copy(const Point ∗ pSource, Point ∗∗ pDest) ?Discute las diferencias.
4 Indica que se tendrıa que cambiar en map.c/h para tener mapasque pudieran almacenar cualquier estructura de datos, es decir,que no estuviera limitado a almacenar puntos.
Ejemplo puntero opaco: declaracion(house.h)
typedef enum{ERROR,OK
}STATUS;
typedef struct House House ;
House ∗ h o u s e i n i t ( ) ;
STATUS house destroy ( House ∗ ) ;
i n t house get number rooms ( House ∗ ) ;i n t house get owner ( House ∗ ) ;
STATUS house set number rooms ( House ∗ , i n t ) ;STATUS house set owner ( House ∗ , i n t ) ;
Ejemplo puntero opaco: definicion(house.c). Falta control exhaustivo de
errores. Istruct House{
i n t nRooms ;i n t owner ;
} ;
House ∗ h o u s e i n i t ( ) {House ∗ pHouse = mal loc ( sizeof ( House ) ) ;return pHouse ;
}
STATUS house destroy ( House ∗ pHouse ) {i f ( pHouse ) {
return ERROR;}f r ee ( pHouse ) ;return OK;
}
Ejemplo puntero opaco: definicion(house.c). Falta control exhaustivo de
errores. IIi n t house get number rooms ( House ∗ pHouse ) {
return pHouse−>nRooms ;}i n t house get owner ( House ∗ pHouse ) {
return pHouse−>owner ;}
STATUS house set number rooms ( House ∗ pHouse , i n t nRooms) {i f ( ! pHouse )
return ERROR;pHouse −> nRooms = nRoomsreturn OK;
}STATUS house set owner ( House ∗ pHouse , i n t owner ) {
i f ( ! pHouse )return ERROR;
pHouse −> owner = owner ;return OK;
}
Cliente de pruebas
i n t main ( i n t argc , char ∗ argv [ ] ) {House ∗ pHouse = h o u s e i n i t ( ) ;i f ( ! pHouse | | argc<3)
f p r i n t f ( s tde r r , ” E r ro r en l ı nea %d de f i c h e r o %s\n ” , L INE , F ILE );
house set owner ( pHouse , a t o i ( argv [ 1 ] ) ) ;house set number rooms ( pHouse , a t o i ( argv [ 2 ] ) ) ;
house destroy ( pHouse ) ;return EXIT SUCCESS ;
}
Ejemplo 1 ficheros
#include <s t d i o . h>#include <s t d l i b . h>#define MAXLINE 20
i n t main ( i n t argc , char ∗ argv [ ] ) {char l i n e [MAXLINE ] ;
while ( f ge t s ( l i n e ,MAXLINE, s t d i n ) !=NULL && l i n e [ 0 ] != ’ \n ’ ) {f pu t s ( l i n e , s tdou t ) ;
}
return EXIT SUCCESS ;}
Mostrar mensajes de error
#include <s t d i o . h>#include <s t d l i b . h>#include <s t r i n g . h>
i n t main ( i n t argc , char ∗ argv [ ] ) {
i f ( argc<2){f p r i n t f ( s tde r r , ” Numero de argumentos i n s u f i c i e n t e \n ” ) ;return EXIT FAILURE ;
}
i f ( ! strcmp ( argv [ 1 ] , ”−1” ) ) {f p r i n t f ( s tde r r , ” E r ro r en l a l ı nea %d del f i c h e r o %s\n ” , L INE ,
F ILE ) ;}
return EXIT SUCCESS ;}