0
PYTHON
     Universidad Nacional de
            Ingenieria

   Centro de Tecnologias de
        Informacion y
       Comun...
PYTHON


            Clase 3

     Abraham Zamudio Ch.

    Abraham Zamudio Chauca
abraham.zamudio@gmail.com




         ...
Lenguaje C




Una introduccion




    Abraham Zamudio   3
Abraham Zamudio   4
C: Etapas de Compilacion




         Abraham Zamudio   5
El Lenguaje C

● Es un lenguaje de programación de alto nivel, de propósito
  general, sintácticamente económico.
● Proxim...
Genealogia de C




     Abraham Zamudio   7
Estructura de un programa en C

Generalmente, un programa en C tiene la
siguiente estructura:
● Comandos para el preproces...
Estructura de un programa en C
/*
Programa de Ejemplo
Fecha_
Autor_
*/
#include ____
#define ____
typedef ____
[Prototipos...
Estructura de una función en C


Cada función debe contener:
● Un encabezado de la función, que está

  compuesta por el n...
Estructura de una función en C




            Abraham Zamudio      11
El Preprocesador de C

El preprocesador tiene más o menos su propio lenguaje el cual
puede ser una herrramienta muy podero...
El Preprocesador de C
                 #define

El preprocesador también permite configurar el lenguaje. Por
ejemplo, para...
El Preprocesador de C
                #define
La directiva #define se usa para definir constantes
o cualquier sustitución ...
El Preprocesador de C
                   #define
La directiva #define tiene otra poderosa característica: el nombre
de mac...
El Preprocesador de C
               #define

Otros ejemplos usando #define pueden ser:

#define Deg_a_Rad(X) (X*M_PI/180....
El Preprocesador de C
                #undef

Se usa #undef para quitar una definición de
nombre de macro que se haya defi...
El Preprocesador de C
               #include
La directiva del preprocesador #include instruye al
compilador para incluir ...
El Preprocesador de C
                 #include
Cuando se indica <archivo> se le dice al compilador que
busque donde estan...
El Preprocesador de C
      #if (Inclusión condicional)

La directiva #if evalua una expresión constante
entera. Siempre s...
El Preprocesador de C
      #if (Inclusión condicional)
#if k-expresion-1
                  <seccion-1>
#elif k-expresion-...
El Preprocesador de C
        #if (Inclusión condicional)
Por ejemplo :

#define MEX 0
#define EUA 1
#define FRAN 2

#defi...
Lectura de Datos desde la
                  consola
● El prototipo de la función main que se utiliza comúnmente es:
    in...
Lecura de Datos desde la consola




             Abraham Zamudio   24
Primer Ejemplo (C)
#include <stdio.h>

main(int argc, char *argv[])
{
    int i,n;
/*Control de numero de argumentos. Es u...
Segundo Ejemplo (C)
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  int i;
  char **p;

    pu...
Tercer Ejemplo (C)
#include <fcntl.h>
main(argc,argv)
int argc;
char * argv[];{
char buffer[16],c;
int l,f1,f2,i;
f1=0;f2=...
#include <stdio.h>
                      #include <stdlib.h>
                      #include <math.h>

                    ...
Memoria dinámica: malloc y free

Los variables y vectores en C ocupan un tamaño prefijado,
no pueden variarlo durante la e...
Memoria dinámica: malloc y free


      void* malloc ( unsigned numero_de_bytes );

El tamaño se especifica en bytes. Se g...
Memoria dinámica: malloc y free
              void *malloc(size_t size);
Lo anterior indica que regresará un apuntador del...
Memoria dinámica: malloc y free
char *cp;
cp = (char *) malloc(100);

Intenta obtener 100 bytes y asignarlos a la
direcció...
Memoria dinámica: malloc y free
El compilador de C requiere hacer una conversión
del tipo. La forma de lograr la coerción ...
Memoria dinámica: malloc y free
            (sizeof)
La función sizeof() puede ser usada para encontrar el tamaño de
cualq...
Memoria dinámica: malloc
                (sizeof)
En el siguiente ejemplo se reserva memoria para la variable ip, en
donde...
#include <stdio.h>

int main(void)
{
                                            Malloc rulez !!!!!
float *bufferFloat;
in...
Librerias (C)


Las librerías son archivos que contienen código
objeto agrupado en funciones o subrutinas que
pueden ser u...
Librerias (C)
El ejemplo mas popular de librerías en Unix es la libc, que es
la librería estándar de funciones C, y contie...
Librerias (C)


Se pueden destacar dos formas de utilización de las
librerías:
● Para utilización local, es decir, como un...
Librerias (C)


Las librerías de utilización local deben ser
registradas en alguna variable de ambiente del
sistema para i...
Librerias del Sistema

● libc. Librería estándar de C.
  ● Entrada y salida estándar: scanf, printf, getchar, que utiliza ...
Makefiles (1º Acto)


El comando de linux make nos ayuda a compilar
nuestros programas. Presenta muchas ventajas
para prog...
Makefiles (1º Acto)

●Es capaz de saber qué cosas hay que recompilar. Si cuando
 estamos depurando nuestro programa tocamo...
Makefiles (1º Acto)


HolaMundo.c


#include <stdio.h>
main()
{
   printf ("Hola mundon");
}

                      Abraha...
Makefiles (1º Acto)




Lo compilaremos de la forma habitual.

$ gcc HolaMundo.c -o HolaMundo




                    Abra...
Makefiles (1º Acto)


Lo probamos y ¡funciona!. Nada espectacular
hasta ahora. Vuelve a compilarlo con el mismo
comando. S...
Makefiles (1º Acto)


Pues make te dirá que no hay nada que hacer.
Primera diferencia con compilar a mano. Como el
program...
Makefiles (1º Acto)



Borra el ejecutable y vuelve a hacer make

$ rm HolaMundo
$ make HolaMundo



                    A...
Makefiles (2º Acto)


Crear dos directorios :

 ●   PRINCIPAL : HolaMundo.c

 ●   FUNCION1 : texto1.h




                ...
Makefiles (2º Acto)
●   HolaMundo.c                   ●   texto1.h
    #include <stdio.h>                #define TEXTO "Ho...
Makefiles (2º Acto)


Ahora nos metemos en el directorio PRINCIPAL y
hacemos, como antes make HolaMundo. Como
es de espera...
Makefiles (2º Acto)

Una variable bastante interesante es CFLAGS
(CPPFLAGS para el compilador de C++). Esta variable
puede...
Makefiles (2º Acto)

Una de las opciones que se puede pasar al
compilador es la opción -I, que nos permite poner
paths de ...
Makefiles (3º Acto)
Pongamos ahora en el directorio FUNCION1 dos
ficheros. Un funcion1.h y un funcion1.c. El
contenido de ...
Makefiles (3º Acto)

En cuanto al programa en el directorio
PRINCIPAL, lo modificamos para que ponga esto:
HolaMundo.c

#i...
Makefiles (3º Acto)

Desde el directorio PRINCIPAL ponemos nuestra variable
CFLAGS como antes y hacemos el make.

$ CFLAGS...
Creando Makefiles



objetivo: dependencia1 dependencia2 ...
<tab>comando1
<tab>comando2
<tab>...




                    ...
Creando Makefiles
●objetivo es lo que queremos construir. Puede ser el nombre de un ejecutable,
 el nombre de una librería...
Creando Makefiles



HolaMundo: HolaMundo.c ../FUNCION1/funcion1.c ../FUNCION1/funcion1.h
    gcc -I../FUNCION1 HolaMundo....
Upcoming SlideShare
Loading in...5
×

Clase3_Python-CTIC

1,352

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,352
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
39
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Clase3_Python-CTIC"

  1. 1. PYTHON Universidad Nacional de Ingenieria Centro de Tecnologias de Informacion y Comunicaciones Facultad de Ciencias Abraham Zamudio Ch. Abraham Zamudio 1
  2. 2. PYTHON Clase 3 Abraham Zamudio Ch. Abraham Zamudio Chauca abraham.zamudio@gmail.com Abraham Zamudio 2
  3. 3. Lenguaje C Una introduccion Abraham Zamudio 3
  4. 4. Abraham Zamudio 4
  5. 5. C: Etapas de Compilacion Abraham Zamudio 5
  6. 6. El Lenguaje C ● Es un lenguaje de programación de alto nivel, de propósito general, sintácticamente económico. ● Proximidad a la máquina. ● Potente. ● Su estructura sintáctica y semántica está edificada sobre conceptos tales como: ● estructuras sencillas, ● jerarquía de bloques y ● control de flujo de datos. ● Instrucciones similares a expresiones algebraicas. ● Buen conjunto de operadores. ● Fácil de aprender. Abraham Zamudio 6
  7. 7. Genealogia de C Abraham Zamudio 7
  8. 8. Estructura de un programa en C Generalmente, un programa en C tiene la siguiente estructura: ● Comandos para el preprocesador (CPP). ● Definiciones de tipo de datos de las variables (definición de variables globales). ● Prototipos de funciones (define el nombre de la función, el tipo que retorna y los parámetros que recibe, aunque pueden aparecer sólo los tipos de éstos). ● Funciones (incluyendo la función main()). Abraham Zamudio 8
  9. 9. Estructura de un programa en C /* Programa de Ejemplo Fecha_ Autor_ */ #include ____ #define ____ typedef ____ [Prototipos] int main(void) { [variables] /* descripcion */ [instrucciones] return 0; } Abraham Zamudio 9
  10. 10. Estructura de una función en C Cada función debe contener: ● Un encabezado de la función, que está compuesta por el nombre de ésta, seguido de una lista opcional de argumentos encerrados entre paréntesis y el tipo de dato que retorna. ● Una lista de declaración de argumentos. ● Una o más instrucciones, que conforman el cuerpo de la función. Abraham Zamudio 10
  11. 11. Estructura de una función en C Abraham Zamudio 11
  12. 12. El Preprocesador de C El preprocesador tiene más o menos su propio lenguaje el cual puede ser una herrramienta muy poderosa para el programador. Todas las directivas de preprocesador o comandos inician con un #. Las ventajas que tiene usar el preprocesador son: ● los programas son más fáciles de desarrollar, ● son más fáciles de leer, ● son más fáciles de modificar ● y el código de C es más transportable entre diferentes arquitecturas de máquinas. Abraham Zamudio 12
  13. 13. El Preprocesador de C #define El preprocesador también permite configurar el lenguaje. Por ejemplo, para cambiar a las sentencias de bloque de código { ... } delimitadores que haya inventado el programador como inicio ... fin se puede hacer: #define inicio { #define fin } Durante la compilación todas las ocurrencias de inicio y fin serán reemplazadas por su correspondiente { o } delimitador y las siguientes étapas de compilación de C no encontrarán ninguna diferencia. Abraham Zamudio 13
  14. 14. El Preprocesador de C #define La directiva #define se usa para definir constantes o cualquier sustitución de macro. Su formato es el siguiente: #define <nombre de macro> <nombre de reemplazo> Por ejemplo: #define FALSO 0 #define VERDADERO !FALSO Abraham Zamudio 14
  15. 15. El Preprocesador de C #define La directiva #define tiene otra poderosa característica: el nombre de macro puede tener argumentos. Cada vez que el compilador encuentra el nombre de macro, los argumentos reales encontrados en el programa reemplazan los argumentos asociados con el nombre de la macro. Por ejemplo: #include <stdio.h> #define MIN(a,b) (a < b) ? a : b Cambia este pequeño programa, usa argc y argv para main() ingresar los argumentos de MIN { por teclado int x=125, y=20; printf("EL minimo es %dn", MIN(x,y) ); } Abraham Zamudio 15
  16. 16. El Preprocesador de C #define Otros ejemplos usando #define pueden ser: #define Deg_a_Rad(X) (X*M_PI/180.0) /* Convierte grados sexagesimales a radianes, M_PI es el valor de pi y esta definida en la biblioteca math.h */ Abraham Zamudio 16
  17. 17. El Preprocesador de C #undef Se usa #undef para quitar una definición de nombre de macro que se haya definido previamente. El formato general es: #undef <nombre de macro> El uso principal de #undef es permitir localizar los nombres de macros sólo en las secciones de código que los necesiten. Abraham Zamudio 17
  18. 18. El Preprocesador de C #include La directiva del preprocesador #include instruye al compilador para incluir otro archivo fuente que esta dado con esta directiva y de esta forma compilar otro archivo fuente. El archivo fuente que se leerá se debe encerrar entre comillas dobles o paréntesis de ángulo. Por ejemplo: #include <archivo> #include "archivo" Abraham Zamudio 18
  19. 19. El Preprocesador de C #include Cuando se indica <archivo> se le dice al compilador que busque donde estan los archivos incluidos o ``include'' del sistema. Usualmente los sistemas con UNIX guardan los archivos en el directorio /usr/include. Si se usa la forma "archivo" es buscado en el directorio actual, es decir, donde el programa esta siendo ejecutado. Los archivos incluidos usualmente contienen los prototipos de las funciones y las declaraciones de los archivos cabecera (header files) y no tienen código de C (algoritmos). Abraham Zamudio 19
  20. 20. El Preprocesador de C #if (Inclusión condicional) La directiva #if evalua una expresión constante entera. Siempre se debe terminar con #endif para delimitir el fin de esta sentencia. Se pueden así mismo evaluar otro código en caso se cumpla otra condición, o bien, cuando no se cumple ninguna usando #elif o #else respectivamente. Abraham Zamudio 20
  21. 21. El Preprocesador de C #if (Inclusión condicional) #if k-expresion-1 <seccion-1> #elif k-expresion-2 <seccion-2> ... #elif k-expresion-n <seccion-n> #else <seccion-final> #endif Abraham Zamudio 21
  22. 22. El Preprocesador de C #if (Inclusión condicional) Por ejemplo : #define MEX 0 #define EUA 1 #define FRAN 2 #define PAIS_ACTIVO MEX #if PAIS_ACTIVO == MEX char moneda[]="pesos"; #elif PAIS_ACTIVO == EUA char moneda[]="dolar"; #else char moneda[]="franco"; #endif Abraham Zamudio 22
  23. 23. Lectura de Datos desde la consola ● El prototipo de la función main que se utiliza comúnmente es: int main( void ) ● La rutina main no admite ningún parámetro. ● Sin embargo existe otro posible prototipo para esta función: ● int main( int argc, char **argv ) o int main( int argc, char *argv[] ) Donde: ● int argc: Este parámetro contiene el número de argumentos con los que el programa ha sido llamado, incluyendo mismo nombre del programa (binario). ● char **argv: Array de punteros a punteros de cadenas de caracteres. ● Ejemplo: ● ps –eo pid,ppid,stat,command ● La función main es llamada por el Sistema Operativo (específicamentepor el kernel). Abraham Zamudio 23
  24. 24. Lecura de Datos desde la consola Abraham Zamudio 24
  25. 25. Primer Ejemplo (C) #include <stdio.h> main(int argc, char *argv[]) { int i,n; /*Control de numero de argumentos. Es un control habitual en todo programa Unix que debe aceptar un numero determinado de argumentos. */ if (argc < 1) { fprintf(stderr,"argv: utilización argv arg1 arg2 arg3 arg4 ...n"); return 0; } /* Visualiza todos los argumentos. Cada componente de argv es una tira. El primer componente es el nombre del programa que se ejecuta */ for (i=0;i<argc;i++) printf("El argumento %d es %sn",i,argv[i]); printf("n"); } Abraham Zamudio 25
  26. 26. Segundo Ejemplo (C) #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int i; char **p; puts("-------------"); puts("forma 1: n"); for (i = 0; i < argc; i++) printf("argv[%d]=%sn", i, argv[i]); puts("-------------"); puts("forma 2: n"); for (p = argv; *p != NULL; p++) printf("argv[%ld]=%sn", (long) (p - argv), *p); puts("-------------"); return EXIT_SUCCESS; } Abraham Zamudio 26
  27. 27. Tercer Ejemplo (C) #include <fcntl.h> main(argc,argv) int argc; char * argv[];{ char buffer[16],c; int l,f1,f2,i; f1=0;f2=1; switch(argc){ case 3: f2=open(argv[2],O_WRONLY|O_CREAT); case 2: f1=open(argv[1],O_RDONLY); break; case 1: break; default: perror("Error: demasiados argumentos"); return 0; } while((l=read(f1,buffer,sizeof(buffer)))>0){ for(i=0;i<l;i++){ c = (char)buffer[i]; if (islower(c)) buffer[i]=(char)toupper((int)buffer[i]); else if (isupper(c)) buffer[i]=(char)tolower((int)buffer[i]); } write(f2,buffer,l); } } Abraham Zamudio 27
  28. 28. #include <stdio.h> #include <stdlib.h> #include <math.h> int calcula ( float, float ); int main(){ float a, b; Elimina printf y int mcd; printf("Programa que calcula el MCD de dos numeros:nn"); printf("Inserta a: "); scanf("%f", &a); scanf usando printf("Inserta b: "); scanf("%f", &b); mcd= calcula (a , b); printf("El mcd de a y b es %dnn", mcd); argc y argv getchar (); return 0; } int calcula ( float a, float b ) { float r, rmcd = 0; do { r = fmod ( a, b ); if ( r == 0 ) b = rmcd; else { a = b; b = r; rmcd = b; } } while ( r != 0 ); return ( rmcd ); } Abraham Zamudio 28
  29. 29. Memoria dinámica: malloc y free Los variables y vectores en C ocupan un tamaño prefijado, no pueden variarlo durante la ejecución del programa. Por medio de punteros se puede reservar o liberar memoria dinámicamente, es decir, según se necesite. Para ello existen varias funciones estándares, de la biblioteca <stdlib.h>x La función malloc sirve para solicitar un bloque de memoria del tamaño suministrado como parámetro. Devuelve un puntero a la zona de memoria concedida: Abraham Zamudio 29
  30. 30. Memoria dinámica: malloc y free void* malloc ( unsigned numero_de_bytes ); El tamaño se especifica en bytes. Se garantiza que la zona de memoria concedida no está ocupada por ninguna otra variable ni otra zona devuelta por malloc. Si malloc es incapaz de conceder el bloque (p.ej. no hay memoria suficiente), devuelve un puntero nulo. Abraham Zamudio 30
  31. 31. Memoria dinámica: malloc y free void *malloc(size_t size); Lo anterior indica que regresará un apuntador del tipo void *, el cual es el inicio en memoria de la porción reservada de tamaño size. Si no puede reservar esa cantidad de memoria la función regresa un apuntador nulo o NULL Dado que void * es regresado, C asume que el apuntador puede ser convertido a cualquier tipo. El tipo de argumento size_t esta definido en la cabecera stddef.h y es un tipo entero sin signo. Abraham Zamudio 31
  32. 32. Memoria dinámica: malloc y free char *cp; cp = (char *) malloc(100); Intenta obtener 100 bytes y asignarlos a la dirección de inicio a cp. Es usual usar la función sizeof() para indicar el número de bytes, por ejemplo: int *ip; ip = (int *) malloc(100 * sizeof(int) ); Abraham Zamudio 32
  33. 33. Memoria dinámica: malloc y free El compilador de C requiere hacer una conversión del tipo. La forma de lograr la coerción (cast) es usando (char *) y (int *), que permite convertir un apuntador void a un apuntador tipo char e int respectivamente. Hacer la conversión al tipo de apuntador correcto asegura que la aritmética con el apuntador funcionará de forma correcta. s una buena práctica usar sizeof() aún si se conoce el tamaño actual del dato que se requiere, -- ya que de esta forma el código se hace independiente del dispositivo (portabilidad). Abraham Zamudio 33
  34. 34. Memoria dinámica: malloc y free (sizeof) La función sizeof() puede ser usada para encontrar el tamaño de cualquier tipo de dato, variable o estructura. Simplemente se debe proporcionar uno de los anteriores como argumento a la función. Por lo tanto: int i; struct COORD {float x,y,z}; struct COORD *pt; sizeof(int), sizeof(i), sizeof(struct COORD) son tambien sentencias correctas. Abraham Zamudio 34
  35. 35. Memoria dinámica: malloc (sizeof) En el siguiente ejemplo se reserva memoria para la variable ip, en donde se emplea la relación que existe entre apuntadores y arreglos, para manejar la memoria reservada como un arreglo. Por ejemplo, se pueden hacer cosas como: main() { int *ip, i; ip = (int *) malloc(100 * sizeof(int) ); ip[0] = 1000; for (i=0; i<100; ++i) scanf("%d",ip++); } Abraham Zamudio 35
  36. 36. #include <stdio.h> int main(void) { Malloc rulez !!!!! float *bufferFloat; int num, i; /*Lee el numero de datos que se van a introducir y despues pide los valores*/ printf ("nCuántos valores va a introducir? "); scanf ("%d", &num); bufferFloat = (float *) malloc (sizeof(float) * num); for (i=0;i<num;i++) { printf ("Introduzca el valor numero %d: ", i+1); scanf ("%f", (bufferFloat + i)); } for (i=0;i<num;i++) { printf ("El valor numero %d que introdujo fue ----> %fn", i+1, *(bufferFloat+i)); } free(bufferFloat); return 0; } Abraham Zamudio 36
  37. 37. Librerias (C) Las librerías son archivos que contienen código objeto agrupado en funciones o subrutinas que pueden ser utilizadas por otros programas. Estos archivos tienen una estructura especial dependiendo del tipo de librería que se trate. Abraham Zamudio 37
  38. 38. Librerias (C) El ejemplo mas popular de librerías en Unix es la libc, que es la librería estándar de funciones C, y contiene subrutinas utilizables para operaciones de entrada y salida. La notación estándar de la librería es: ● libpalabra.extensión ● palabra: diferencia unas librerías de otras, dando una idea de qué tipo de funciones contiene. ● extensión: indica el tipo de librería, la cual puede ser estática (.a) o dinámica o compartida (.so). Abraham Zamudio 38
  39. 39. Librerias (C) Se pueden destacar dos formas de utilización de las librerías: ● Para utilización local, es decir, como un elemento mas del desarrollo de una aplicación. ● Son de fácil mantención. ● Como un paquete de funciones desarrolladas por un fabricante. ● No es posible modificarlas. ● En general, el sistema conoce su ubicación. Abraham Zamudio 39
  40. 40. Librerias (C) Las librerías de utilización local deben ser registradas en alguna variable de ambiente del sistema para indicar su ubicación, por ejemplo, LD_LIBRARY_PATH. $echo $ LD_LIBRARY_PATH Abraham Zamudio 40
  41. 41. Librerias del Sistema ● libc. Librería estándar de C. ● Entrada y salida estándar: scanf, printf, getchar, que utiliza el archivo cabecera stdio.h. ● Funciones de manipulación de caracteres y string: strcpy, strlen, etc. ● Fechas: ctime, etc. ● Llamadas al sistema: como fork(). ● Linux utiliza Glic, la librería C GNU. ● libm. Librería de funciones matemáticas: cos, sin, exp, etc. ● libX11. Librería interfaz gráfica para el sistema X, con funciones como xterm, xload, etc. ● libGL: librería de OpenGL. ● libpthread: librería de POSIX threads. Abraham Zamudio 41
  42. 42. Makefiles (1º Acto) El comando de linux make nos ayuda a compilar nuestros programas. Presenta muchas ventajas para programas grandes, en los que hay muchos ficheros fuente (muchos .c y muchos .h) repartidos por varios directorios. Principalmente aporta dos ventajas: Abraham Zamudio 42
  43. 43. Makefiles (1º Acto) ●Es capaz de saber qué cosas hay que recompilar. Si cuando estamos depurando nuestro programa tocamos un fichero fuente, al compilar con make sólo se recompilaran aquellos ficheros que dependan del que hemos tocado. Si compilamos a mano con gcc, (o el compilador que sea), o tenemos en la cabeza esas dependencias para compilar sólo lo que hace falta, o lo compilamos todo. Si el proyecto es grande, se nos olvidará alguna dependencia o nos pasaremos horas compilando. ●Nos guarda los comandos de compilación con todos sus parámetros para encontrar librerías, ficheros de cabecera (.h), etc, etc. No tendremos que escribir largas líneas de compilación con montones de opciones que debemos saber de memoria o, al menos, sólo tendremos que hacerlo una vez. Abraham Zamudio 43
  44. 44. Makefiles (1º Acto) HolaMundo.c #include <stdio.h> main() { printf ("Hola mundon"); } Abraham Zamudio 44
  45. 45. Makefiles (1º Acto) Lo compilaremos de la forma habitual. $ gcc HolaMundo.c -o HolaMundo Abraham Zamudio 45
  46. 46. Makefiles (1º Acto) Lo probamos y ¡funciona!. Nada espectacular hasta ahora. Vuelve a compilarlo con el mismo comando. Se vuelve a compilar y sigue funcionando. Veamos ahora con make. Si haces $ make HolaMundo Abraham Zamudio 46
  47. 47. Makefiles (1º Acto) Pues make te dirá que no hay nada que hacer. Primera diferencia con compilar a mano. Como el programa ya está hecho, make no hace nada. Esto, en un programa de muchas líneas de código que tarda varios minutos en compilar, es una gran ventaja. Abraham Zamudio 47
  48. 48. Makefiles (1º Acto) Borra el ejecutable y vuelve a hacer make $ rm HolaMundo $ make HolaMundo Abraham Zamudio 48
  49. 49. Makefiles (2º Acto) Crear dos directorios : ● PRINCIPAL : HolaMundo.c ● FUNCION1 : texto1.h Abraham Zamudio 49
  50. 50. Makefiles (2º Acto) ● HolaMundo.c ● texto1.h #include <stdio.h> #define TEXTO "Hola Mundo" #include <texto.h> main() { printf ("%sn", TEXTO); } Abraham Zamudio 50
  51. 51. Makefiles (2º Acto) Ahora nos metemos en el directorio PRINCIPAL y hacemos, como antes make HolaMundo. Como es de esperar, obtenemos un error. No sabe encontrar el fichero texto.h, puesto que no está en los directorios por defecto de búsqueda de ficheros .h. Abraham Zamudio 51
  52. 52. Makefiles (2º Acto) Una variable bastante interesante es CFLAGS (CPPFLAGS para el compilador de C++). Esta variable puede contener las opciones que queramos que se pasen al compilador. Por ejemplo, si hacermos $ CFLAGS=-g; export CFLAGS $ make HolaMundo veremos cómo al compilar el fichero HolaMundo se le pasa al compilador la opción -g (para poder meter luego el debugger). Abraham Zamudio 52
  53. 53. Makefiles (2º Acto) Una de las opciones que se puede pasar al compilador es la opción -I, que nos permite poner paths de busqueda para ficheros de cabecera (.h). En nuestro ejemplo, y usando un path relativo, deberíamos poner algo así como -I../FUNCION1. Vamos a ello: $ CFLAGS=-I../FUNCION1; export CFLAGS $ make HolaMundo Abraham Zamudio 53
  54. 54. Makefiles (3º Acto) Pongamos ahora en el directorio FUNCION1 dos ficheros. Un funcion1.h y un funcion1.c. El contenido de estos ficheros sería: funcion1.h funcion1.c void escribeHolaMundo(); #include <stdio.h> void escribeHolaMundo() { El fichero texto.h podemos printf ("Hola Mundon"); borrarlo porque ya no nos servirá } más. Abraham Zamudio 54
  55. 55. Makefiles (3º Acto) En cuanto al programa en el directorio PRINCIPAL, lo modificamos para que ponga esto: HolaMundo.c #include <funcion1.h> main() { escribeHolaMundo (); } Abraham Zamudio 55
  56. 56. Makefiles (3º Acto) Desde el directorio PRINCIPAL ponemos nuestra variable CFLAGS como antes y hacemos el make. $ CFLAGS=-I../FUNCION1; export CLFAGS $ make HolaMundo Obtenemos otra vez un error. make compila el fichero HolaMundo.c, no compila el fichero funcion1.c y obtenemos un error. Esto ya es demasiado para resolverlo con variables de entorno. En el momento que tenemos dos ficheros .c para construir un único ejecutable, necesitamos decirle a make cuáles son los ficheros que debe compilar. Abraham Zamudio 56
  57. 57. Creando Makefiles objetivo: dependencia1 dependencia2 ... <tab>comando1 <tab>comando2 <tab>... Abraham Zamudio 57
  58. 58. Creando Makefiles ●objetivo es lo que queremos construir. Puede ser el nombre de un ejecutable, el nombre de una librería o cualquier palabra que nos inventemos. Para nuestro ejemplo, podemos poner que nuestro objetivo es el nombre de nuestro ejecutable, es decir HolaMundo. ●dependencia<i> es el nombre de otro objetivo que debe hacerse antes que el nuestro o bien ficheros de los que depende nuestro objetivo. En nuestro ejemplo, las dependencias serían nuestros ficheros fuente HolaMundo.c, ../FUNCION1/funcion1.h y ../FUNCION1/funcion1.c ya que para hacer el ejecutable necesitamos todos esos fuentes y si los tocamos, posiblemente debamos rehacer el ejecutable. ●<tab> es un tabulador. Es importante que ahi pongamos un tabulador, porque si no el fichero no se lee correctamente. ●comando<i> es lo que se tiene que ejecutar para construir nuestro objetivo. Se irán ejecutando estos comandos en secuencia. Puede ser cualquier comando de shell válido. (cc, rm, cp, ls, o incluso un script que nos hayamos hecho). En nuestro ejemplo, sería cc HolaMundo.c -o HolaMundo. Abraham Zamudio 58
  59. 59. Creando Makefiles HolaMundo: HolaMundo.c ../FUNCION1/funcion1.c ../FUNCION1/funcion1.h gcc -I../FUNCION1 HolaMundo.c ../FUNCION1/funcion1.c -o HolaMundo Ahora, después de borrar el ejecutable, si hacemos make (a secas, sin parámetro), se volverá a compilar nuestro programa. Si a make no le ponemos parámetro, buscará un fichero Makefile y dentro de él hará el primer objetivo que encuentre. En nuestro caso, el único que hay es HolaMundo. Abraham Zamudio 59
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×