Ceballos: C/C++ - Curso de programación 4Ed.

September 6, 2017 | Author: Fco. Javier Ceballos Sierra | Category: Pointer (Computer Programming), C++, Computer Programming, Programming Language, Data Type
Share Embed Donate


Short Description

Lógica de programación. Elementos del lenguaje. Estructura de un programa. Entrada y salida. Sentencias de control. Matr...

Description

C/C++ Curso de Programación 4.ª edición Fco. Javier Ceballos Sierra Profesor titular de la Escuela Politécnica Superior Universidad de Alcalá

http://www.fjceballos.es/

C/C++: Curso de programación. 4.ª edición © Fco. Javier Ceballos Sierra © De la edición: RA-MA 2015 MARCAS COMERCIALES: las marcas de los productos citados en el contenido de este libro (sean o no marcas registradas) pertenecen a sus respectivos propietarios. RA-MA no está asociada a ningún producto o fabricante mencionado en la obra, los datos y los ejemplos utilizados son ficticios salvo que se indique lo contrario. RA-MA es una marca comercial registrada. Se ha puesto el máximo empeño en ofrecer al lector una información completa y precisa. Sin embargo, RA-MA Editorial no asume ninguna responsabilidad derivada de su uso, ni tampoco por cualquier violación de patentes ni otros derechos de terceras partes que pudieran ocurrir. Esta publicación tiene por objeto proporcionar unos conocimientos precisos y acreditados sobre el tema tratado. Su venta no supone para el editor ninguna forma de asistencia legal, administrativa ni de ningún otro tipo. En caso de precisarse asesoría legal u otra forma de ayuda experta, deben buscarse los servicios de un profesional competente. Reservados todos los derechos de publicación en cualquier idioma. Según lo dispuesto en el Código Penal vigente, ninguna parte de este libro puede ser reproducida, grabada en sistema de almacenamiento o transmitida en forma alguna ni por cualquier procedimiento, ya sea electrónico, mecánico, reprográfico, magnético o cualquier otro, sin autorización previa y por escrito de RA-MA; su contenido está protegido por la ley vigente, que establece penas de prisión y/o multas a quienes intencionadamente reprodujeren o plagiaren, en todo o en parte, una obra literaria, artística o científica. Editado por: RA-MA Editorial C/ Jarama, 3A, Polígono industrial Igarsa 28860 Paracuellos del Jarama, Madrid Teléfono: 91 658 42 80 Telefax: 91 662 81 39 Correo electrónico: [email protected] Internet: www.ra-ma.es y www.ra-ma.com ISBN: 978-84-9964-527-8 Depósito Legal: M-2512-2015 Autoedición: Fco. Javier Ceballos Filmación e impresión: Copias Centro, S.L. Impreso en España Primera impresión: marzo 2015

La mente es como un paracaídas. Solo funciona si la tenemos abierta. Einstein Dedico esta obra a María del Carmen, mi esposa, y a mis hijos Francisco y Javier.

CONTENIDO PRÓLOGO.............................................................................................................. XIX  CAPÍTULO 1. FASES EN EL DESARROLLO DE UN PROGRAMA ............



QUÉ ES UN PROGRAMA................................................................................. LENGUAJES DE PROGRAMACIÓN............................................................... Compiladores ................................................................................................. Intérpretes....................................................................................................... ¿QUÉ ES C? ........................................................................................................ HISTORIA DEL LENGUAJE C ........................................................................ Lenguaje C++................................................................................................. REALIZACIÓN DE UN PROGRAMA EN C ................................................... Edición de un programa ................................................................................. ¿Qué hace este programa?......................................................................... Guardar el programa escrito en el disco ......................................................... Compilar y ejecutar el programa .................................................................... Biblioteca de funciones ............................................................................. Guardar el programa ejecutable en el disco ................................................... Depurar un programa ..................................................................................... UN AVANCE SOBRE LA PROGRAMACIÓN CON C ................................... Entrada y salida .............................................................................................. Matrices .......................................................................................................... Sentencias de control ..................................................................................... Funciones ....................................................................................................... EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

1  2  4  4  4  5  6  7  8  9  10  10  11  12  13  13  14  15  16  18  19  21

VIII

C/C++: CURSO DE PROGRAMACIÓN

CAPÍTULO 2. ELEMENTOS DEL LENGUAJE C ...........................................

23 

PRESENTACIÓN DE LA SINTAXIS DE C ..................................................... CARACTERES DE C ......................................................................................... Letras, dígitos y carácter de subrayado .......................................................... Espacios en blanco ......................................................................................... Caracteres especiales y signos de puntuación ................................................ Secuencias de escape...................................................................................... TIPOS DE DATOS ............................................................................................. Tipos primitivos ............................................................................................. char............................................................................................................ short .......................................................................................................... int .............................................................................................................. long ........................................................................................................... enum.......................................................................................................... Creación de una enumeración .............................................................. float ........................................................................................................... double........................................................................................................ Ejemplo: tipos de datos .................................................................................. Tipos derivados .............................................................................................. SINÓNIMOS DE UN TIPO ................................................................................ LITERALES ....................................................................................................... Literales enteros ............................................................................................. Literales reales ............................................................................................... Literales de un solo carácter ........................................................................... Literales de cadenas de caracteres .................................................................. IDENTIFICADORES ......................................................................................... PALABRAS CLAVE .......................................................................................... COMENTARIOS ................................................................................................ DECLARACIÓN DE CONSTANTES SIMBÓLICAS ...................................... Constantes C++ .............................................................................................. ¿Por qué utilizar constantes? .......................................................................... DECLARACIÓN DE UNA VARIABLE ........................................................... Iniciación de una variable .............................................................................. EXPRESIONES NUMÉRICAS .......................................................................... OPERADORES................................................................................................... Operadores aritméticos................................................................................... Operadores de relación................................................................................... Operadores lógicos ......................................................................................... Operadores unitarios ...................................................................................... Operadores a nivel de bits .............................................................................. Operadores de asignación .............................................................................. Operador condicional .....................................................................................

23  24  24  24  25  25  26  26  27  28  28  28  29  29  31  32  32  33  33  35  35  36  36  37  38  38  39  39  40  40  40  41  42  42  42  44  45  46  46  47  49 

CONTENIDO

IX

Otros operadores ............................................................................................ Operador sizeof ......................................................................................... Operador coma .......................................................................................... Operador dirección-de .............................................................................. Operador de indirección ............................................................................ PRIORIDAD Y ORDEN DE EVALUACIÓN ................................................... CONVERSIÓN ENTRE TIPOS DE DATOS..................................................... EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

50  50  51  51  52  53  54  58  60

CAPÍTULO 3. ESTRUCTURA DE UN PROGRAMA...........................................

63 

ESTRUCTURA DE UN PROGRAMA C .......................................................... Directrices para el preprocesador ................................................................... Directriz de inclusión ................................................................................ Directriz de sustitución ............................................................................. Definiciones y declaraciones.......................................................................... Sentencia simple ............................................................................................ Sentencia compuesta o bloque ....................................................................... Funciones ....................................................................................................... Declaración de una función ...................................................................... Definición de una función ......................................................................... Llamada a una función .............................................................................. Función main.................................................................................................. Un ejemplo ..................................................................................................... PASANDO ARGUMENTOS A LAS FUNCIONES.......................................... PROGRAMA C FORMADO POR MÚLTIPLES FICHEROS .......................... ÁMBITO DE UNA VARIABLE ........................................................................ Variables globales y locales ........................................................................... CLASES DE ALMACENAMIENTO DE UNA VARIABLE............................ Calificación de variables globales .................................................................. Calificación de variables locales .................................................................... Calificación de funciones ............................................................................... EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

63  67  68  68  69  69  70  70  71  73  75  75  76  77  81  83  84  86  86  88  90  90  93

CAPÍTULO 4. ENTRADA Y SALIDA ESTÁNDAR .........................................

99 

DATOS NUMÉRICOS Y CADENAS DE CARACTERES .............................. FLUJOS DE E/S ESTÁNDAR ........................................................................... SALIDA CON FORMATO ................................................................................ ENTRADA CON FORMATO ............................................................................

100  101  102  108 

X

C/C++: CURSO DE PROGRAMACIÓN

CARÁCTER FIN DE FICHERO ........................................................................ CARÁCTER \n ................................................................................................... Limpiar el buffer de la entrada estándar......................................................... LEER UN CARÁCTER DE LA ENTRADA ESTÁNDAR ............................... ESCRIBIR UN CARÁCTER EN LA SALIDA ESTÁNDAR ........................... FUNCIONES getch y getche .............................................................................. LEER UNA CADENA DE CARACTERES ...................................................... VALIDAR UN DATO DE ENTRADA .............................................................. REUTILIZAR CÓDIGO ..................................................................................... LIMPIAR LA PANTALLA ................................................................................ EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

114  115  117  118  119  120  121  124  126  128  128  133

CAPÍTULO 5. SENTENCIAS DE CONTROL ................................................... 139  SENTENCIA if ................................................................................................... ANIDAMIENTO DE SENTENCIAS if ............................................................. ESTRUCTURA else if ........................................................................................ SENTENCIA switch ........................................................................................... SENTENCIA while ............................................................................................. Bucles anidados.............................................................................................. SENTENCIA do ... while .................................................................................... SENTENCIA for ................................................................................................. SENTENCIA break ............................................................................................. SENTENCIA continue ........................................................................................ SENTENCIA goto .............................................................................................. EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

139  141  144  147  151  154  157  160  163  164  164  165  180

CAPÍTULO 6. TIPOS ESTRUCTURADOS DE DATOS .................................. 187  INTRODUCCIÓN A LAS MATRICES ............................................................. MATRICES NUMÉRICAS UNIDIMENSIONALES ........................................ Definir una matriz .......................................................................................... Acceder a los elementos de una matriz .......................................................... Trabajar con matrices unidimensionales ........................................................ Iniciar una matriz ........................................................................................... Matrices asociativas ....................................................................................... CADENAS DE CARACTERES ......................................................................... Leer y escribir una cadena de caracteres ........................................................ Funciones gets y fgets ............................................................................... Función puts ..............................................................................................

188  189  189  190  191  195  196  200  201  201  203 

CONTENIDO

Trabajar con cadenas de caracteres ................................................................ Funciones de la biblioteca de C ..................................................................... TIPO Y TAMAÑO DE UNA MATRIZ ............................................................. MATRICES MULTIDIMENSIONALES ........................................................... Matrices numéricas multidimensionales ........................................................ Matrices de cadenas de caracteres .................................................................. COPIAR MATRICES ......................................................................................... TRABAJAR CON BLOQUES DE BYTES ....................................................... ESTRUCTURAS ................................................................................................ Crear una estructura ....................................................................................... Definir variables de un tipo de estructura ...................................................... Acceso a los miembros de una estructura ...................................................... Miembros que son estructuras ........................................................................ Operaciones con estructuras ........................................................................... Matrices de estructuras ................................................................................... UNIONES ........................................................................................................... Estructuras variables ...................................................................................... CAMPOS DE BITS ............................................................................................ EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

XI

206  207  208  209  209  214  218  220  221  221  222  224  225  226  231  234  237  242  246  259

CAPÍTULO 7. PUNTEROS .................................................................................. 267  CREACIÓN DE PUNTEROS ............................................................................ Operadores ..................................................................................................... Importancia del tipo del objeto al que se apunta ............................................ OPERACIONES CON PUNTEROS .................................................................. Operación de asignación ................................................................................ Operaciones aritméticas ................................................................................. Comparación de punteros............................................................................... Punteros genéricos ......................................................................................... Puntero nulo ................................................................................................... Punteros constantes ........................................................................................ PUNTEROS Y MATRICES ............................................................................... Punteros a cadenas de caracteres.................................................................... MATRICES DE PUNTEROS ............................................................................. Punteros a punteros ........................................................................................ Matriz de punteros a cadenas de caracteres ................................................... Ordenar matrices de cadenas de caracteres .................................................... ASIGNACIÓN DINÁMICA DE MEMORIA .................................................... Funciones para administrar dinámicamente la memoria .................................. malloc........................................................................................................

267  269  270  271  271  272  274  274  276  277  277  282  286  288  291  295  299  299  299 

XII

C/C++: CURSO DE PROGRAMACIÓN

free ............................................................................................................ Reasignar un bloque de memoria ................................................................... MATRICES DINÁMICAS ................................................................................. Matrices dinámicas numéricas ....................................................................... Matrices dinámicas de una dimensión ...................................................... Matrices dinámicas de dos dimensiones ................................................... Matrices dinámicas de cadenas de caracteres................................................. PUNTEROS A ESTRUCTURAS ....................................................................... PUNTEROS COMO PARÁMETROS EN FUNCIONES .................................. DECLARACIONES COMPLEJAS .................................................................... EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

301  302  304  305  305  309  313  317  320  326  327  337

CAPÍTULO 8. MÁS SOBRE FUNCIONES ........................................................ 347  PASAR UNA MATRIZ COMO ARGUMENTO A UNA FUNCIÓN ..................... Matrices estáticas ........................................................................................... Matrices dinámicas......................................................................................... PASAR UN PUNTERO COMO ARGUMENTO A UNA FUNCIÓN ...................... PASAR UNA ESTRUCTURA A UNA FUNCIÓN ........................................... DATOS RETORNADOS POR UNA FUNCIÓN ............................................... Retornar una copia de los datos ..................................................................... Retornar un puntero al bloque de datos.......................................................... Retornar la dirección de una variable declarada static ................................... ARGUMENTOS EN LA LÍNEA DE ÓRDENES .............................................. REDIRECCIÓN DE LA ENTRADA Y DE LA SALIDA ................................. FUNCIONES RECURSIVAS............................................................................. PUNTEROS A FUNCIONES ............................................................................. EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

347  348  350  352  354  358  359  360  361  363  365  367  369  376  392

CAPÍTULO 9. TRABAJAR CON FICHEROS................................................... 401  VISIÓN GENERAL DE LOS FLUJOS DE E/S................................................. VISIÓN GENERAL DE UN FICHERO............................................................. ABRIR UN FICHERO ........................................................................................ fopen .............................................................................................................. freopen ........................................................................................................... CERRAR UN FICHERO .................................................................................... fclose .............................................................................................................. MANIPULACIÓN DE ERRORES ..................................................................... ferror ..............................................................................................................

403  405  409  409  411  412  412  413  413 

CONTENIDO

XIII

clearerr ........................................................................................................... feof ................................................................................................................. perror .............................................................................................................. POSICIÓN DEL PUNTERO DE L/E ................................................................. ftell ................................................................................................................. fseek ............................................................................................................... rewind ............................................................................................................ E/S CARÁCTER A CARÁCTER....................................................................... fputc ............................................................................................................... fgetc................................................................................................................ E/S DE CADENAS DE CARACTERES ............................................................ fputs................................................................................................................ fgets ................................................................................................................ ENTRADA/SALIDA CON FORMATO ............................................................ fprintf ............................................................................................................. fscanf .............................................................................................................. E/S UTILIZANDO REGISTROS ....................................................................... fwrite .............................................................................................................. fread ............................................................................................................... ABRIENDO FICHEROS PARA ACCESO SECUENCIAL .............................. Un ejemplo de acceso secuencial ................................................................... ESCRIBIR DATOS EN UNA IMPRESORA ..................................................... Escribir en una impresora USB ...................................................................... CONTROL DEL BUFFER ASOCIADO CON UN FLUJO............................... setvbuf ............................................................................................................ fflush .............................................................................................................. FICHEROS TEMPORALES .............................................................................. tmpfile ............................................................................................................ ABRIENDO FICHEROS PARA ACCESO ALEATORIO ................................ EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

413  414  415  417  417  417  418  418  419  420  422  422  423  425  425  426  427  428  428  429  430  434  436  437  438  441  441  441  441  445  464

CAPÍTULO 10. EL PREPROCESADOR DE C ................................................. 471  DIRECTRIZ #define ........................................................................................... Macros predefinidas ....................................................................................... El operador # .................................................................................................. El operador ## ................................................................................................ DIRECTRIZ #undef ............................................................................................ DIRECTRIZ #include ......................................................................................... COMPILACIÓN CONDICIONAL .................................................................... Operador defined............................................................................................

472  475  476  476  476  477  477  479 

XIV

C/C++: CURSO DE PROGRAMACIÓN

CONSTANTE DEFINIDA EN LA ORDEN DE COMPILACIÓN ................... DIRECTRICES #ifdef e #ifndef ......................................................................... DIRECTRIZ #line ............................................................................................... DIRECTRIZ #error ............................................................................................. UTILIZACIÓN DE FICHEROS DE CABECERA ............................................ EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

479  482  482  483  483  486  488

CAPÍTULO 11. ESTRUCTURAS DINÁMICAS ................................................ 495  LISTAS LINEALES ........................................................................................... Listas lineales simplemente enlazadas ........................................................... Operaciones básicas ....................................................................................... Inserción de un elemento al comienzo de la lista ...................................... Buscar en una lista un elemento con un valor x ........................................ Inserción de un elemento en general ......................................................... Borrar un elemento de la lista ................................................................... Recorrer una lista ...................................................................................... Borrar todos los elementos de una lista .................................................... UN EJEMPLO CON LISTAS LINEALES......................................................... Interfaz genérica para listas lineales............................................................... LISTAS CIRCULARES ..................................................................................... Interfaz para manipular una lcse .................................................................... PILAS.................................................................................................................. COLAS ................................................................................................................ Ejemplo .......................................................................................................... LISTA DOBLEMENTE ENLAZADA ............................................................... Lista circular doblemente enlazada ................................................................ Interfaz para manipular una lcde ............................................................... Ejemplo ..................................................................................................... ÁRBOLES........................................................................................................... Árboles binarios ............................................................................................. Formas de recorrer un árbol binario ............................................................... ÁRBOLES BINARIOS DE BÚSQUEDA .......................................................... Interfaz para manipular un árbol binario de búsqueda ................................... Buscar un nodo en el árbol ............................................................................. Insertar un nodo en el árbol............................................................................ Borrar un nodo del árbol ................................................................................ Utilización de la interfaz abb ......................................................................... ÁRBOLES BINARIOS PERFECTAMENTE EQUILIBRADOS ...................... Interfaz para manipular un árbol perfectamente equilibrado ......................... Utilización de la interfaz abe..........................................................................

496  496  500  501  502  502  503  504  504  505  509  520  522  527  528  530  533  533  534  540  542  543  544  546  547  550  550  552  554  558  559  564 

CONTENIDO

XV

EJERCICIOS RESUELTOS ............................................................................... 567  EJERCICIOS PROPUESTOS............................................................................. 582 CAPÍTULO 12. ALGORITMOS DE USO COMÚN .......................................... 591  RECURSIVIDAD ............................................................................................... ORDENACIÓN DE DATOS .............................................................................. Método de la burbuja ..................................................................................... Método de inserción ....................................................................................... Método quicksort ........................................................................................... Comparación de los métodos expuestos......................................................... BÚSQUEDA DE DATOS .................................................................................. Búsqueda secuencial ...................................................................................... Búsqueda binaria ............................................................................................ Búsqueda de cadenas ..................................................................................... ORDENACIÓN DE FICHEROS EN DISCO..................................................... Ordenación de ficheros. Acceso secuencial ................................................... Ordenación de ficheros. Acceso aleatorio ...................................................... ALGORITMOS HASH ....................................................................................... Matrices hash ................................................................................................. Método hash abierto ....................................................................................... Método hash con desbordamiento .................................................................. Eliminación de elementos .............................................................................. Interfaz hash abierto ....................................................................................... Un ejemplo de una matriz hash ...................................................................... EJERCICIOS RESUELTOS ............................................................................... EJERCICIOS PROPUESTOS.............................................................................

591  597  598  600  602  605  605  606  606  607  610  611  616  619  619  621  622  623  623  627  629  633

A. ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C................................ 639  FUNCIONES DE CADENAS Y DE CARACTERES ....................................... strcat ............................................................................................................... strcpy .............................................................................................................. strchr .............................................................................................................. strrchr ............................................................................................................. strcmp ............................................................................................................. strcspn ............................................................................................................ strlen ............................................................................................................... strncat ............................................................................................................. strncpy ............................................................................................................ strncmp ........................................................................................................... strspn ..............................................................................................................

639  639  640  640  640  642  643  644  644  645  645  645 

XVI

C/C++: CURSO DE PROGRAMACIÓN

strstr................................................................................................................ strtok .............................................................................................................. strlwr .............................................................................................................. strupr .............................................................................................................. Funciones para conversión de datos ............................................................... atof ................................................................................................................. atoi.................................................................................................................. atol.................................................................................................................. sprintf ............................................................................................................. Funciones de caracteres.................................................................................. toascii ............................................................................................................. tolower ........................................................................................................... toupper ........................................................................................................... FUNCIONES MATEMÁTICAS ........................................................................ acos ................................................................................................................ asin ................................................................................................................. atan ................................................................................................................. atan2 ............................................................................................................... cos .................................................................................................................. sin ................................................................................................................... tan ................................................................................................................... cosh ................................................................................................................ sinh ................................................................................................................. tanh ................................................................................................................. exp .................................................................................................................. log .................................................................................................................. log10 .............................................................................................................. ceil .................................................................................................................. fabs ................................................................................................................. floor ................................................................................................................ pow ................................................................................................................. sqrt.................................................................................................................. NÚMEROS SEUDOALEATORIOS .................................................................. rand ................................................................................................................ srand ............................................................................................................... FUNCIONES DE FECHA Y HORA .................................................................. clock ............................................................................................................... time................................................................................................................. ctime ............................................................................................................... localtime ......................................................................................................... FUNCIONES PARA MANIPULAR BLOQUES DE MEMORIA .................... memset ........................................................................................................... memcpy ..........................................................................................................

645  646  647  647  647  648  648  648  649  650  650  650  650  651  652  652  652  652  653  653  653  653  653  654  654  654  654  654  655  655  655  655  656  656  656  656  656  657  657  658  659  659  659 

CONTENIDO

XVII

memcmp ......................................................................................................... 660 B. ENTORNOS DE DESARROLLO.................................................................... 661  MICROSOFT VISUAL STUDIO ....................................................................... Añadir ficheros existentes a un proyecto ....................................................... Depurar la aplicación ..................................................................................... INTERFAZ DE LÍNEA DE ÓRDENES EN WINDOWS.................................. CREAR UNA BIBLIOTECA DE FUNCIONES................................................ NETBEANS ........................................................................................................ Depurar una aplicación con NetBeans ........................................................... INTERFAZ DE LÍNEA DE ÓRDENES EN UNIX/LINUX .............................. El depurador gdb de Unix/Linux ................................................................... CODE::BLOCKS ................................................................................................

661  666  666  668  669  672  676  678  679  680

C. CÓDIGOS DE CARACTERES ....................................................................... 685  UTILIZACIÓN DE CARACTERES ANSI CON WINDOWS .......................... JUEGO DE CARACTERES ANSI ..................................................................... UTILIZACIÓN DE CARACTERES ASCII ....................................................... JUEGO DE CARACTERES ASCII.................................................................... JUEGO DE CARACTERES UNICODE ............................................................

685  686  687  688  689 

ÍNDICE ................................................................................................................... 691

PRÓLOGO Aprender C nunca ha sido fácil. Por eso el autor, apoyándose en su experiencia docente, ha puesto todo su empeño en escribir un libro fácil de leer, progresivo en el aprendizaje y con muchos ejemplos que aclaren lo expuesto.

Para quién es este libro Este libro está pensado para aquellas personas que quieran aprender a escribir programas, utilizando el lenguaje C, siguiendo una metodología fundamentada en técnicas de desarrollo que conducen a realizar una programación estructurada. Para ello, ¿qué debe hacer el lector? Pues simplemente leer ordenadamente los capítulos del libro, resolviendo cada uno de los ejemplos que en ellos se detallan. Es evidente que el lenguaje C ha ido evolucionando a lo largo de su historia. Producto de esta evolución fue el lenguaje C++ y, finalmente, el diseño de una amplia biblioteca de funciones para el desarrollo de aplicaciones con interfaz gráfica (programación visual). De ahí que este libro sea el primero de una colección de tres libros orientados al desarrollo de aplicaciones con C/C++. Entre los tres, y en el orden comentado a continuación, cubren los siguientes aspectos: programación estructurada con C y programación orientada a objetos con C++. Este es el primero, C/C++: Curso de programación. Abarca todo lo relativo a la programación estructurada con C. También incluye diversos algoritmos de uso común así como desarrollos con estructuras dinámicas de datos. ¿Por qué el título C/C++? Porque C++ fue desarrollado a partir del lenguaje de programación C y con pocas excepciones incluye a C. Esta parte de C incluida en C++ es conocida como C–, y podría compilarse bajo C++ sin problemas. No obstante, cuando C++ se utiliza para lo que fue pensado, para realizar una programación orientada a objetos, los conocimientos nuevos que hay que adquirir son cuantiosos.

XX

C/C++: CURSO DE PROGRAMACIÓN

El segundo, Programación orientada a objetos con C++, estudia, como su nombre indica, el desarrollo de aplicaciones orientadas a objetos. Esta tecnología es imprescindible conocerla si su propósito es llegar a desarrollar aplicaciones vistosas como lo son las aplicaciones a base de ventanas, más bien conocidas como aplicaciones para Windows. Y el tercero, Enciclopedia de C++, incluye a los dos anteriores, pero con un nuevo enfoque, ya que a lo largo de todos los capítulos del libro solo se utiliza la biblioteca de C++. Por el contrario, si lo que usted persigue es profundizar en aplicaciones C incluyendo llamadas al sistema UNIX, entonces le recomiendo el libro de Francisco Manuel Márquez titulado UNIX, Programación Avanzada, publicado también por la editorial RA-MA.

Cómo está organizado el libro El libro se ha dividido en doce capítulos que van presentando el lenguaje poco a poco, empezando por lo más sencillo, viendo cada tema a su tiempo, hasta llegar al final donde se habrá visto todo lo referente a la programación con el lenguaje C, sin apenas encontrar dificultades. Se completa el estudio de C con un capítulo referente a estructuras dinámicas y otro de algoritmos de uso común. El lector podrá comprobar al final de esta obra que el nivel de conocimientos que ha adquirido es elevado. El primer capítulo introduce al lector en el mundo de la programación C. El segundo capítulo presenta de una sola vez todos los elementos del lenguaje que el lector utilizará constantemente en el resto de los capítulos; por eso, debe simplemente leerse fijándose en los ejemplos y, por el momento, no preocuparse de más; posteriormente se podrá retornar a él todas las veces que sean necesarias. El tercer capítulo presenta la estructura general de un programa C con un ejemplo; el lector debe también leerlo con un objetivo: asimilar cómo es la estructura de un programa C y cuál es su secuencia de ejecución, sin tratar de aprender en este instante todos los conceptos que ahí se exponen. Leídos estos tres capítulos, el lector tendrá claro el escenario donde se va a mover. A partir del capítulo 4 empezará a aprender a programar; por lo tanto, el lector debe tener un poco de paciencia hasta que se inicie en este capítulo. Este libro posee varias características dignas de resaltar. Es breve en teoría y abundante en ejemplos (más de 250 ejercicios resueltos), lo que le hará aún más fácil el aprendizaje.

PRÓLOGO XXI

Estos capítulos y apéndices que componen la materia total de C/C++: Curso de programación se resumen así: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. A. B. C.

Fases en el desarrollo de un programa. Elementos del lenguaje C. Estructura de un programa. Entrada y salida estándar. Sentencias de control. Tipos estructurados de datos. Punteros. Más sobre funciones. Trabajar con ficheros. El preprocesador de C. Estructuras dinámicas. Algoritmos de uso común. Algunas funciones de la biblioteca de C. Entornos de desarrollo. Códigos de caracteres.

Todo esto se ha documentado con abundantes ejemplos, ejercicios resueltos y ejercicios propuestos, de los cuales también se da su solución en un ZIP, muchos de ellos válidos como parte integrante en el desarrollo de aplicaciones.

Agradecimientos He recibido ideas y sugerencias de algunas personas durante la preparación de este libro, entre las que se encuentran, cómo no, mis alumnos, que con su interés por aprender me hacen reflexionar sobre objetivos que a primera vista parecen inalcanzables, pero que una vez logrados sirven para que todos aprendamos; a todos ellos les estoy francamente agradecido. En especial, quiero expresar mi agradecimiento a Martín Knoblauch Revuelta, por sus buenas recomendaciones y aportaciones para esta nueva edición, y a Inmaculada Rodríguez Santiago, por sus consejos en las versiones anteriores, así como a Alfredo Gallego Gandarillas y a Francisco Manuel Márquez García, por su participación en la corrección de las versiones anteriores, y a David Jurado González, porque aportó una solución para la mayoría de los ejercicios propuestos. Francisco Javier Ceballos Sierra http://www.fjceballos.es/

APÉNDICE A  F.J.Ceballos/RAMA

ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C Además de las funciones expuestas a lo largo de esta obra, hay otras muchas. Este apéndice muestra algunas de las funciones más útiles de la biblioteca de C que aún no han sido expuestas. Todas estas funciones se pueden agrupar en las siguientes categorías:      

Funciones de E/S. Funciones de cadenas y de caracteres. Funciones matemáticas. Funciones de fecha y hora. Funciones de asignación dinámica. Otras funciones.

FUNCIONES DE CADENAS Y DE CARACTERES La biblioteca de C proporciona un amplio número de funciones que permiten realizar diversas operaciones con cadenas de caracteres, como copiar una cadena en otra, añadir una cadena a otra, etc. A continuación se describen las más utilizadas.

strcat #include char *strcat( char *cadena1, const char *cadena2 ); Compatibilidad: ANSI, UNIX y Windows

640

C/C++: CURSO DE PROGRAMACIÓN

La función strcat añade la cadena2 a la cadena1, finaliza la cadena resultante con el carácter nulo y devuelve un puntero a cadena1.

strcpy #include char *strcpy( char *cadena1, const char *cadena2 ); Compatibilidad: ANSI, UNIX y Windows

La función strcpy copia la cadena2, incluyendo el carácter de terminación nulo, en la cadena1 y devuelve un puntero a cadena1. /* Este programa utiliza strcpy y strcat * strcpy.c */ #include #include main(void) { char cadena[81]; strcpy( cadena, "Hola, " ); strcat( cadena, "strcpy " ); strcat( cadena, "y " ); strcat( cadena, "strcat te saludan!" ); printf( "cadena = %s\n", cadena ); } Ejecución del programa: cadena = Hola, strcpy y strcat te saludan!

strchr #include char *strchr( const char *cadena, int c ); Compatibilidad: ANSI, UNIX y Windows

La función strchr devuelve un puntero a la primera ocurrencia de c en cadena o un valor NULL si el carácter no es encontrado. El carácter c puede ser el carácter nulo (‘\0’).

strrchr #include char *strrchr( const char *cadena, int c ); Compatibilidad: ANSI, UNIX y Windows

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

641

La función strrchr devuelve un puntero a la última ocurrencia de c en cadena o un valor NULL si el carácter no se encuentra. El carácter c puede ser un carácter nulo (‘\0’). /* Este programa ilustra cómo buscar un carácter con strchr * (hacia delante) o con strrchr (hacia atrás). /* strchr.c */ #include #include main( void ) { int car = 'i'; char cadena[] = "La biblioteca de C proporciona muchas funciones"; char dec1[] = " 1 2 3 4 5"; char uni2[] = "12345678901234567890123456789012345678901234567890"; char *pdest; int resu; printf( "Cadena en la que se busca: \n%s\n", cadena ); printf( "%s\n%s\n\n", dec1, uni2 ); printf( "Buscar el carácter: %c\n\n", car ); // Buscar de adelante hacia atrás pdest = strchr( cadena, car ); resu = pdest - cadena; if ( pdest != NULL ) printf( "La %c primera está en la posición %d\n", car, resu ); else printf( "%c no se encuentra en la cadena\n" ); // Buscar desde atrás hacia delante pdest = strrchr( cadena, car ); resu = pdest - cadena; if ( pdest != NULL ) printf( "La última %c está en la posición %d\n\n", car, resu ); else printf( "%c no se encuentra en la cadena\n" ); } Ejecución del programa: Cadena en la que se busca: La biblioteca de C proporciona muchas funciones 1 2 3 4 01234567890123456789012345678901234567890123456789 Buscar el carácter: i La i primera está en la posición 4 La última i está en la posición 42

642

C/C++: CURSO DE PROGRAMACIÓN

Sabemos que los elementos de una matriz de caracteres, igual que los de cualquier otra matriz, ocupan posiciones sucesivas en memoria. También sabemos que el nombre de una matriz es la dirección de comienzo de la matriz y coincide con la dirección del primer carácter. Así mismo, observe que el valor retornado por strchr y strrchr está definido como un puntero a un char; esto es, una dirección que hace referencia al lugar donde está almacenado el carácter que se busca. cadena

pdest L

a

b

i

b

...

u

n

c

i

o

n

e

s

\0

Por lo tanto, una sentencia como: resu = pdest - cadena;

da como resultado la posición 0, 1, 2,... del carácter buscado dentro de la cadena, que es lo que hace el programa planteado.

strcmp #include int strcmp( const char *cadena1, const char *cadena2 ); Compatibilidad: ANSI, UNIX y Windows

La función strcmp compara la cadena1 con la cadena2 lexicográficamente y devuelve un valor: 0 si la cadena1 es mayor que la cadena2. En otras palabras, la función strcmp nos permite saber si una cadena está en orden alfabético antes (es menor) o después (es mayor) que otra y el proceso que sigue es el mismo que nosotros ejercitamos cuando lo hacemos mentalmente: comparar las cadenas carácter a carácter. La función strcmp diferencia las letras mayúsculas de las minúsculas. Las mayúsculas están antes por orden alfabético. Esto es así porque en la tabla ASCII las mayúsculas tienen asociado un valor entero menor que las minúsculas. /* strcmp.c */ #include #include

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

643

main(void) { char cadena1[] = "La Comunidad de Cantabria es muy bonita"; char cadena2[] = "La Comunidad de CANTABRIA es muy bonita"; char temp[20]; int resu; // Se diferencian mayúsculas de minúsculas printf( "Comparar las cadenas:\n\n%s\n%s\n\n", cadena1, cadena2 ); resu = strcmp( cadena1, cadena2 ); if ( resu > 0 ) strcpy( temp, "mayor que" ); else if ( resu < 0 ) strcpy( temp, "menor que" ); else strcpy( temp, "igual a" ); printf( "strcmp: cadena 1 es %s cadena 2\n", temp ); } Ejecución del programa: Comparar las cadenas: La Comunidad de Cantabria es muy bonita La Comunidad de CANTABRIA es muy bonita strcmp: cadena 1 es mayor que cadena 2

La solución de este problema es que la cadena1 es mayor que la cadena2 porque alfabéticamente Cantabria está después de CANTABRIA.

strcspn #include size_t strcspn( const char *cadena1, const char *cadena2 ); Compatibilidad: ANSI, UNIX y Windows

La función strcspn da como resultado la posición (subíndice) del primer carácter de cadena1, que pertenece al conjunto de caracteres contenidos en cadena2. Este valor corresponde a la longitud de la subcadena de cadena1 formada por caracteres no pertenecientes a cadena2. Si ningún carácter de cadena1 pertenece a cadena2, el resultado es la posición del carácter de terminación (\0) de cadena1; esto es, la longitud de cadena1. /* strcspn.c */ #include #include main(void)

644

C/C++: CURSO DE PROGRAMACIÓN

{ char cadena[] = "xyzabc"; int pos; pos = strcspn( cadena, "abc" ); printf( "Primer a, b o c en %s es el carácter %d\n", cadena, pos ); } Ejecución del programa: Primer a, b o c en xyzabc es el carácter 3

strlen #include size_t strlen( char *cadena ); Compatibilidad: ANSI, UNIX y Windows

La función strlen devuelve la longitud en bytes de cadena, no incluyendo el carácter de terminación nulo. El tipo size_t es sinónimo de unsigned int. /* strlen.c */ #include #include main(void) { char cadena[80] = "Hola"; printf("El tamaño de cadena es %d\n", strlen(cadena)); } Ejecución del programa: El tamaño de cadena es 4

strncat #include char *strncat( char *cadena1, const char *cadena2, size_t n ); Compatibilidad: ANSI, UNIX y Windows

La función strncat añade los primeros n caracteres de cadena2 a la cadena1, termina la cadena resultante con el carácter nulo y devuelve un puntero a cadena1. Si n es mayor que la longitud de cadena2, se utiliza como valor de n la longitud de cadena2.

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

645

strncpy #include char *strncpy( char *cadena1, const char *cadena2, size_t n ); Compatibilidad: ANSI, UNIX y Windows

La función strncpy copia n caracteres de la cadena2 en la cadena1 (sobrescribiendo los caracteres de cadena1) y devuelve un puntero a cadena1. Si n es menor que la longitud de cadena2, no se añade automáticamente un carácter nulo a la cadena resultante. Si n es mayor que la longitud de cadena2, la cadena1 es rellenada con caracteres nulos (‘\0’) hasta la longitud n.

strncmp #include int strncmp( const char *cadena1, const char *cadena2, size_t n ); Compatibilidad: ANSI, UNIX y Windows

La función strncmp compara lexicográficamente los primeros n caracteres de cadena1 y de cadena2, distinguiendo mayúsculas y minúsculas, y devuelve un valor: 0 si la cadena1 es mayor que la cadena2. Si n es mayor que la longitud de la cadena1, se toma como valor la longitud de la cadena1.

strspn #include size_t strspn( const char *cadena1, const char *cadena2 ); Compatibilidad: ANSI, UNIX y Windows

La función strspn da como resultado la posición (subíndice) del primer carácter de cadena1, que no pertenece al conjunto de caracteres contenidos en cadena2. Esto es, el resultado es la longitud de la subcadena inicial de cadena1, formada por caracteres pertenecientes a cadena2.

strstr #include char *strstr( const char *cadena1, const char *cadena2 );

646

C/C++: CURSO DE PROGRAMACIÓN

Compatibilidad: ANSI, UNIX y Windows

La función strstr devuelve un puntero a la primera ocurrencia de cadena2 en cadena1 o un valor NULL si la cadena2 no se encuentra en la cadena1.

strtok #include char *strtok( char *cadena1, const char *cadena2 ); Compatibilidad: ANSI, UNIX y Windows

La función strtok permite obtener de la cadena1 los elementos en los que se divide según los delimitadores especificados en cadena2. Para obtener el primer elemento, strtok debe tener cadena1 como primer argumento y para obtener los siguientes elementos, debe tener NULL. Cada llamada a strtok devuelve un puntero al siguiente elemento o NULL si no hay más elementos. Si un elemento finaliza con un delimitador, este es sustituido con un \0 y se guarda un puntero al siguiente carácter para la siguiente llamada a strtok. Puede ponerse más de un delimitador entre elemento y elemento, y también puede variarse el conjunto de caracteres que actúan como delimitadores, de una llamada a otra. Finalmente, tiene que saber que esta función modifica su primer argumento, por lo tanto, debe existir un espacio de memoria sobre el que la función pueda escribir. Por ejemplo, para cadena1 serían válidas cualesquiera de las dos definiciones siguientes: char cadena1[] = "Una cadena de caracteres"; char *cadena1 = (char *)malloc(nBytes); strcpy(cadena1, "Una cadena de caracteres");

En cambio, no sería válida la siguiente definición porque cadena1 apunta a una zona de memoria sobre la que no se puede escribir (se trata de una constante). char *cadena1 = "Una cadena de caracteres";

El ejemplo siguiente divide la cadena de caracteres especificada por cadena en los elementos definidos por los delimitadores espacio en blanco y coma. /* strtok.c */ #include #include

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

647

main(void) { char cadena[] = "Esta cadena, está formada por varias palabras"; char *elemento; elemento = strtok(cadena," ,"); while (elemento != NULL) { printf("%s\n", elemento); elemento = strtok(NULL," ,"); } } Ejecución del programa: Esta cadena está formada por varias palabras

strlwr #include char *strlwr(char *cadena ); Compatibilidad: Windows

La función strlwr convierte las letras mayúsculas de cadena en minúsculas. El resultado es la propia cadena en minúsculas.

strupr #include char *strupr(char *cadena ); Compatibilidad: Windows

La función strupr convierte las letras minúsculas de cadena en mayúsculas. El resultado es la propia cadena en mayúsculas.

Funciones para conversión de datos Las funciones de la biblioteca de C que se muestran a continuación permiten convertir cadenas de caracteres a números y viceversa, suponiendo que la conversión sea posible.

648

C/C++: CURSO DE PROGRAMACIÓN

atof #include double atof( const char *cadena ); Compatibilidad: ANSI, UNIX y Windows

La función atof convierte una cadena de caracteres a un valor de tipo double.

atoi #include int atoi( const char *cadena ); Compatibilidad: ANSI, UNIX y Windows

La función atoi convierte una cadena de caracteres a un valor de tipo int.

atol #include long atol( const char *cadena ); Compatibilidad: ANSI, UNIX y Windows

La función atol convierte una cadena de caracteres a un valor de tipo long. Cuando las funciones atof, atoi y atol toman de la variable cadena un carácter que no es reconocido como parte de un número, interrumpen la conversión. /* Este programa muestra como los números almacenados como * cadenas de caracteres pueden ser convertidos a valores * numéricos utilizando las funciones atof, atoi y atol. * * atof.c */ #include #include main(void) { char *s = NULL; double x = 0; int i = 0; long l = 0; s = " -3208.15E-13"; // para ver cómo trabaja atof x = atof( s ); printf( "atof: cadena ASCII: %-17s float: %e\n", s, x ); s = "8.7195642337X120"; // para ver cómo trabaja atof x = atof( s ); printf( "atof: cadena ASCII: %-17s float: %e\n", s, x ); s = " -8995 libros"; // para ver cómo trabaja atoi i = atoi( s ); printf( "atoi: cadena ASCII: %-17s int : %d\n", s, i );

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

649

s = "89954 euros"; // para ver cómo trabaja atol l = atol( s ); printf( "atol: cadena ASCII: %-17s long : %ld\n", s, l ); } Ejecución del programa: atof: atof: atoi: atol:

cadena cadena cadena cadena

ASCII: -3208.15E-13 ASCII: 8.7195642337X120 ASCII: -8995 libros ASCII: 89954 euros

double: -3.208150e-010 double: 8.719564e+000 int : -8995 long : 89954

sprintf #include int sprintf( char *buffer, const char *formato [, argumento] ... ); Compatibilidad: ANSI, UNIX y Windows

La función sprintf convierte los valores de los argumentos especificados a una cadena de caracteres que almacena en buffer. La cadena de caracteres finaliza con el carácter nulo. Cada argumento es convertido y almacenado de acuerdo con el formato correspondiente que se haya especificado. La descripción de formato es la misma que la que se especificó para printf. La función sprintf devuelve como resultado un entero correspondiente al número de caracteres almacenados en buffer sin contar el carácter nulo de terminación. Por ejemplo: /* sprintf.c. Este programa utiliza sprintf para almacenar * en buffer la cadena de caracteres formada por: * * Cadena: ordenador * Carácter: / * Entero: 40 * Real: 1.414214 */ #include main(void) { char buffer[200], s[] = "ordenador", c = '/'; int i = 40, j; float f = 1.414214F; j = sprintf( buffer, "\tCadena: %s\n", s ); j += sprintf( buffer + j, "\tCarácter: %c\n", c ); j += sprintf( buffer + j, "\tEntero: %d\n", i ); j += sprintf( buffer + j, "\tReal: %f\n", f ); printf( "Salida:\n%s\nNúmero de caracteres = %d\n", buffer, j ); }

650

C/C++: CURSO DE PROGRAMACIÓN

Ejecución del programa: Salida: Cadena: Carácter: Entero: Real:

ordenador / 40 1.414214

Número de caracteres = 72

Funciones de caracteres Las funciones de la biblioteca de C que se exponen a continuación actúan sobre un entero para dar como resultado un carácter.

toascii #include int toascii( int c ); Compatibilidad: UNIX y Windows

La función toascii pone a 0 todos los bits de c, excepto los siete bits de menor orden. Dicho de otra forma, convierte c a un carácter ASCII.

tolower #include int tolower( int c ); Compatibilidad: ANSI, UNIX y Windows

La función tolower convierte c a una letra minúscula, si procede.

toupper #include int toupper( int c ); Compatibilidad: ANSI, UNIX y Windows

La función toupper convierte c a una letra mayúscula, si procede. /* tolower.c */ #include #include main()

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

651

{ char car; // ... do { printf("¿Desea continuar? s/n "); car = getchar(); fflush(stdin); } while (tolower(car) != 'n' && tolower(car) != 's'); // ... }

Este ejemplo admite una respuesta sí o no (s|S|n|N) en minúsculas o en mayúsculas, pero la comparación se hace en minúsculas.

FUNCIONES MATEMÁTICAS Las declaraciones para las funciones matemáticas que a continuación se describen están en el fichero de cabecera math.h. Quiere esto decir que, cuando se utilice una función matemática en un programa, debe especificarse la directriz: #include

Los argumentos para estas funciones son de tipo double y el resultado devuelto es también de tipo double. Por ello, en muchos casos utilizaremos una conversión explícita de tipo (conversión cast) para convertir explícitamente los argumentos al tipo deseado. Por ejemplo, suponiendo que valor es un int: a = acos((double)valor);

calcula el arco coseno de valor. Se puede observar que el argumento pasado a la función acos es convertido explícitamente a tipo double. Las funciones matemáticas las podemos clasificar en las siguientes categorías:    

Funciones trigonométricas. Funciones hiperbólicas. Funciones exponencial y logarítmica. Otras varias.

652

C/C++: CURSO DE PROGRAMACIÓN

acos La función acos da como resultado el arco, en el rango 0 a , cuyo coseno es x. El valor de x debe estar entre 1 y 1; de lo contrario se obtiene un error (argumento fuera del dominio de la función). #include double acos( double x ); Compatibilidad: ANSI, UNIX y Windows

asin La función asin da como resultado el arco, en el rango /2 a /2, cuyo seno es x. El valor de x debe estar entre 1 y 1; si no se obtiene un error (argumento fuera del dominio de la función). #include double asin( double x ); Compatibilidad: ANSI, UNIX y Windows

atan La función atan da como resultado el arco, en el rango /2 a /2, cuya tangente es x. #include double atan( double x ); Compatibilidad: ANSI, UNIX y Windows

atan2 La función atan2 da como resultado el arco, en el rango a , cuya tangente es y/x. Si ambos argumentos son 0, se obtiene un error (argumento fuera del dominio de la función). #include double atan2( double y, double x); Compatibilidad: ANSI, UNIX y Windows /* acos.c */ #include #include main()

APÉNDICE A: ALGUNAS FUNCIONES DE LA BIBLIOTECA DE C

{ double valor = 0; do { printf("%lf %lf\n", acos(valor), atan2(valor, 1.0)); valor += 0.1; } while (valor tm_min); }

La función localtime utiliza una variable de tipo static struct tm para realizar la conversión y lo que devuelve es la dirección de esa variable.

FUNCIONES PARA MANIPULAR BLOQUES DE MEMORIA La biblioteca de C/C++ proporciona un conjunto de funciones para manipular bloques de bytes consecutivos en memoria. Comentamos a continuación las más utilizadas.

memset La función memset permite iniciar un bloque de memoria. #include void *memset( void *destino, int b, size_t nbytes ); Compatibilidad: ANSI, UNIX y Windows

El argumento destino es la dirección del bloque de memoria que se desea iniciar, b es el valor empleado para iniciar cada byte del bloque y nbytes es el número de bytes del bloque que se iniciarán. Por ejemplo, el siguiente código inicia a 0 la matriz a: double a[10][10]; // ... memset(a, 0, sizeof(a));

memcpy La función memcpy copia un bloque de memoria en otro. #include void *memcpy( void *destino, const void *origen, size_t nbytes );

660

C/C++: CURSO DE PROGRAMACIÓN

Compatibilidad: ANSI, UNIX y Windows

El argumento destino es la dirección del bloque de memoria destino de los datos, origen es la dirección del bloque de memoria origen de los datos y nbytes es el número de bytes que se copiarán desde el origen al destino. Por ejemplo, el siguiente código copia la matriz a en b: double a[10][10], b[10][10]; // ... memcpy(b, a, sizeof(a));

memcmp La función memcmp compara byte a byte dos bloques de memoria. #include int memcmp( void *bm1, const void *bm2, size_t nbytes ); Compatibilidad: ANSI, UNIX y Windows

Los argumentos bm1 y bm2 son las direcciones de los bloques de memoria a comparar y nbytes es el número de bytes que se compararán. El resultado devuelto por la función es el mismo que se expuso para strcmp. Por ejemplo, el siguiente código compara la matriz a con la b: double a[10][10], b[10][10]; // ... if ( memcmp(a, b, sizeof(a)) == 0 ) printf("Las matrices a y b contienen los mismos datos\n"); else printf("Las matrices a y b no contienen los mismos datos\n");

APÉNDICE B  F.J.Ceballos/RA-MA

ENTORNOS DE DESARROLLO Un entorno de desarrollo integrado (EDI, en inglés IDE: Integrated Development Environment) es una aplicación que agrupa varias herramientas de programación, básicamente, las necesarias para escribir, compilar y depurar un programa. El EDI puede utilizar un solo lenguaje de programación, o bien puede ser compatible con varios, tales como C/C++, C#, Visual Basic, Java, PHP, Python, etc. Dicho EDI presentará al usuario una interfaz gráfica que le abstraerá del manejo individual, a nivel de línea de órdenes, de cada una de esas herramientas de programación. Para realizar los ejemplos de este libro, el autor propone utilizar alguno de los entornos indicados a continuación: Microsoft Visual Studio Express para Windows, NetBeans para Windows/Linux/Mac OS X o Code::Blocks para Windows/Linux/Mac OS X. Estos EDI pueden descargarse de Internet y utilizarlos sin coste alguno.

MICROSOFT VISUAL STUDIO Este entorno de desarrollo lo puede descargar gratuitamente desde Internet (www.fjceballos.es > Utilidades) en su edición Express. En la figura siguiente se puede observar la interfaz gráfica de este entorno de desarrollo integrado: Microsoft Visual Studio Express. Dicho entorno muestra una barra de menús y otra de herramientas, un panel de edición (en el ejemplo muestra un programa C), el explorador de soluciones (en el ejemplo muestra un proyecto progC correspondiente al programa que estamos realizando), el panel de propiedades y el panel de resultados (en el ejemplo muestra los resultados de la compilación).

662

C/C++: CURSO DE PROGRAMACIÓN

Para editar y ejecutar el programa avance.c expuesto en el capítulo 1 utilizando este entorno de desarrollo, los pasos a seguir son los siguientes: 1. Partiendo de la página de inicio de Microsoft Visual Studio Express, hacemos clic en Nuevo proyecto de la página principal para crear un proyecto nuevo o bien ejecutamos la orden Archivo > Nuevo proyecto. Esta acción hará que se visualice una ventana análoga a la siguiente:

APÉNDICE B: ENTORNOS DE DESARROLLO

663

Esta ventana muestra en su panel izquierdo los tipos de proyectos que se pueden crear y a la derecha de este, las plantillas que se pueden utilizar; la elección de una o de otra dependerá del tipo de aplicación que deseemos construir. Para nuestro ejemplo, elegimos el tipo de proyecto Visual C++ Win32 y la plantilla Aplicación de consola Win32. Después especificamos el nombre del proyecto y su ubicación (no hace falta que marque Crear directorio para la solución); observe que el proyecto será creado en una carpeta con el mismo nombre. A continuación pulsamos el botón Aceptar. Esta acción visualizará la ventana mostrada en la figura siguiente, que permitirá establecer la configuración de la aplicación; por ejemplo, aplicación de consola, proyecto vacío:

2. Una vez configurada la aplicación, pulsamos el botón Finalizar. El resultado será un proyecto vacío al que podremos añadir ficheros. Por ejemplo, para añadir el fichero avance.c, hacemos clic con el botón derecho del ratón sobre el nombre del proyecto y seleccionamos la orden Agregar > Nuevo elemento del menú contextual.

664

C/C++: CURSO DE PROGRAMACIÓN

3. La acción ejecutada en el punto anterior muestra la ventana que se expone a continuación, la cual nos permitirá elegir la plantilla para el fichero. En nuestro caso, al no haber una plantilla para archivos C, hemos añadido la extensión .c a continuación del nombre del fichero en la caja Nombre.

APÉNDICE B: ENTORNOS DE DESARROLLO

665

4. El siguiente paso es escribir el código que se almacenará en este fichero, según muestra la figura siguiente:

En esta figura observamos una ventana principal que contiene otras ventanas o paneles. La que está en la parte izquierda superior está mostrando la página de edición del fichero avance.c que estamos editando. La que está en la parte derecha superior está mostrando el explorador de soluciones; este lista el nombre de la solución (una solución puede contener uno o más proyectos), el nombre del proyecto o proyectos y el nombre de los ficheros que componen el proyecto; en nuestro caso solo tenemos el fichero avance.c donde escribiremos el código de las acciones que tiene que llevar a cabo nuestra aplicación. Al lado de la pestaña de la ventana del explorador puede haber otras pestañas como, por ejemplo, la Vista de clases. Y la ventana que hay debajo de la página de edición puede mostrar varios paneles, por ejemplo, el de resultados de la compilación. 5. Una vez editado el programa, para compilarlo ejecutamos la orden Compilar... del menú Compilar y para ejecutarlo, seleccionamos la orden Iniciar sin depurar del menú Depurar o bien pulsamos las teclas Ctrl+F5.

666

C/C++: CURSO DE PROGRAMACIÓN

Añadir ficheros existentes a un proyecto Supongamos que disponemos de un fichero .c que deseamos añadir a un proyecto vacío o no. ¿Cómo podemos hacerlo? Una vez abierto el proyecto, basta con ejecutar la orden Proyecto > Agregar elemento existente y seleccionar el fichero que deseamos añadir.

Depurar la aplicación ¿Por qué se depura una aplicación? Porque los resultados que estamos obteniendo con la misma no son correctos y no sabemos por qué. El proceso de depuración consiste en ejecutar la aplicación paso a paso, indistintamente por sentencias o por funciones, con el fin de observar el flujo seguido durante su ejecución, así como los resultados intermedios que se van sucediendo, con la finalidad de detectar dónde está la anomalía que produce un resultado final erróneo. Hay dos configuraciones, como se puede observar en la figura siguiente, bajo las que se puede compilar una aplicación: Release y Debug:

La primera permite obtener un programa ejecutable optimizado en código y en velocidad, y la segunda, un programa ejecutable con código extra necesario para depurar la aplicación. Por lo tanto, para depurar una aplicación utilizando el depurador del entorno de desarrollo de Visual Studio, debe activar la configuración Win32 Debug antes de iniciar su compilación. Para ello, ejecute la orden

APÉNDICE B: ENTORNOS DE DESARROLLO

667

Administrador de configuración... del menú Compilar y seleccione dicha configuración. Una vez construida la aplicación bajo la configuración Win32 Debug podrá, si lo necesita, depurar la misma. Para ello, ejecute la orden Depurar > Paso a paso por instrucciones y utilice las órdenes del menú Depurar o los botones correspondientes de la barra de herramientas (para saber el significado de cada botón, ponga el puntero del ratón sobre cada uno de ellos).

De forma resumida, las órdenes de que dispone para depurar una aplicación son las siguientes: 

Iniciar o F5. Inicia la ejecución de la aplicación en modo depuración hasta encontrar un punto de parada o hasta el final si no hay puntos de parada.



Alternar puntos de interrupción o F9. Pone o quita un punto de parada en la línea sobre la que está el punto de inserción.



Detener depuración o Mayús+F5. Detiene el proceso de depuración.



Paso a paso por instrucciones o F11. Ejecuta la aplicación paso a paso. Si la línea a ejecutar coincide con una llamada a una función definida por el usuario, dicha función también se ejecutará paso a paso.



Paso a paso por procedimientos o F10. Ejecuta la aplicación paso a paso. Si la línea a ejecutar coincide con una llamada a una función definida por el usuario, dicha función no se ejecutará paso a paso, sino de una sola vez.



Paso a paso para salir o Mayús+F11. Cuando una función definida por el usuario ha sido invocada para ejecutarse paso a paso, utilizando esta orden se puede finalizar su ejecución en un solo paso.



Ejecutar hasta el cursor o Ctrl+F10. Ejecuta el código que hay entre la última línea ejecutada y la línea donde se encuentra el punto de inserción.



Inspección rápida o Ctrl+Alt+Q. Visualiza el valor de la variable que está bajo el punto de inserción o el valor de la expresión seleccionada (sombreada). El simple hecho de poner el punto de inserción sobre dicha variable ya visualiza su valor.

668

C/C++: CURSO DE PROGRAMACIÓN

Para ejecutar la aplicación en un solo paso, seleccione la orden Iniciar sin depurar (Ctrl+F5) del menú Depurar. Además de la barra de herramientas Depurar, dispone también de otras barras de herramientas que puede mostrar ejecutando la orden Barras de herramientas del menú Ver.

INTERFAZ DE LÍNEA DE ÓRDENES EN WINDOWS Los ficheros que componen una aplicación C pueden ser escritos utilizando cualquier editor de texto ASCII; por ejemplo, el Bloc de notas. Una vez editados y guardados todos los ficheros que componen la aplicación, el siguiente paso es compilarlos y enlazarlos para obtener el fichero ejecutable correspondiente a la misma. La orden para realizar estas operaciones es la siguiente: cl fichero01.c [fichero02 [fichero03] ...]

El nombre del fichero ejecutable resultante será el mismo que el nombre del primer fichero especificado, pero con extensión .exe. Previamente, para que el sistema operativo encuentre la utilidad cl, los ficheros de cabecera (directriz include) y las bibliotecas dinámicas y estáticas, cuando son invocados desde la línea de órdenes, hay que definir en el entorno de trabajo (en la consola sobre la que estemos trabajando) las siguientes variables: set path=%path%;ruta de los ficheros .exe y .dll set include=ruta de los ficheros .h set lib=ruta de los ficheros .lib

La expresión %path% representa el valor actual de la variable de entorno path. Una ruta va separada de la anterior por un punto y coma. Estas variables también pueden ser establecidas ejecutando el fichero vcvars32.bat que aporta Visual Studio en la ruta (no tiene porqué coincidir con la de su instalación): C:\Archivos de programa\Microsoft Visual Studio xx.x\VC\bin

Una vez establecidas estas variables, ya puede invocar al compilador C y al enlazador. En la figura siguiente se puede observar, como ejemplo, el proceso seguido para compilar avance.c:

APÉNDICE B: ENTORNOS DE DESARROLLO

669

Observe que primero hemos ejecutado vcvars32.bat para establecer las variables de entorno, después hemos cambiado al directorio de la aplicación (cd), a continuación hemos visualizado los ficheros .c de ese directorio (dir) y finalmente hemos invocado al compilador C (cl). El resultado es avance.exe. Para ejecutar este fichero, escriba avance en la línea de órdenes y pulse Entrar. El resultado será el mostrado en la figura.

CREAR UNA BIBLIOTECA DE FUNCIONES Visual Studio proporciona, entre otros, el tipo de proyecto Win32 Static Library que permite crear una biblioteca de funciones (ficheros con extensión .lib) análoga a las proporcionadas por C. Esto nos permitirá agrupar todas nuestras funciones de interés general en un solo fichero y utilizarlas en cualquier aplicación igual que utilizamos las funciones de la biblioteca C, printf, scanf, etc. Eso sí, antes de compilar una aplicación que utilice funciones de nuestra biblioteca, debemos es-

670

C/C++: CURSO DE PROGRAMACIÓN

pecificar en la lista de ficheros o en las opciones del enlazador (linker) el nombre de esa biblioteca. Para crear una de estas bibliotecas siga los pasos indicados a continuación. Como ejemplo, vamos a crear una biblioteca hash.lib con las funciones incluidas en el fichero cap12\hash\hash.c incluido en el ZIP que acompaña al libro. 1. Ejecute el entorno de desarrollo de Visual Studio. 2. Seleccione la orden Archivo > Nuevo > Proyecto. 3. Seleccione el tipo de proyecto Win32 y la plantilla Aplicación de consola Win32. Escriba el nombre del proyecto en la caja Nombre y en la caja Ubicación seleccione el directorio donde desea crear este proyecto. En nuestro caso vamos a dar al proyecto el nombre Hash. Pulse el botón Aceptar. Se visualiza la siguiente ventana:

4. En esta ventana seleccione Biblioteca estática, no seleccione Encabezado precompilado y haga clic en el botón Finalizar. 5. Ahora tenemos un proyecto vacío. Ejecute la orden Proyecto > Agregar elemento existente y añada el fichero o los ficheros que contengan las funciones que desea incluir en su biblioteca (hash.lib), así como los ficheros de cabecera necesarios para poder compilar el código escrito en cada una de las funciones. En nuestro caso, según muestra la figura siguiente, añadiremos el fichero

APÉNDICE B: ENTORNOS DE DESARROLLO

671

hash.c que contiene las funciones de nuestro interés y el fichero de cabecera hash.h que incluye las declaraciones de esas funciones.

6. Finalmente, ejecute la orden Compilar > Compilar... para compilar el proyecto y generar el fichero .lib. En nuestro caso se generará el fichero hash.lib con las funciones que incluía hash.c. Para utilizar esta biblioteca vamos a realizar otro ejemplo. Cree un nuevo proyecto ApHash formado por los ficheros: apHash.c, hash.h y hash.lib. El fichero apHash.c simplemente hará uso de las funciones de la biblioteca hash.lib lo que requerirá incluir el fichero hash.h. En la fase de enlace será necesario poder acceder a hash.lib, ya que apHash.c invoca a funciones de esta biblioteca. Por lo tanto, asegúrese de que ha añadido al proyecto la biblioteca hash.lib; después, compile y ejecute el proyecto.

672

C/C++: CURSO DE PROGRAMACIÓN

NETBEANS Evidentemente, para poder escribir programas C/C++ en una plataforma Linux se necesita un entorno de desarrollo válido para dicha plataforma. NetBeans, entre otros, puede ser este entorno de desarrollo. Se trata de un EDI libre, gratuito y sin restricciones de uso. Puede descargarlo de https://netbeans.org. Este EDI fue construido principalmente para el lenguaje Java, pero soporta otros lenguajes como C/C++. Está escrito en java, por lo que para ser ejecutado es necesario haber instalado previamente la máquina virtual de Java, que también puede descargar gratuitamente de http://java.com/es/. En la figura siguiente se puede observar la interfaz gráfica de este entorno de desarrollo integrado:

APÉNDICE B: ENTORNOS DE DESARROLLO

673

Para personalizar el EDI, ejecute la orden Options del menú Tools. Para editar y ejecutar el programa avance.c expuesto en el capítulo 1 utilizando este entorno de desarrollo, los pasos a seguir se indican a continuación: 1. Suponiendo que ya se está visualizando el entorno de desarrollo, ejecute la orden File > New Project (Archivo > Nuevo Proyecto). Se muestra la ventana New Project. 2. Seleccione C/C++ en la lista Categories (Categorías) y en la lista Projects (Proyectos) seleccione C/C++ Application (Aplicación C o C++). Después haga clic en el botón Next (siguiente). Se muestra la ventana New C/C++ Application. 3. Escriba el nombre del proyecto (Project Name); en nuestro caso será ProgC y, a continuación, seleccione la carpeta donde quiere guardarlo. 4. Asegúrese de que la casilla Create Main File (crear fichero/archivo principal) está marcada, establezca el nombre, en nuestro caso avance, y elija el lenguaje C (se añadirá la extensión correspondiente al fichero cuando se cree).

674

C/C++: CURSO DE PROGRAMACIÓN

5. Para finalizar haga clic en el botón Finish. El resultado será el siguiente:

El EDI crea la carpeta NetBeansProjects/ProgC en la que guardará el proyecto compuesto en este caso por un solo fichero de código fuente, avance.c, que almacenará el código correspondiente al programa.

APÉNDICE B: ENTORNOS DE DESARROLLO

675

En la ventana mostrada en la figura anterior distinguimos otras tres ventanas, algunas de ellas, con varios paneles. La que está en la parte superior derecha está mostrando el panel de edición para el código fuente de nuestra aplicación y tiene oculto el panel de inicio. La que está en la parte superior izquierda muestra el panel de proyectos; este lista el nombre del proyecto y el nombre de los ficheros que componen el proyecto. Observe el fichero avance.c; contiene el código de las acciones que tiene que llevar a cabo nuestra aplicación. También distinguimos otros nodos para otros tipos de ficheros, por ejemplo, para los ficheros de cabecera. Finalmente, la ventana que hay debajo de la de proyectos permite navegar por el código del proyecto. Puede visualizar otras ventanas desde el menú Window; por ejemplo, la ventana Output, que será utilizada para mostrar los resultados de la compilación y de la ejecución. Una vez creado el esqueleto de la aplicación, editamos el código de la misma. En nuestro caso, este código ya fue expuesto en el capítulo 1. El paso siguiente es construir el fichero ejecutable (fichero progc en la carpeta ProgC/dist/Debug/GNU-Linux-x86). Para ello, ejecute la orden Run > Build Project, o bien pulse la tecla F11. Si la compilación es correcta, puede pasar a ejecutar la aplicación ejecutando la orden Run > Run Project, o bien pulsando la tecla F6; observe el resultado en la ventana Output. En este caso, la ventana Output muestra un error: En la función ‘log’: avance.c:16: referencia a ‘log10’ sin definir. Para hacer uso de la biblioteca matemática en Linux tenemos que utilizar la opción –lm. Por ejemplo: cc avance.c -o avance.exe -lm

La opción –lm indica al compilador que utilice la biblioteca matemática libm.a como alternativa a la biblioteca estándar libc.a. Para especificar esta opción de compilación desde el entorno de desarrollo, haga clic con el botón secundario del ratón sobre el nombre del proyecto y seleccione Properties (propiedades del proyecto). Se muestra la ventana que se muestra a continuación; seleccione Build > C Compiler > Additional Options y escriba la opción –lm.

676

C/C++: CURSO DE PROGRAMACIÓN

Cuando la aplicación necesite más de un fichero, el proceso es igual de sencillo. Añadir otro fichero a una aplicación, por ejemplo un nuevo fichero que almacene una nueva clase, supone hacer clic con el botón derecho del ratón sobre el nombre del proyecto, elegir la orden New y seleccionar del menú contextual que se visualiza el tipo de elemento que se desea añadir.

Depurar una aplicación con NetBeans Anteriormente ya comentamos que una aplicación se depura porque los resultados que estamos obteniendo con la misma no son correctos y no sabemos por qué. Por ejemplo, para depurar una aplicación utilizando el depurador del entorno de desarrollo NetBeans, debe establecer un punto de parada inicial. Para ello, haga clic con el botón derecho del ratón sobre la sentencia a partir de la cual quiere ejecutar el código de su aplicación paso a paso y ejecute la orden Toggle Line Breakpoint (poner un punto de parada) del menú contextual que se visualiza, o haga clic en la zona sombreada a su izquierda:

APÉNDICE B: ENTORNOS DE DESARROLLO

677

Después, ejecute la orden Debug > Debug Project, o bien pulse las teclas Ctrl+F5 para iniciar la depuración. Continúe la ejecución paso a paso utilizando las órdenes del menú Debug o los botones correspondientes de la barra de herramientas Debug (para saber el significado de cada botón, ponga el puntero del ratón sobre cada uno de ellos).

De forma resumida, las órdenes disponibles para depurar una aplicación son las siguientes: 

Debug Project o Ctrl+F5. Inicia la ejecución de la aplicación en modo depuración hasta encontrar un punto de parada o hasta el final si no hay puntos de parada.



Toggle Line Breakpoint o Ctrl+F8. Pone o quita un punto de parada en la línea sobre la que está el punto de inserción.



Finish Debugger Session o Mayús+F5. Detiene el proceso de depuración.



Step Into o F7. Ejecuta la aplicación paso a paso. Si la línea a ejecutar coincide con una llamada a un método definido por el usuario, dicho método también se ejecuta paso a paso.



Step Over o F8. Ejecuta la aplicación paso a paso. Si la línea a ejecutar coincide con una llamada a un método definido por el usuario, dicho método no se ejecuta paso a paso, sino de una sola vez.



Step Out o Ctrl+F7. Cuando un método definido por el usuario ha sido invocado para ejecutarse paso a paso, utilizando esta orden se puede finalizar su ejecución en un solo paso.



Run to Cursor o F4. Ejecuta el código que hay entre la última línea ejecutada y la línea donde se encuentra el punto de inserción.

Para ver los valores intermedios que van tomando las variables ponga el cursor sobre ellas, o bien utilice las ventanas Variable, etc., del fondo del EDI. Para añadir o quitar ventanas ejecute la orden Window > Debuggin.

678

C/C++: CURSO DE PROGRAMACIÓN

INTERFAZ DE LÍNEA DE ÓRDENES EN UNIX/LINUX Los ficheros que componen una aplicación C realizada bajo UNIX/LINUX pueden ser escritos utilizando cualquier editor de texto ASCII proporcionado por este. Una vez editados y guardados todos los ficheros .c que componen la aplicación, el siguiente paso es compilarlos y enlazarlos para obtener el fichero ejecutable correspondiente a la misma. La orden para realizar estas operaciones es la siguiente: cc fich01.c [fich02 [fich03] ...] –o fich_ejecutable opciones

En el caso de UNIX/LINUX las rutas de acceso para que el sistema operativo encuentre la utilidad cc, los ficheros de cabecera .h y las bibliotecas, cuando son invocados desde la línea de órdenes, ya están definidas en el entorno de trabajo. En la figura siguiente se puede observar, como ejemplo, el proceso seguido para compilar avance.c:

Observe que primero hemos cambiado al directorio de la aplicación (cd), después hemos visualizado el contenido de ese directorio (ls -l) y finalmente hemos invocado al compilador C (cc). El fichero ejecutable resultante es el especificado por la opción –o, en el ejemplo progc, o a.out por omisión. Para ejecutar la aplicación del ejemplo, escriba progc en la línea de órdenes y pulse Entrar. El resultado será el que muestra la figura anterior. Si al realizar esta operación se encuentra con que no puede hacerlo porque el sistema no encuentra

APÉNDICE B: ENTORNOS DE DESARROLLO

679

el fichero especificado, tiene que añadir la ruta del directorio actual de trabajo a la variable de entorno PATH. Esto se hace así: PATH=$PATH:.

o bien especificar explícitamente la ruta a partir del directorio actual: ./progc

La expresión $PATH representa el valor actual de la variable de entorno PATH. Una ruta va separada de la anterior por dos puntos. El directorio actual está representado por el carácter punto.

El depurador gdb de Unix/Linux Cuando se tiene la intención de depurar un programa C escrito bajo UNIX, en el momento de compilarlo se debe especificar la opción g. Esta opción indica al compilador que incluya información extra para el depurador en el fichero objeto. Por ejemplo: cc -g prog01.c -o prog01

La orden anterior compila y enlaza el fichero fuente prog01.c. El resultado es un fichero ejecutable prog01 con información para el depurador. Una vez compilado un programa con las opciones necesarias para depurarlo, invocaremos a gdb para proceder a su depuración. La sintaxis es la siguiente: gdb fichero-ejecutable El siguiente ejemplo invoca al depurador gdb de UNIX, que carga el fichero ejecutable prog01 en memoria para depurarlo. gdb prog01

Una vez que se ha invocado el depurador, desde la línea de órdenes se pueden ejecutar órdenes como las siguientes: 

break [fichero:]función. Establece un punto de parada en la función indicada del fichero especificado. Por ejemplo, la siguiente orden pone un punto de parada en la función escribir. b escribir

680

C/C++: CURSO DE PROGRAMACIÓN



break [fichero:]línea. Establece un punto de parada en la línea indicada. Por ejemplo, la siguiente orden pone un punto de parada en la línea 10. b 10



delete punto-de-parada. Elimina el punto de parada especificado. Por ejemplo, la siguiente orden elimina el punto de parada 1 (primero). d 1



run [argumentos]. Inicia la ejecución de la aplicación que deseamos depurar. La ejecución se detiene al encontrar un punto de parada o al finalizar la aplicación. Por ejemplo: run



print expresión. Visualiza el valor de una variable o de una expresión. Por ejemplo, la siguiente orden visualiza el valor de la variable total. p total



next. Ejecuta la línea siguiente. Si la línea coincide con una llamada a una función definida por el usuario, no se entra a depurar la función. Por ejemplo: n



continue. Continúa con la ejecución de la aplicación. Por ejemplo: c



step. Ejecuta la línea siguiente. Si la línea coincide con una llamada a una función definida por el usuario, se entra a depurar la función. Por ejemplo: s



list. Visualiza el código fuente. Por ejemplo: l



bt. Visualiza el estado de la pila de llamadas en curso (las llamadas a funciones).



help [orden]. Solicita ayuda sobre la orden especificada.



quit. Finaliza el trabajo de depuración.

CODE::BLOCKS Otro entorno de desarrollo integrado para escribir programas C/C++ del que existen versiones para Windows, Linux y Mac OS X es Code::Blocks. Se trata de un EDI libre, gratuito y sin restricciones de uso que puede descargar de Internet desde la dirección http://www.codeblocks.org/. En la figura siguiente se puede observar el aspecto de este entorno de desarrollo integrado.

APÉNDICE B: ENTORNOS DE DESARROLLO

681

Para editar y ejecutar el programa avance.c visto en el capítulo 1, o cualquier otro programa, utilizando este entorno de desarrollo integrado, los pasos a seguir se indican a continuación: 1. Suponiendo que ya está visualizado el entorno de desarrollo, creamos un nuevo proyecto C++ (File, New, Project). Se muestra la ventana siguiente:

682

C/C++: CURSO DE PROGRAMACIÓN

2. Elegimos la categoría consola (Console), la plantilla Console application y pulsamos el botón Go. Se muestra la ventana siguiente:

3. Seleccionamos el lenguaje C y hacemos clic en el botón Next. Se muestra la ventana siguiente:

APÉNDICE B: ENTORNOS DE DESARROLLO

683

4. Especificamos el nombre del proyecto, la carpeta donde será guardado y hacemos clic en Next. Se muestra la ventana siguiente:

5. Si los datos presentados en la ventana anterior son correctos, hacemos clic en el botón Finish. El proyecto está creado; contiene un fichero main.c que incluye la función main por donde se iniciará y finalizará la ejecución del pro-

684

C/C++: CURSO DE PROGRAMACIÓN

grama. Si lo desea, puede cambiar el nombre main.c por avance.c. Después, edite este fichero igual que lo hizo en el capítulo 1.

6. A continuación, según se puede observar en la figura anterior, editamos el código que compone el programa y lo guardamos. 7. Después, para compilar el programa, ejecutamos la orden Build del menú Build y, una vez compilado (sin errores), lo podemos ejecutar seleccionando la orden Run del mismo menú (si no pudiéramos ver la ventana con los resultados porque desaparece ‒no es el caso‒, añadiríamos al final de la función main, antes de return, la sentencia “system("pause");” y al principio del fichero .c la directriz #include , si fuera necesario). En el caso de que la aplicación esté compuesta por varios ficheros fuente, simplemente tendremos que añadirlos al proyecto ejecutando la orden New del menú File.

APÉNDICE C

 F.J.Ceballos/RA-MA

CÓDIGOS DE CARACTERES Una tabla de códigos es un juego de caracteres donde cada uno tiene asignado un número utilizado para su representación interna. Algunos lenguajes como Java utilizan UNICODE para almacenar y manipular cadenas, y otros como C utilizan ANSI o ASCII.

UTILIZACIÓN DE CARACTERES ANSI CON WINDOWS ANSI (American National Standards Institute) es el juego de caracteres estándar más utilizado por los equipos personales. Como el estándar ANSI solo utiliza un byte para representar un carácter, está limitado a un máximo de 256 caracteres. Aunque es adecuado para el inglés, no acepta totalmente muchos otros idiomas. Para escribir un carácter ANSI que no esté en el teclado: 1. Localice en la tabla que se muestra en la página siguiente el carácter ANSI que necesite y observe su código numérico. 2. Pulse la tecla Bloq Núm (Num Lock) para activar el teclado numérico. 3. Mantenga pulsada la tecla Alt y utilice el teclado numérico para pulsar el 0 y a continuación las teclas correspondientes al código del carácter. Por ejemplo, para escribir el carácter  en el entorno Windows, mantenga pulsada la tecla Alt mientras escribe 0177 en el teclado numérico (ver la tabla de códigos en la página siguiente).

686

C/C++: CURSO DE PROGRAMACIÓN

JUEGO DE CARACTERES ANSI

APÉNDICE C: CÓDIGOS DE CARACTERES

687

UTILIZACIÓN DE CARACTERES ASCII En MS-DOS y fuera del entorno Windows se utiliza el juego de caracteres ASCII. Para escribir un carácter ASCII que no esté en el teclado: 1. Busque el carácter en la tabla de códigos que coincida con la tabla activa. Utilice la orden chcp para saber qué tabla de códigos está activa. 2. Mantenga pulsada la tecla Alt y utilice el teclado numérico para pulsar las teclas correspondientes al número del carácter que desee. Por ejemplo, si está utilizando la tabla de códigos 850, para escribir el carácter  mantenga pulsada la tecla Alt mientras escribe 227 en el teclado numérico (ver la tabla de códigos en la página siguiente).

688

C/C++: CURSO DE PROGRAMACIÓN

JUEGO DE CARACTERES ASCII

APÉNDICE C: CÓDIGOS DE CARACTERES

689

JUEGO DE CARACTERES UNICODE UNICODE es un juego de caracteres en el que se emplean 2 bytes (16 bits) para representar cada carácter. Esto permite la representación de cualquier carácter en cualquier lenguaje escrito en el mundo, incluyendo los símbolos del chino, japonés o coreano. Códigos UNICODE de los dígitos utilizados en español: \u0030-\u0039

0-9 ISO-LATIN-1

Códigos UNICODE de las letras y otros caracteres utilizados en español: \u0024 \u0041-\u005a \u005f \u0061-\u007a \u00c0-\u00d6 \u00d8-\u00f6 \u00f8-\u00ff

$ signo dólar A-Z _ a-z ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö øùúûüýþÿ

Dos caracteres son idénticos solo si tienen el mismo código Unicode.

ÍNDICE #  #, 476  ##, 476  #define, 39, 68, 472  #elif, 477  #else, 477  #endif, 477  #error, 483  #if, 477  #include, 68, 477, 483  #line, 482  #undef, 476 

A  abrir un fichero, 409  acceso aleatorio, 441  acceso secuencial, 429, 453  Ackerman, 592  acos, 652  algoritmo Boyer y Moore, 607  algoritmos hash, 619  ámbito de una variable, 83  ancho, 103  anidar if, 141  anidar while, do, o for, 154  ANSI, 72, 685  ANSI C, 475  árbol, 542  árbol binario, 543   

    árbol binario de búsqueda, 546  árbol binario perfectamente equilibrado, 558  árbol, recorrer, 544  archivo, 402  argumento, 71  argumentos en la línea de órdenes, 363  argumentos pasados por valor, 77  argumentos por referencia, 78  argumentos, pasar a una función, 77  aritmética de punteros, 272, 277, 278, 286  ASCII, 687  asignación, 100  asignación dinámica de memoria, 299  asignar bytes desde una dirección, 270  asin, 652  ASSERT, 486  atan, 652  atan2, 652  atof, 208, 648  atoi, 208, 648  atol, 208, 648  auto, 86 

B  biblioteca de funciones, 669  bit, 2  bits de error, 413  bloque, 70  borrar los elementos de una lista, 504  borrar nodo, 552  borrar un elemento de una lista, 503 

692

C/C++: CURSO DE PROGRAMACIÓN

Boyer y Moore, 607  break, 149, 163  buffer, 404    flujo, 437    vaciar, 441  burbuja, 598  buscar nodo, 550  buscar un elemento en una lista, 502  búsqueda binaria, 606  búsqueda de cadenas, 607  búsqueda secuencial, 606  byte, 2 

C  cadenas de caracteres, 200    leer, 121    leer y escribir, 201  cadena, principio y final, 282  calificación de funciones, 90  calificadores, 86  calloc, 304  campo, 402  campo de bits, 242  carácter \n, 115  caracteres de C, 24    manipular, 198  cast, 55  ceil, 654  cerrar un fichero, 412  char, 27  clearerr, 413  clock, 656  cola, 528  comentario, 39  compilación condicional, 477  compilación, constante simbólica, 479  compilador, 4  const, 40  constante simbólica, 39, 472  contador, 199  continue, 164  conversión, 42  conversión entre tipos, 54  conversión forzada, 55  copiar matrices, 218  copiar un fichero en otro, 421  copiar una matriz, 280  cos, 653  cosh, 653 

CR, 115  CR+LF, 410  ctime, 657 

D  decimal, 35  declaración, 69  declaración compleja, 326  declaración de una función, 71  define, 68  defined, 479  definición, 69  definición de una función, 73  depurar, 666, 676  dirección de, 51  dirección de memoria, 78, 267  directrices, 67  directrices #if, #elif, #else y #endif, 477  directrices para el preprocesador, 471  directriz, 471    #define, 472    #error, 483    #include, 477, 483    #line, 482    #undef, 476    de inclusión, 68    de sustitución, 68  dispositivos estándar, 434  do ... while, 157  double, 32 

E  E/S carácter a carácter, 418  E/S con formato, 425  E/S de cadenas de caracteres, 422  E/S utilizando registros, 427  EDI, 661  else if, 144  ensamblador, 2  enum, 29  EOF, 115  errno, 416  errores en operaciones de E/S, 413  escribir con formato, 102  escribir en un fichero, 430  escribir un carácter, 119  estática vs dinámica, 301  estructura como argumento, 354 

ÍNDICE

estructura else if, 144  estructura FILE, 403  estructuras, 221    abstractas de datos, 496    acceso a sus miembros, 224    crear, 221    definir variables, 222    dinámicas, 495    miembros, 225    operaciones, 226    variables, 237  exit, 131, 302  exp, 654  expresión, 42  expresiones booleanas, 45  extern, 86 

F  fabs, 655  fclose, 412  feof, 415  ferror, 413  fflush, 117, 441  fgetc, 420  fgets, 423  fichero, 402    abrir, 409    cerrar, 412    de cabecera, 483    escribir, 430    indexado, crear, 637    leer, 433    temporal, 441  ficheros binarios, 406  ficheros de texto, 406  FILE, 403  fin de fichero, 115, 415  float, 31  floor, 655  flujo, 102, 403    buffer, 437  fopen, 410  for, 160  formato, especificaciones, 102  fprintf, 425  fputc, 419  fputs, 422  fread, 429  free, 301 

freopen, 411  fscanf, 426  fseek, 417, 442  ftell, 417, 418, 442, 444, 461  fugas de memoria, 301  función, 63, 70    acos, 652    asin, 652    atan, 652    atan2, 652    atof, 648    atoi, 648  función    atol, 648    calloc, 304    ceil, 654    clearerr, 413    clock, 656    cos, 653    cosh, 653    ctime, 657    es recursiva, 367    exit, 131, 302    exp, 654    fabs, 655    fclose, 412    feof, 415    ferror, 413    fflush, 117, 441    fgetc, 420    fgets, 423    floor, 655    fopen, 410    fprintf, 425    fputc, 419    fputs, 422    fread, 429    free, 301    frente a macro, 473    freopen, 411    fscanf, 426    fseek, 417    ftell, 417    fwrite, 428    getch, 120    getchar, 118    getche, 120    gets, 201, 423    localtime, 658    log, 654 

693

694

C/C++: CURSO DE PROGRAMACIÓN

getchar, 118  getche, 120  gets, 122, 201, 423  getw, 422 

  log10, 654    malloc, 299    memcmp, 660    memcpy, 220, 659    memset, 220, 659    perror, 415    pow, 655    printf, 102    putchar, 119    puts, 203    rand, 656    realloc, 302    rewind, 418    scanf, 81, 108    setvbuf, 438    sin, 653  función    sinh, 653    sprintf, 649    sqrt, 655    srand, 656    strcat, 640    strchr, 640    strcmp, 642    strcpy, 640    strcspn, 643    strlen, 644    strlwr, 647    strncat, 644    strncmp, 645    strncpy, 645    strrchr, 641    strspn, 645    strstr, 646    strtok, 646    strupr, 647    system, 128    tan, 653    tanh, 654    time, 657    tmpfile, 441    toascii, 650    tolower, 650    toupper, 650  fwrite, 428 

H  Hanoi, 595  hash, 619  hexadecimal, 36 

I  identificadores, 38  if anidados, 141  impresora, 434  include, 68  indirección, 52, 288  inorden, 544  inserción, 600  insertar nodo, 550  insertar un elemento en una lista, 501  int, 28  interfaz genérica, 509  intérprete, 4 



G  gdb, 679  getch, 120 

lagunas de memoria, 301  leer con formato, 108  leer de un fichero, 433  leer un carácter, 118  lenguaje máquina, 3  lenguajes de alto nivel, 3  LF, 115  limpiar el buffer asociado con un flujo, 117  limpiar la pantalla, 128  línea de órdenes, 363, 668  LINUX, 678  lista circular, 520  lista circular doblemente enlazada, 533  lista doblemente enlazada, 533  lista lineal simplemente enlazada, 496  lista lineal, recorrer, 504  listas lineales, 496  literal, 35  literal de cadena de caracteres, 37  literal de un solo carácter, 36  literal entero, 35  literal real, 36 

ÍNDICE

llamada a una función, 75  localtime, 658  log, 654  log10, 654  long, 28  long double, 32  LPT1, 435 

M  macro, 472  macro frente a función, 473  macros predefinidas, 475  main, 75  malloc, 299  matrices, 187, 188  matrices de punteros, 286  matrices dinámicas, 304  matrices dinámicas de cadenas de caracteres,  313  matrices dinámicas de dos dimensiones, 309  matrices dinámicas de una dimensión, 305  matriz, 15, 121  matriz asociativa, 196  matriz de cadenas de caracteres, 214  matriz de estructuras, 231  matriz de punteros a cadenas de caracteres,  291  matriz multidimensional, 209  matriz numérica multidimensional, 209  matriz sparse, 265  matriz static, 195  matriz, acceder a un elemento, 190  matriz, definir, 189  matriz, iniciar, 195  matriz, tipo y tamaño, 208  memcmp, 220, 660  memcpy, 220, 659  memoria intermedia, 404  memset, 220, 308, 659  mensajes de error, 415  método de inserción, 600  método de la burbuja, 598  método de quicksort, 602  mezcla natural, 611  milisegundos transcurridos desde el 1 de enero  de 1970, 332 

695

N  nivel de indirección, 288  nodo de un árbol, 544  NULL, 276, 498  números aleatorios, 330 

O  octal, 35  operaciones con punteros, 271  operador   #, 476    ##, 476    &, 51    *, 52    coma, 51    condicional, 49    defined, 479    sizeof, 50    ternario, 49  operadores, 42    a nivel de bits, 46    aritméticos, 42    de asignación, 47    de relación, 44    lógicos, 45    prioridad, 53    unitarios, 46  ordenación, 597  ordenar cadenas de caracteres, 295  ordenar un fichero, 610  ordenar un fichero utilizando acceso aleatorio,  616 

P  palabras clave, 38  pantalla, limpiar, 128  parámetros, 72, 74  path, 668  perror, 415  pila, 527  polinomios, 327  postorden, 545  pow, 655  precisión, 106  preorden, 544  preprocesador, 67, 471  printf, 102 

696

C/C++: CURSO DE PROGRAMACIÓN

prioridad de los operadores, 53  programa, 2, 63  programa compuesto por varios ficheros, 81  prototipo de una función, 71  puntero, 79, 267    a un puntero, 288    a una cadena de caracteres, 282    a una función, 369    como argumento, 352    como parámetro, 320    de lectura/escritura, 417    definir, 267    genérico, 274    nulo, 276  punteros   a estructuras, 317    asignación, 271    comparación, 274    const, 277    operaciones aritméticas, 272    operadores, 269    y matrices, 277  putchar, 119  puts, 203  putw, 422 

Q  quicksort, 602 

R  raíz de un árbol, 544  rand, 656  realloc, 302  reasignar un bloque de memoria, 302  recorrer un árbol, 544  recursión, 591  redireccionar la entrada o salida, 365  redireccionar stdin, stdout o stderr, 411  register, 86  registro, 402  registros, 427  retornar la dirección de una v. static, 361  retornar un puntero, 360  retornar una copia de los datos, 359  return, 74, 131  return vs exit, 302  rewind, 418 

S  scanf, 108, 123  secuencia de escape, 25  sentencia   break, 163    compuesta, 70    continue, 164    de asignación, 100    do ... while, 157    for, 160    return, 74, 131    simple, 69    switch, 147    while, 151  set, 668  setvbuf, 438  short, 28  signed, 26  sin, 653  sinh, 653  sinónimos de otro tipo, 33  size_t, 300  sizeof, 50  sprintf, 208, 649  sqrt, 655  srand, 656  static, 86  stdaux, 405  stderr, 405  stdin, 102, 405  stdout, 102, 405  stdprn, 405  strcat, 640  strchr, 640  strcmp, 208, 642  strcpy, 208, 640  strcspn, 643  stream, 403  strlen, 208, 644  strlwr, 647  strncat, 644  strncmp, 645  strncpy, 645  strrchr, 641  strspn, 645  strstr, 646  strtok, 646  struct, 222  strupr, 647 

ÍNDICE

tolower, 208, 650  torres de Hanoi, 595  toupper, 208, 650  typedef, 33, 208, 223 

subíndice, 189  switch, 147  sys_errlist, 416  sys_nerr, 416  system, 128 

T  tan, 653  tanh, 654  temporal, fichero, 441  tiempo de ejecución, 479  time, 332, 657  tipo, 104    abstracto de datos, 227    char, 27    double, 32    enumerado, 29    float, 31    int, 28    long, 28    long double, 32    short, 28  tipos de datos, 26  tipos derivados, 33  tipos primitivos, 26  tmpfile, 441  toascii, 650 

 

U  UNICODE, 689  unión, 234  UNIX, 678  unsigned, 26 

V  validar un dato de entrada, 124  variable, 40    global, 84    iniciar, 41    local, 84  Visual C++, 661  void, 73  void  , 274 

W  while, 151  while, do, o for anidados, 154 

697

Del mismo autor ● Curso de programación con PASCAL ● Curso de programación GW BASIC/BASICA ● Manual para TURBO BASIC Guía del programador ● Manual para Quick C 2 Guía del programador ● Manual para Quick BASIC 4.5 Guía del programador ● Curso de programación Microsoft COBOL ● Enciclopedia del lenguaje C ● Curso de programación QBASIC y MS-DOS 5 ● Curso de programación RM/COBOL-85 ● El abecé de MS-DOS 6 ● Microsoft Visual C ++ (ver. 1.5x de 16 bits) Aplicaciones para Windows ● Microsoft Visual C ++ Aplicaciones para Win32 (2.ª edición) ● Microsoft Visual C ++ Programación avanzada en Win32 ● Visual Basic 6 Curso de programación (2.ª edición) ● Enciclopedia de Microsoft Visual Basic 6 ● El lenguaje de programación Java ● El lenguaje de programación C#

ISBN: 978-84-86381-36-3 224 págs. ISBN: 978-84-86381-87-5 320 págs. ISBN: 978-84-86381-43-1 444 págs. ISBN: 978-84-86381-65-3 540 págs. ISBN: 978-84-86381-74-5 496 págs. ISBN: 978-84-7897-001-8 480 págs. ISBN: 978-84-7897-053-7 888 págs. ISBN: 978-84-7897-059-9 384 págs. ISBN: 978-84-7897-070-4 396 págs. ISBN: 978-84-7897-114-5 224 págs. ISBN: 978-84-7897-180-0 846 págs. + 2 disquetes ISBN: 978-84-7897-561-7 792 págs. + disquete ISBN: 978-84-7897-344-6 888 págs. + CD-ROM ISBN: 978-84-7897-357-6 528 págs. + disquete ISBN: 978-84-7897-386-6 1.072 págs. + CD-ROM ISBN: 978-84-7897-485-6 320 págs. + CD-ROM ISBN: 978-84-7897-500-6 320 págs. + CD-ROM

Del mismo autor ● El lenguaje de programación Visual Basic.NET ● Java 2 Lenguaje y aplicaciones ● Programación orientada a objetos con C ++ (4.ª edición) ● C/C++ Curso de programación (3.ª edición) ● Microsoft C# Lenguaje y aplicaciones (2.ª edición) ● Aplicaciones .Net multiplataforma (Proyecto Mono) ● Enciclopedia del lenguaje C ++ (2.ª edición) ● Microsoft Visual Basic .NET Lenguaje y aplicaciones (3.ª edición) ● Java 2 Curso de programación (4.ª edición) ● Microsoft C# Curso de programación (2.ª edición) ● Visual C#. Interfaces gráficas y aplicaciones para Internet con WPF, WCF y Silverlight ● Visual Basic. Interfaces gráficas y aplicaciones para Internet con WPF, WCF y Silverlight ● Enciclopedia de Microsoft Visual C#. Interfaces gráficas y aplicaciones para Internet con Windows Forms y ASP.NET (4.ª edición) ● Enciclopedia de Microsoft Visual Basic. Interfaces gráficas y aplicaciones para Internet con Windows Forms y ASP.NET (3.ª edición) ● Java. Interfaces gráficas y aplicaciones para Internet (4.ª edición)

ISBN: 978-84-7897-525-9 464 págs. + CD-ROM ISBN: 978-84-7897-745-1 392 págs. + CD-ROM ISBN: 978-84-7897-761-1 648 págs. + CD-ROM ISBN: 978-84-7897-762-8 708 págs. + CD-ROM ISBN: 978-84-7897-813-7 520 págs. + CD-ROM ISBN: 978-84-7897-880-9 212 págs. + CD-ROM ISBN: 978-84-7897-915-8 902 págs. + CD-ROM ISBN: 978-84-9964-020-4 520 págs. + CD-ROM ISBN: 978-84-9964-032-7 820 págs. + CD-ROM ISBN: 978-84-9964-068-6 850 págs. + CD-ROM ISBN: 978-84-9964-203-1 956 págs. + CD-ROM ISBN: 978-84-9964-204-8 938 págs. + CD-ROM ISBN: 978-84-7897-986-8 1.145 págs. + CD-ROM ISBN: 978-84-7897-987-5 1.125 págs. + CD-ROM ISBN: 978-84-9964-522-3 1.000 págs. + ZIP

INSTALACIÓN Para instalar el kit de desarrollo de C/C++ y los ejemplos de este libro, descargue de Internet el paquete correspondiente al EDI preferido por usted (Microsoft Visual Studio, NetBeans, Code::Blocks, etc.) e instálelo. Después, proceda según se indica en el apéndice B.

SOBRE LOS EJEMPLOS DEL LIBRO El material adicional de este libro, con las aplicaciones desarrolladas y el software para reproducirlas, puede descargarlo desde http://www.fjceballos.es (sección Mis publicaciones > C/C++ > Material adicional) o desde http://www.ra-ma.com (en la página correspondiente al libro). La descarga consiste en un fichero ZIP con una contraseña que encontrará en el libro.

LICENCIA Los paquetes de software a los que se hace referencia en el material adicional del libro es propiedad de las firmas que los representan. La inclusión en este libro se debe a su gentileza y es totalmente gratuita y con la finalidad de apoyar el aprendizaje del software correspondiente. Para obtener más información y actualizaciones, visite las direcciones indicadas en dicho software. Al realizar el proceso de instalación, haga el favor de consultar el acuerdo de licencia para cada uno de los productos.

WEB DEL AUTOR: http://www.fjceballos.es En esta web podrá echar una ojeada a mis publicaciones más recientes y acceder a la descarga del software necesario para el estudio de esta obra, así como a otros recursos.

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF