introdccuin a la programacion



Comments



Description

UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001– METODOLOGÍA DE TRABAJO ACADÉMICO UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA ESCUELA DE CIENCIAS BASICAS, TECNOLOGIA E INGENIERIA PROGRAMA DE INGENIERIA DE SISTEMAS 301304 – INTRODUCCIÓN A LA PROGRAMACIÓN MIRIAN BENAVIDES RUANO (Director Nacional) SERGIO BERMUDEZ ROJAS Acreditador PASTO Enero de 2011 1 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ASPECTOS DE PROPIEDAD INTELECTUAL Y VERSIONAMIENTO El presente módulo fue diseñado en el año 2004 por el Ing. IVAN ARTURO LOPEZ, docente de la UNAD, y ubicado en el CEAD de Popayán, el Ing. López es Ingeniero de Sistemas, y especialista en Pedagogía para el Desarrollo del Aprendizaje Autónomo y Estudiante master educación y tics UOC (Universidad Oberta de Cataluña). El presente módulo ha tenido tres actualizaciones, una desarrollada por el Ing. Iván López en los años 2005, la segunda hecha en el año 2008 por la Ing. IRINA NARVAEZ ESPINOSA, quien ha sido tutora de la UNAD en los CEAD de Acacias y José Acevedo y Gómez, desde el año 2001, es Ingeniera de Sistemas, especialista en Pedagogía para el Desarrollo del Aprendizaje Autónomo y aspirante al título de magíster en Informática Educativa. En el año 2009 el Ing. SERGIO BERMUDEZ ROJAS, tutor del CEAD Barranquilla, apoyó el proceso de revisión de estilo del módulo y dio aportes disciplinares, didácticos y pedagógicos en el proceso de acreditación de material didáctico desarrollado en el mes de JULIO de 2009. La actualización más reciente ha sido desarrollada en ENERO DE 2011 por la Ing. MIRIAN BENAVIDES RUANO, Docente Auxiliar en el CEAD Pasto, Ingeniera de Sistemas, Especialista en Docencia Universitaria y Especialista en Informática y Telemática, quien se desempeña como Directora del curso a nivel nacional desde AGOSTO de 2010. 2 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO INTRODUCCIÓN El curso de introducción a la programación es un curso que cobra vital importancia y al cual se le puede sacar el máximo provecho, puesto que los participantes tienen conocimientos previos fuertes, que vienen del curso inmediatamente anterior (algoritmos), y enlaza la última unidad donde se inicia el trabajo con un lenguaje de programación específico. En este módulo se incluirá un pequeño apartado al retomar conceptos básicos del lenguaje de programación, de su compilador, su editor y algunas lecturas que permiten conceptualizar la forma de depurar programas; se reforzará los conceptos sobre funciones, complementándolas con trabajo de recursividad, y a pesar de que en algoritmos se trabaja la parte de funciones es bueno prestarle mucho interés, ya que C++ es un lenguaje que se trabaja todo bajo funciones, luego se continúa con un trabajo importante referido a punteros, la razón es que cuando s e habla de funciones, estructuras, archivos, s e j u s t i f i c a l a i m p o r t a n c i a d e l u s o d e punteros. En la segunda unidad se aborda el tema de las estructuras estáticas y se dedica todo un capítulo a este tema, aunque no es suficiente para abordar todos los apartados, es aquí donde se ve la necesidad de que el estudiante se apropie de los temas e investigue más por su cuenta, aproveche los recursos de biblioteca y las consultas de Internet para ampliar aun más los conceptos. Se trabaja también el tema de vectores (unidimensionales y bidimensionales), y las cadenas de caracteres. Por último es importante, conocer los métodos de ordenamiento y de búsqueda, también se requiere que los datos no se queden únicamente en la memoria del computador, sino que sean escritos en un dispositivo de almacenamiento para que puedan recuperarse en cualquier momento. Este tema es un poco complejo se pide a los participantes que no solo se queden con los ejercicios propuestos, sino que traten de profundizar más; esta tarea puede ser apasionante, pues es la base para abordar los temas que se acercan cuando inicien el trabajo con bases de datos. Para terminar, solo resta decir que este modulo está construido, con base en una recopilación de ejercicios prácticos que llevarán al estudiante a un aprendizaje significativo, complementado con teoría, una amplia referencia bibliográfica y direcciones web, que posibilitarán una mayor autonomía y confianza por parte del estudiante. 3 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ÍNDICE DE CONTENIDO ITEM INTRODUCCION 1.0 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4 UNIDAD UNO: INTRODUCCION A LA PROGRAMACION EN C O C++ CAPITULO 1: GENERALIDADES Lección 1: Revisión de conceptos generales de programación Lección 2: Editor de Lenguaje C++ Lección 3: Estructura general de un programa en lenguaje C Lección 4: Definición de compilador Lección 5: Depuración de Programas CAPITULO 2: FUNCIONES Lección 6: Definición de una función Lección 7: Declaración de una función Lección 8: Llamados de función Lección 9: Prototipos Lección 10: Recursividad CAPITULO 3: APUNTADORES Lección 11: Declaración de apuntador Lección 12: Definición de un apuntador Lección 13: Apuntadores y Funciones Lección 14: Apuntadores y Arreglos Lección 15: Ejercicios ACTIVIDADES DE AUTOEVALUACIÓN DE LA UNIDAD 1 TEMA PAG 3 9 11 12 14 15 16 19 21 21 22 23 24 24 27 27 28 31 32 33 35 4 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4 3.0 3.1 3.1.1 3.1.2 UNIDAD DOS: ARREGLOS CAPITULO 4: ARREGLOS Y CADENAS Lección 16: Definición y Declaración Lección 17: Arreglos Unidimensionales Lección 18: Arreglos Bidimensionales Lección 19: Cadenas de Caracteres Lección 20: Ejercicios CAPITULO 5: ORDENACION Lección 21: Definición Lección 22: Burbuja Lección 23: Inserción Lección 24: Shell Lección 25: Quicksort CAPITULO 6: BUSQUEDA Lección 26: Definición Lección 27: Lineal Lección 28: Binaria Lección 29: De Hash Lección 30: Ejercicios ACTIVIDADES DE AUTOEVALUACIÓN DE LA UNIDAD 2 UNIDAD TRES: ESTRUCTURAS Y ARCHIVOS CAPITULO 7: ESTRUCTURAS Lección 31: Declaración de una Estructura Lección 32: Asignación de Estructuras 36 38 38 40 42 43 44 46 46 48 51 54 57 65 65 65 67 68 69 72 74 75 75 76 5 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 3.1.3 3.1.4 3.1.5 3.2 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.4 Lección 33: Estructuras Anidadas Lección 34: Estructuras Anónimas Lección 35: Ejercicios CAPITULO 8: ARCHIVOS Lección 36: Definición de Archivos Lección 37: Características de los Archivos Lección 38: Clasificación de los Archivos Lección 39: Tipos de Archivos Lección 40: Ejercicios CAPITULO 9: ACCESO A LOS ARCHIVOS Lección 41: Tipos de Acceso Lección 42: Operaciones que se Realizan a los Archivos Lección 43: Organización de los Archivos Lección 44: Archivos Tipo Texto Lección 45: Archivos de acceso directo ACTIVIDADES DE AUTOEVALUACIÓN DE LA UNIDAD 3 BIBLIOGRAFIA ANEXOS Tipos de Datos ANEXOS Índice de funciones ANEXOS Errores Comunes de Programación 77 78 81 83 83 83 83 85 86 88 88 92 93 96 104 112 113 114 118 125 6 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO LISTADO DE TABLAS TEMA TABLA 1. Tipos de datos básicos TABLA 2. Tipos de datos TABLA 3. Operadores PAG 18 114 117 7 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO LISTADO DE GRÁFICOS Y FIGURAS TEMA FIGURA 1. Partes del editor de Lenguaje C++ FIGURA 2. Ventana de compilación FIGURA 3. Torres de Hanoi FIGURA 4. Vector FIGURA 5. Matriz FIGURA 6. Funciones para trabajo con archivos FIGURA 7. Ventana de ejecución 1 FIGURA 8. Recomendación FIGURA 9. Ventana de ejecución 2 FIGURA 10. Ventana de ejecución 3 FIGURA 11. Ventana de ejecución 3 FIGURA 12. Ventana de ejecución 5 FIGURA 13. Ventana de ejecución 6 PAG 14 20 35 40 42 85 96 98 99 102 104 104 106 8 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO UNIDAD 1 Nombre de la Unidad Introducción INTRODUCCION A LA PROGRAMACION EN C O C++ El curso de introducción a la programación es un curso que cobra vital importancia y al cual se le puede sacar el máximo provecho, puesto que los participantes tienen conocimientos previos fuertes, que vienen del curso inmediatamente anterior (algoritmos), y enlaza la última unidad donde se inicia el trabajo con un lenguaje de programación especifico. En este modulo se incluirá un pequeño apartado al retomar conceptos básicos del lenguaje de programación, de su compiladores, de su editor y algunas lecturas que permiten conceptualizar la forma de depurar programas, se reforzará los conceptos sobre funciones, complementándolas con trabajo de recursividad, y a pesar de que en algoritmos se trabaja la parte de funciones es bueno prestarle mucho interés, ya que C++ es un lenguaje que se trabaja todo bajo funciones, luego continuamos con un trabajo importante referido a punteros, la razón es que cuando hablamos de funciones, estructuras, archivos, los punteros cobran vital importancia en el funcionamiento adecuado de estos ítems. En una segunda unidad nos afrentamos a las estructuras estáticas y le dedicamos todo un capitulo a este tema y consideró que no es suficiente para abordar todos los apartados, es aquí donde se ve la necesidad de que el estudiante se apropie de los temas e investigue más por su cuenta, aproveche los recurso de biblioteca y las consultas de Internet para ampliar aun más los conceptos, se trabaja también y por tratarse de vectores, las cadenas de caracteres. Por último es importante que los datos no se queden únicamente en la memoria del computador, sino que sean escritos en un dispositivo de almacenamiento para que puedan recuperarse en cualquier momento. Este tema es un poco complejo se pide a los participantes que no solo se queden con los ejercicios propuestos, sino que traten de mirar un poco más este tema, es uno de los más apasionantes, pues es la base abordar los temas que se acercan cuando inicien el trabajo con bases de datos. Para terminar, solo resta decir que este modulo está construido, con base en una recopilación de ejercicios prácticos que llevará al estudiante a un aprendizaje significativo, complementado con teoría y una amplia referencia bibliográfica y direcciones web. Nuevamente reitererarles la invitación a que consulten la diversidad de textos que existen con referencia a los temas que se trabajan en este modulo. La primera unidad de una u otra manera se trata de un pequeño repaso sobre la programación de computadoras, haciendo especial énfasis en la programación utilizando un lenguaje especifico, como lo es C++. Es importante que los estudiantes retomen el modulo de algoritmos, para recordar algunos de los conceptos olvidados, lo mismo que bibliografía Justificación 9 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO referente al tema. Esta primera unidad comprende una pequeña inducción al editor del lenguaje que se utilizará a lo largo del modulo, se prestará primordial interés al tema de las funciones tratado al final del último capítulo de algoritmos, pero complementándolo con temas nuevos como son las funciones recursivas. Igualmente están implícitas diferentes estrategias de pensamiento de orden superior que el estudiante irá afianzado gracias al apoyo permanente del tutor, quien es el mediador del proceso de aprendizaje. A lo largo de esta unidad se presentan una serie de ejercicios que le permiten al estudiante verificar la evolución de su aprendizaje. Afianzar conocimientos referentes a la programación de computadoras, con un lenguaje especifico Propósitos de la unidad Realizar recuento de las principales características de la programación de computadoras Dominar de manera general el entorno de programación con el compilador C++ Fortalecer los temas de funciones Intencionalidades Formativas Objetivos de la unidad Conocer la funcionalidad del editor del compilador utilizado aquí Motivar a descubrir que otras funciones tiene el editor del lenguaje Determinar las técnicas de programación, utilizando C++ como lenguaje de base Competencias de la unidad El estudiante domina los conceptos previos necesarios para el desarrollo de programas en C++ El estudiante reconoce el funcionamiento general del editor de C++ El estudiante aplica las funciones como herramienta fundamental en la modularización de los programas Metas de aprendizaje El estudiante es capaz de desarrollar programas mediante la utilización de funciones Denominación de capítulos Generalidades Funciones Apuntadores 10 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 1: GENERALIDADES Introducción Es fundamental inicial el curso de introducción a la programación, abordando temas que ubiquen al estudiante en el entorno de trabajo, por ello se incluyen temáticas generales de gran importancia para comprender los conceptos básicos de programación estructurada. Es así como se han elegido cinco lecciones que parten de información general sobre los aspectos más relevantes de la programación, los requerimientos que se deben tener en cuenta antes de iniciar con la codificación propiamente dicha de programas en el Lenguaje C o C++. Posteriormente se realiza una descripción del entorno de trabajo del lenguaje, donde se explica de manera general la forma como se construye un programa, utilizando el entorno propio del lenguaje de programación y las estructuras básicas que constituyen un programa en C o C++. Se analiza la temática de los compiladores y de manera específica el compilador del lenguae C o C++, para apoyar al estudiante en la comprensión sobre la forma como un conjunto de instrucciones debidamente estructuradas pueden lograr la construcción de programas que sirvan de solución a problemas específicos que puedan ser resueltos mediante un sistema informático, partiendo de interpretaciones adecuadas, diseños sólidos y revisiones constantes posibiliten depuraciones óptimas que solucionen problemas lógicos y de sintaxis. Finalmente, debido a que el tema de la programación es bastante amplio, es indispensable que el estudiante utilice todos los recursos que se encuentrena su alcance para lograr una verdadera comprensión de los temas expuestos, puesto que el módulo constituye un punto de partida para avanzar en su proceso de aprendizaje. Queda abiertan entonces la invitación a consultar la bibliografía sugerida y aprovechar todas las herramientas que se encuentran en la web para avanzar en el proceso de construcción de conocimiento. 11 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lección 1: Revisión de conceptos generales de programación Programación: es un proceso mediante el cual se convierten especificaciones generales de la solución de un problema, en instrucciones que el computador puede interpretar y que producen los resultados deseados (desarrollo de software). Programa: lista de instrucciones que el computador sigue para convertir datos en información. Estas dependen del lenguaje de programación que se utilice. Un programa debe ser: • Confiable y funcional • Comprensible • Documentado Fases para la creación de un programa • • Definición del problema: clara y precisa Análisis del problema: requiere identificar o Datos de salida (información que debe producir el programa) o Datos de entrada (datos que debe suministrar el usuario para lograr los resultados esperados o Datos de proceso (fórmulas necesarias para procesar los datos) Diseño de la solución: lista ordenada y cronológica de los pasos a seguir para lograr resultados (diagramas de flujo, pseudocódigo, etc.). Debe ser simple, clara, precisa, exacta, tener un orden lógico e indicar su inicio y final. Codificación: escribir la solución del problema en un lenguaje de programación (traducir el diagrama de flujo o pseudocódigo en instrucciones que puedan ser interpretadas por el computador) Prueba y depuración: ejecutar el software para identificar y eliminar los errores (de sintaxis o de tipo lógico) Documentación: guía que facilita futuras modificaciones del software • • • • Programación estructurada: se caracteriza por organizar las instrucciones de manera secuencial, de tal manera que es posible leer la codificación desde el inicio hasta el final en forma continua sin saltar de un lugar a otro, siguiendo el camino lógico establecido por el programador. En este paradigma de programación se debe prestar especial atención a la etapa de diseño de la solución, una vez establecidos los pasos secuenciales, la codificación es más fácil. Características: la estructura del programa se realiza de la manera más clara y precisa posible, para ello utiliza: 12 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO • • • Secuencia: sucesión simple de operaciones Selección: bifurcación condicional de una o más operaciones Iteracción: repetición de tareas mientras se cumple una o más condiciones Ventajas: • Tiene una estructura clara y por ende una buena presentación. • Es más fácil de comprender • Facilita la revisión de la codificación • Reduce el tiempo de prueba y depuración Identación: utilización de sangrias (espacios) para facilitar la lectura del programa puesto que muestra en forma gráfica las relaciones entre las instrucciones. Para aprovechar la identación en un programa en C++ se sugiere: • Escribir en la misma columna los indicadores de inicio y fin de cada bloque de sentencias • Utilizar diferentes sangrias para indicar anidamientos de instrucciones • Escribir una instrucción por línea Lenguaje de Programación C Según Cesar Becerra: • C es un lenguaje de nivel medio: combina elementos de lenguajes de alto nivel con la funcionalidad del ensamblador. • Su código es transportable: funciona en equipos APPLEE como en IBM. • Es estructurado: permite el uso de subrutinas (parte del código que maneja sus propias variables y que pueden ser llamadas en diferentes partes del programa principal) • Funcionalidad: en un comienzo se utilizó por su potencia y eficacia en programas de sistemas (sistemas operativos, interpretes, editores, ensambladores, compiladores, administradores de bases de datos); pero actualmente para todo tipo de desarrollos. • C es compilador, los lenguajes al ser ejecutados pueden interpretarse (línea a línea), o compilarse (utiliza compilador para ejecutarse, todo el programa fuente se convierte en programa objeto, de manera que el compilador lo ejecuta directamente). 13 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lección 2: Editor de lenguaje C++ 1 2 3 4 5 6 7 8 9 10 11 12 15 13 14 FIGURA 1: Partes del Editor de lenguaje C++ 1.- Procesos de archivo: crear, abrir, guardar …. 2.- Procesos de edición: copiar, cortar, pegar…. 3.- Realizar búsquedas por diferentes criterios en un texto de programa 4.- Opciones para ejecutar los programas 5.- Opciones para compilar los programas (una a de las más importantes) 6.- Parámetros para depurar programas 7.- Opciones necesarias para crear proyectos desde cero 8.- Permite configurar todo el entorno e inclusive opciones de trabajo en modo 14 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO gráfico 9.- Mode de trabajo con ventanas independientes 10.- Ayuda de comandos, funciones con ejemplos 11.- Barra de menú 12.- Editor, espacio para escribir los programas 13.- Espacio donde aparecen ventanas de apoyo al programa 14.- Barra de ayudas y accesos rápidos 15.- Nombre del archivo que esta procesando Lección 3: Estructura general de un programa en Lenguaje C Un programa en c++ está constituido básicamente por: • • • • • Directivas del pre-procesador: [declaración de variables globales] [prototipos de funciones] Función main [definiciones de funciones] Directivas del Pre-procesador: en este se encuentra Los archivos de cabecera que permiten indicarle al compilador que se va a hacer uso de las funcionalidades que proporcionan ciertas bibliotecas (en este caso predefinidas). Por ejem plo para emplear la biblioteca de entrada/salida iostream s e d e b e incluir iostream.h. #include <iostream.h> Declaración de variables y constantes globales: las variables y constantes globales son aquellas cu yo valor afecta a todo el programa. Cabecera de funciones: se realiza una descripción a manera de prototipo de las funciones que se crearan más adelante. Función main(): todo programa escrito en c++ está constituido por funciones, y la función principal es main(). Definición de funciones: es necesario crear las funciones que se definieron 15 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO como prototipos para darle viabilidad al programa. Sentencias: cada una de las ordenes que se le da al compilador por medio del lenguaje para que efectué una acción. Lección 4: Definición de Compilador Un traductor es cualquier programa que toma como entrada un texto escrito en un lenguaje, llamado fuente y da como salida otro texto en un lenguaje, denominado objeto. En el caso de que el lenguaje fuente sea un lenguaje de programación de alto nivel y el objeto sea un lenguaje de bajo nivel (ensamblador o código de máquina), a dicho traductor se le denomina compilador. Un ensamblador es un compilador cuyo lenguaje fuente es el lenguaje ensamblador. Un intérprete no genera un programa equivalente, sino que toma una sentencia del programa fuente en un lenguaje de alto nivel y la traduce al código equivalente y al mismo tiempo lo ejecuta. Históricamente, con la escasez de memoria de los primeros ordenadores, se puso de moda el uso de intérpretes frente a los compiladores, pues el programa fuente sin traducir y el intérprete juntos daban una ocupación de memoria menor que la resultante de los compiladores. Por ello los primeros ordenadores personales iban siempre acompañados de un intérprete de BASIC (Spectrum, Commodore VIC-20, PC XT de IBM, etc.). La mejor información sobre los errores por parte del compilador así como una mayor velocidad de ejecución del código resultante hizo que poco a poco se impusieran los compiladores. Hoy en día, y con el problema de la memoria prácticamente resuelto, se puede hablar de un gran predominio de los compiladores frente a los intérpretes, aunque intérpretes como los incluidos en los navegadores de Internet para interpretar el código JVM de Java son la gran excepción. Ventajas de compilar frente a interpretar: • Se compila una vez, se ejecuta n veces. • En bucles, la compilación genera código equivalente al bucle, pero interpretándolo se traduce tantas veces una línea como veces se repite el bucle. • El compilador tiene una visión global del programa, por lo que la información de mensajes de error es mas detallada. Ventajas del intérprete frente al compilador: 16 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO • • Un intérprete necesita menos memoria que un compilador. En principio eran más abundantes dado que los ordenadores tenían poca memoria. Permiten una mayor interactividad con el código en tiempo de desarrollo. Un compilador no es un programa que funciona de manera aislada, sino que necesita de otros programas para conseguir su objetivo: obtener un programa ejecutable a partir de un programa fuente en un lenguaje de alto nivel. Algunos de esos programas son el preprocesador, el linker, el depurador y el ensamblador. El preprocesador se ocupa (dependiendo del lenguaje) de incluir ficheros, expandir macros, eliminar comentarios, y otras tareas similares. El linker se encarga de construir el fichero ejecutable añadiendo al fichero objeto generado por el compilador las cabeceras necesarias y las funciones de librería utilizadas por el programa fuente. El depurador permite, si el compilador ha generado adecuadamente el programa objeto, seguir paso a paso la ejecución de un programa. Finalmente, muchos compiladores, en vez de generar código objeto, generan un programa en lenguaje ensamblador que debe después convertirse en un ejecutable mediante un programa ensamblador. El compilador C ++ DIRECTIVA INCLUDE (Archivos con extensión h): Los archivos con extensión h (Ejemplo: stdio.h, conio.h etc) se llaman archivos de cabecera, contienen información técnica que requiere el compilador para la buena operación de las funciones que usan los programas. Un programa necesita directivas para incluir archivos, algunas de ellas son: #include <stdio.h> #include <conio.h> Los archivos con extensión h viene con el compilador. Pero también el programador pueden crear archivos propios, de este tipo. DIRECTIVA #define: (Definición de Macros) La directiva #define se utiliza para definir un identificador y una cadena que será sustituida cada vez que s e u t i l i c e el identificador se en el programa. Al identificador se le denomina nombre de la macro y al proceso de reemplazamiento sustitución de macro. 17 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO El siguiente programa está usando directivas para incluir (macro) constantes. Ejemplos: #define mensaje “El sistema no tiene Solución” Otro tipo de macro podría ser: #define CIERTO 1 #define FALSO 0 Una vez se define una macro se puede usar el nombre de ella como parte de la definición de otra, ejemplo: #define UNO 1 #define DOS #define TRES UNO + UNO UNO + DOS Declaración de Variables Antes del main() o después de él se deben definir las variables, ejemplo: float a, b, x; Las variables que se declaran dentro del main() se dice que son variables locales, las que se declaran fuera se dicen globales, cuando se analice el concepto de función se ampliará la diferencia entre estos tipos de variables. La siguiente tabla muestra los distintos tipos de dato que se pueden usar en C para declarar variables. TIPOS DE DATOS BÁSICOS RECONOCIDOS POR TURBO C TAMAÑO en RANGO de Valores que Bytes de la Variable Puede Almacenar Cuando Usamos 1 0..255 ‘Á’...’Z’, $ Para almacenar 2 -32767..32768 números enteros Para almacenar números Reales 8 1.7E-308..1.7E308 Variables que 4 3E-38..3E38 almacenan números reales. Punteros near, es, _es, ss Para variables que 2 byte guardan direcciones de memoria 10 bytes 3.4E-4932 a 1.1 E 4932 Variables Reales TIPO char int double float pointer long double TABLA 1: Tipos de datos básicos 18 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lección 5: Depuración de Programas La depuración p e rmit e determinar las causas de los errores y por tanto facilita la corrección de los mismos, en un programa determinado. El proceso de depuración 1. Estudio de los síntomas del error 2. Determinación de las causas 3. Corrección 4. Prueba. Pueden existir varias causas de error que se pueden agrupar en dos grandes grupos: 1.- Errores de sintaxis 2.- Errores lógicos: Para el primer caso, al momento de compilar el programa, este detecta los errores y es posible corregirlos, (ver Figura 2) Mirar anexo referente a errores comunes de programación y algunas buenas prácticas de programación, propuesto por Miguel Á. Toledo Martínez1 19 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO FIGURA 2: Ventana de compilación Los errores lógicos son más difíciles de corregir, pues el compilador no los detecta. Un ejemplo válido se muestra al analizar un programa para el pago de la nómina de 500 empleados, se produce una equivocación a la hora de hacer la fórmula de los descuentos, en lugar de realizar la resta se hace una suma. Como se puede ver en este ejemplo es un error muy grave, pero de análisis y no de sintaxis, por lo tanto el programa no lo detectará. Por lo tanto es indispensable realizar una buena interpretación del problema para desarrollar el diseño y codificación del programa. 20 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 2: FUNCIONES Introducción La forma más razonable de encarar el desarrollo de un programa complicado es aplicar lo que se ha dado en llamar "Programación Top-Down". Esto implica que, luego de conocer cual es la meta a alcanzar, se subdivide esta en otras varias tareas concurrentes, por ejemplo: Leer un teclado, procesar datos, mostrar los resultados. Luego a estas se las vuelve a dividir en otras menores: Y así se continúa hasta llegar a tener un gran conjunto de pequeñas y simples tareas, del tipo de "leer una tecla" ó "imprimir un caracter". Luego sólo resta abocarse a resolver cada una de ellas por separado. De esta forma el programador, sólo se las tendrá que ver con diminutas piezas de programa, de pocas líneas, cuya escritura y corrección posterior es una tarea simple. Tal es el criterio con que está estructurado el lenguaje C, donde una de sus herramientas fundamentales son las funciones. Todo compilador comercial trae una gran cantidad de Librerías de toda índole, matemáticas, de entrada salida, de manejo de textos, de manejo de gráficos, etc, que solucionan la mayor parte de los problemas básicos de programación. Sin embargo será inevitable que en algún momento tenga que crear mis propias funciones, las reglas para ello son las que desarrollaremos en este capítulo. Comencemos con algunos conceptos básicos: para hacer que las instrucciones contenidas en una función, se ejecuten en determinado momento, no es necesario más que escribir su nombre como una línea de sentencia en mi programa. Convencionalmente en C los nombres de las funciones se escriben en minúscula y siguen las reglas dadas anteriormente para los de las variables, pero deben ser seguidos, para diferenciarlas de aquellas por un par de paréntesis. Lección 6: Definición de una Función La definición de una función puede ubicarse en cualquier lugar del programa, con sólo dos restricciones: debe hallarse luego de dar su prototipo, y no puede estar dentro de la definición de otra función (incluida main() ). Es decir que a diferencia de Pascal, en C las definiciones no pueden anidarse. 21 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO NOTA: no confundir definición con llamada; una función puede llamar a tantas otras como desee. La definición debe comenzar con un encabezamiento, que debe coincidir totalmente con el prototipo declarado para la misma, y a continuación del mismo, encerradas por llaves se escribirán las sentencias que la componen; por ejemplo: #include <stdio.h> float mi_funcion(int i, double j ); /* DECLARACION observe que termina en ";" */ main() { float k ; int p ; double z ; ........... k = mi_funcion( p, z ); /* LLAMADA a la función */ ........... /* fin de la función main() */ } float mi_funcion(int i, double j ) /* DEFINICION observe que NO lleva ";" */ { float n ................... printf("%d", i ); /* LLAMADA a otra función */ ................... return ( 2 * n ); /* RETORNO devolviendo un valor float */ } Pasemos ahora a describir más puntualmente las distintas modalidades que adoptan las funciones. Lección 7: Declaración de una Función Antes de escribir una función es necesario informarle al Compilador los tamaños de los valores que se le enviarán en el stack y el tamaño de los valores que ella retornará al programa invocante. Estas informaciones están contenidas en la DECLARACION del PROTOTIPO DE LA FUNCION. Formalmente dicha declaración queda dada por: tipo del valor de retorno nombre_de_la_función(lista de tipos de parámetros) 22 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Algunos ejemplos : float mi_funcion(int i, double j ) ; double otra_funcion(void) ; otra_mas(long p) ; void la_ultima(long double z, char y, int x, unsigned long w) ; El primer término del prototipo da, como hemos visto el tipo del dato retornado por la función; en caso de obviarse el mismo se toma, por omisión, el tipo int. Sin embargo, aunque la función devuelva este tipo de dato, para evitar malas interpretaciones es conveniente explicitarlo. Ya que el "default" del tipo de retorno es el int, debemos indicar cuando la función NO retorna nada, esto se realiza por medio de la palabra VOID (sin valor). De la misma manera se actúa, cuando no se le enviarán argumentos. Más adelante se profundizará sobre el tema de los argumentos y sus características. La declaración debe anteceder en el programa a la definición de la función. Es normal, por razones de legibilidad de la documentación, encontrar todas las declaraciones de las funciones usadas en el programa, en el HEADER del mismo, junto con los include de los archivos *.h que tienen los prototipos de las funciones de Librería. Si una ó más de nuestras funciones es usada habitualmente, podemos disponer su prototipo en un archivo de texto, e incluirlo las veces que necesitemos, según se vio en capítulos previos. Lección 8: Llamados de Función Una vez que en su programa se ha definido una función, esta puede ser llamada las veces que sean necesarias. Para llamar a una función basta con hacer referencia a su nombre y si la misma requiere de parámetros estos deberán indicarse dentro de paréntesis. Para llamar a una función que no requiera de parámetros se deberá indicar el nombre de la misma seguida de paréntesis vacios. Por ejemplo, para llamar a la función cuadrado() vista anteriormente, podemos emplear: cout << cuadrado(25); cout << cuadrado(X); R = cuadrado(X); // guardar en R el cuadrado de X 23 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lección 9: Prototipos Para utilizar una función en un programa, se requiere en primer lugar declararla y después definirla. La declaración de la función le indica al compilador el nombre, el tipo de dato devuelto por la función y los parámetros pasados a la función. A la declaración de una función se le llama también el prototipo Un prototipo es una declaración de una función. Consistente simplemente en el encabezado de la función, terminado con punto y coma (;) lo que hace es avisar al compilador, como se va a llamar la función y si recibe y devuelve información La estructura de un prototipo es: <tipo> func(<lista de declaración de parámetros>); Ejemplo: int Mayor(int a, int b);// es un prototipo de función que devuelve un entero y recibe dos parámetros enteros. Aunque C++ permite realizar el prototipo de la siguiente manera: int Mayor(int,int); Sin necesidad de escribir el nombre de las variables; entonces La estructura de un programa en C++ quedaría así: [directivas del pre-procesador: includes y defines] [declaración de variables y constantes globales] [prototipos de funciones] [declaraciones de clases] función main () [definiciones de funciones]//definidas en los prototipos [definiciones de clases] Lección 10: Recursividad Esta es la propiedad que tienen las funciones en C++ de poder llamarse a sí mismas. Se dice que una función es recursiva cuando se autollama. No todas las funciones pueden llamarse a sí mismas (ser recursivas), deben estar diseñadas especialmente para que tengan un final y no se conviertan en ciclos o bucles infinitos. Es importante notar que cuando una función se llama a sí misma, una nueva copia de esta función es la que se ejecuta. Las variables locales de la segunda 24 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO función no interfieren con las variables locales de la primera, así mismo, las variables locales no se pueden afectar mutuamente. Tomemos como ejemplo un programa que calcule el factorial de un número entero introducido por el usuario. El factorial está definido como el producto del número en cuestión por todos los números enteros menores que él, de tal manera que el factorial de 5=5*4*3*2*1 = 120. El código puede quedar así: #include <iostream.h> double factorial(int valor); int K=1; // variable global, para un contador general int main() { int num; cout << "Introduzca un numero" << endl; cin >> num; cout << endl; cout << “El factorial del número es “ << factorial(num) << endl; cout << "La función se llamo en forma recursiva " << k << " veces" << endl; return 0; } double factorial(int valor) { double R; if(valor<=1) return 1; else { R= (valor*factorial(valor-1)); K = K+1; } return resultado; } 1.) la función se declara de tipo doble, puesto que los valores que retorna la función pueden ser demasiado grandes. 2.) También se utiliza una variable global (K), que sirve de contador, para determinar el número de iteraciones que la función se repite 3.) El programa empieza solicitándole un número entero y después llama por primera vez a la función factorial ( ). La recursividad necesita una condición para terminar el proceso en el momento especifico, por ésta razón, la función factorial () determina en primer lugar si el valor pasado como parámetro de la función es igual a 1, en cuyo caso la función retorna 1. Si el valor del parámetro es mayor que 1, entonces la función factorial ( ) se llama a sí misma tomando como parámetro el valor original menos uno, multiplicando 25 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO éste valor por el valor del parámetro original y almacenando el resultado en la variable llamada resultado. (se recomienda realizar una prueba de escritorio para entender un poco más el movimiento de la función y sus iteraciones) 26 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 3: APUNTADORES Introducción Los apuntadores son una parte fundamental de C. Si usted no puede usar los apuntadores apropiadamente entonces está perdiendo la potencia y la flexibilidad que C ofrece básicamente. El secreto para C esta en el uso de apuntadores. C usa los apuntadores en forma extensiva. ¿Porqué? • • • • Es la única forma de expresar algunos cálculos. Se genera código compacto y eficiente. Es una herramienta muy poderosa. C usa apuntadores explícitamente con: Arreglos, Estructuras y Funciones Lección 11: Declaración de Apuntador Apuntador: es una variable a la que se asigna una dirección de memoria. El apuntador debe definirse con el mismo tipo de la variable a la cual apunta. Ejemplo: si se define la variable llamada X, de tipo entero, el apuntador que contendrá su dirección debe ser de tipo entero, así: int X; \\ define la variable X de tipo entero int *px; \\ define un variable tipo puntero llamada px Definición de un apuntador: para diferenciar un apuntador de otra variable, al nombre del puntero se le antepone un asterisco (*) Ejemplo: int *px; Al definir un apuntador o puntero, este contiene una dirección que no indica una variable conocida, si se desea que contenga la dirección de una variable, esta se debe asignar. La sintaxis es: px=&x; con esta instrucción ahora se tiene almacenado en px la dirección de memoria donde se encuentra la variable x. A la variable x, se le debe asignar un valor, porque hasta el momento esta vacia. Esto se puede hacer de dos formas: X=10; ó *px = 10; 27 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Se debe tener claro que de acuerdo a las asignaciones que se realicen, se van a presentar diferencias en el contenido de las variables y los apuntadores. Ej. int x, *px; px = &x; \\ asigna a px la dirección de la variable x *px = 10; \\ asigna el valor 10 a la variable x, es lo mismo que decir x = 10. \\ Prácticamente la expresión *px es la variable x. Ejercicio: analizar el siguiente programa void main ( ) { int x, *px; px = &x; *px = 0; *px = *px + 5; x = *px – 1; printf ( “ %d %d “, x, *px ); getch ( ); } void main ( ) { int x, *px; px = &x; x = 0; x = x + 5; x = x – 1; printf ( “ %d %d “, x, *px ); getch ( ); } Situar un asterisco delante del nombre de una variable. char *ptr1; //puntero a un char "utilizado para las cadenas de longitud variable". int *ptr2; //puntero a un entero. float *ptr3; //putnero a un float int *p1, num1, num2, *p2; //punteros a enteros *p1, *p2 Recuperar dirección del puntero. Situar & delante de variable. Lección 12: Definición de un Apuntador Un apuntador es una variable que contiene la dirección en memoria de otra variable. Se pueden tener apuntadores a cualquier tipo de variable. El operador unario o monádico & devuelve la dirección de memoria de una variable. El operador de indirección o dereferencia * devuelve el ``contenido de un objeto apuntado por un apuntador''. Para declarar un apuntador para una variable entera hacer: int *apuntador; Se debe asociar a cada apuntador un tipo particular. Por ejemplo, no se puede asignar la dirección de un short int a un long int. 28 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Para tener una mejor idea, considerar el siguiente código: main() { int x = 1, y = 2; int *ap; ap = &x; y = *ap; x = ap; *ap = 3; } Cuando se compile el código se mostrará el siguiente mensaje: warning: assignment makes integer from pointer without a cast. Con el objetivo de entender el comportamiento del código supongamos que la variable x está en la localidad de la memoria 100, y en 200 y ap en 1000. Nota: un apuntador es una variable, por lo tanto, sus valores necesitan ser guardados en algún lado. int x = 1, y = 2; int *ap; ap = &x; 100 x 1 200 y 2 1000 ap 100 Las variables x e y son declaradas e inicializadas con 1 y 2 respectivamente, ap es declarado como un apuntador a entero y se le asigna la dirección de x (&x). Por lo que ap se carga con el valor 100. y = *ap; 100 x 1 200 y 1 1000 ap 100 Después y obtiene el contenido de ap. En el ejemplo ap apunta a la localidad de memoria 100 -- la localidad de x. Por lo tanto, y obtiene el valor de x -- el cual es 1. x = ap; 29 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 100 200 1000 ap 100 x 100 y 1 Como se ha visto C no es muy estricto en la asignación de valores de diferente tipo (apuntador a entero). Así que es perfectamente legal (aunque el compilador genera un aviso de cuidado) asigna el valor actual de ap a la variable x. El valor de ap en ese momento es 100. *ap = 3; 100 x 3 200 y 1 1000 ap 100 Finalmente se asigna un valor al contenido de un apuntador (*ap). Importante: Cuando un apuntador es declarado apunta a algún lado. Se debe inicializar el apuntador antes de usarlo. Por lo que: main() { int *ap; *ap = 100; } puede generar un error en tiempo de ejecución o presentar un comportamiento errático. El uso correcto será: main() { int *ap; int x; ap = &x; *ap = 100; } Con los apuntadores se puede realizar también aritmética entera, por ejemplo: main() { float *flp, *flq; 30 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO *flp = *flp + 10; ++*flp; (*flp)++; flq = flp; } NOTA: Un apuntador a cualquier tipo de variables es una dirección en memoria la cual es una dirección entera, pero un apuntador NO es un entero. La razón por la cual se asocia un apuntador a un tipo de dato, es porque se debe conocer en cuántos bytes está guardado el dato. De tal forma, que cuando se incrementa un apuntador, se incrementa el apuntador por un ``bloque'' de memoria, en donde el bloque está en función del tamaño del dato. Por lo tanto para un apuntador a un char, se agrega un byte a la dirección y para un apuntador a entero o a flotante se agregan 4 bytes. De esta forma si a un apuntador a flotante se le suman 2, el apuntador entonces se mueve dos posiciones float que equivalen a 8 bytes. Lección 13: Apuntadores y Funciones Cuando C pasa argumentos a funciones, los pasa por valor, es decir, si el parámetro es modificado dentro de la función, una vez que termina la función el valor pasado de la variable permanece inalterado. Hay muchos casos que se quiere alterar el argumento pasado a la función y recibir el nuevo valor una vez que la función ha terminado. Para hacer lo anterior se debe usar una llamada por referencia, en C se puede simular pasando un puntero al argumento. Con esto se provoca que la computadora pase la dirección del argumento a la función. Para entender mejor lo anterior consideremos la función swap() que intercambia el valor de dos argumentos enteros: void swap(int *px, int *py); main() { int x, y; x = 10; y = 20; printf("x=%d\ty=%d\n",x,y); swap(&x, &y); printf("x=%d\ty=%d\n",x,y); } 31 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO void swap(int *px, int *py) { int temp; temp = *px; /* guarda el valor de la direccion x */ *px = *py; /* pone y en x */ *py = temp; /* pone x en y */ } Lección 14: Apuntadores y Arreglos Existe una relación estrecha entre los punteros y los arreglos. En C, un nombre de un arreglo es un índice a la dirección de comienzo del arreglo. En esencia, el nombre de un arreglo es un puntero al arreglo. Considerar lo siguiente: int a[10], x; int *ap; ap = &a[0]; /* ap apunta a la dirección de a[0] */ /* A x se le asigna el contenido de ap (a[0] en este caso) */ x = *ap; *(ap + 1) = 100; /* Se asigna al segundo elemento de 'a' el valor 100 usando ap*/ Como se puede observar en el ejemplo la sentencia a[t] es idéntica a ap+t. Se debe tener cuidado ya que C no hace una revisión de los límites del arreglo, por lo que se puede ir fácilmente más allá del arreglo en memoria y sobreescribir otras cosas. C sin embargo es mucho más sutil en su relación entre arreglos y apuntadores. Por ejemplo se puede teclear solamente: ap = a; en vez de ap = &a[0]; y también *(a + i) en vez de a[i], esto es, &a[i] es equivalente con a+i. Y como se ve en el ejemplo, el direccionamiento de apuntadores se puede expresar como: a[i] que es equivalente a *(ap + i) Sin embargo los apuntadores y los arreglos son diferentes: Un apuntador es una variable. Se puede hacer ap = a y ap++. Un arreglo NO ES una variable. 32 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Hacer a = ap y a++ ES ILEGAL. NOTA: Esta parte es muy importante, asegúrese haberla entendido. Con lo comentado se puede entender como los arreglos son pasados a las funciones. Cuando un arreglo es pasado a una función lo que en realidad se le está pasando es la localidad de su elemento inicial en memoria. Por lo tanto: strlen(s) es equivalente a strlen(&s[0]) Esta es la razón por la cual se declara la función como: int strlen(char s[]); y una declaración equivalente es int strlen(char *s); ya que char s[] es igual que char *s. La función strlen() es una función de la biblioteca estándar que regresa la longitud de una cadena. Se muestra enseguida la versión de esta función que podría escribirse: int strlen(char *s) { char *p = s; while ( *p != '\0' ) p++; return p - s; } Se muestra enseguida una función para copiar una cadena en otra. Al igual que en el ejercicio anterior existe en la biblioteca estándar una función que hace lo mismo. void strcpy(char *s, char *t) { while ( (*s++ = *t++) != '\0' ); } En los dos últimos ejemplos se emplean apuntadores y asignación por valor. Nota: Se emplea el uso del carácter nulo con la sentencia while para encontrar el fin de la cadena. Lección 15: Ejercicios 1. Escribir el programa que ordena las líneas de un texto leído desde la entrada estándar, donde cada línea tiene diferente longitud, según lo descrito en la sección de arreglo de apuntadores. 33 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 2. Escribir una función que convierta una cadena s a un número de punto flotante usando apuntadores. Considerar que el número tiene el siguiente formato 99999999.999999, es decir, no se dará en notación científica. La función deberá suministrársele una cadena y deberá devolver un número. 3. Escribir un programa que encuentre el número de veces que una palabra dada (esto es, una cadena corta) ocurre en una sentencia (una cadena larga). Leer los datos de la entrada estándar. La primera línea es una sola palabra, en la segunda línea se tiene un texto general. Leer ambas hasta encontrar un carácter de nueva línea. Recordar que se debe insertar un carácter nulo antes de procesar. La salida típica podría ser: La palabra es "el" La sentencia es "el perro, el gato y el canario" La palabra ocurrio 3 veces. 34 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ACTIVIDADES DE AUTOEVALUACION DE LA UNIDAD 1 Existe un ejercicio clásico, la intencionalidad no es transcribirlo, es leer los enunciados y desarrollarlo utilizando funciones recursivas, se trata de las torres de Hanoi La Leyenda: En una ciudad antigua en la India, los monjes de un templo tienen que mover una pila de 64 discos sagrados a partir de una localización a otra. Los discos son frágiles; solamente uno se puede llevar al mismo tiempo. Un disco no se puede colocar encima de un disco más pequeño, menos valioso. Y, hay solamente otra localización en el templo (además de la original y de la localización de destino) bastante sagrada y solo una pila de discos se puede colocar allí. Así pues, los monjes comienzan a mover discos hacia adelante y hacia atrás, entre la pila original, la pila en la nueva localización, y la localización intermedia, manteniendo siempre el orden (más grande en el fondo, más pequeño en la tapa). La leyenda consiste en que, antes de que los monjes hagan el movimiento final de terminar la pila nueva en la nueva localización, el templo se convertirá en polvo y el mundo terminará. Tú qué crees? .........Bueno dejémonos de leyendas y vamos a lo que vamos....... El "Juego" torres de Hanoi consiste en tres palos, en el cual el primer palo tiene N número de argollas colocadas de tal manera que las más grandes siempre deben estar por debajo de las más pequeñas...el segundo palo le podremos llamar palo auxiliar y es el que nos ayudará de cierta manera a lograr el desarrollo del juego el cual será lograr pasar todas las argollas al tercer palo de tal manera que se mueve una argolla a la vez y que nunca una argolla grande quede encima de una pequeña … FIGURA 3. Torres de Hanoi 35 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO UNIDAD 2 Nombre de la Unidad Introducción ARREGLOS En clase ya conocimos algunos tipos básicos como por ejemplo los tipos char, int y float. El lenguaje C++ permite, además, construir estructuras más complejas a partir de estos tipos básicos. Una de las construcciones que podemos definir son los arreglos. Arreglo: Colección ordenada de elementos de un mismo tipo. Ordenada significa que cada elemento tiene una ubicación determinada dentro del arreglo y debemos conocerla para accederlo. Justificación Esta unidad nos permite afrentarnos un poco en el mundo de los datos estructurados, para tal efecto iniciaremos con los datos mas sencillos como son los arreglos unidimensionales, realizando ejemplos de diferente tipo, y se presentará una vez se tenga dominio sobre este tema, abordaremos un tipo especial de arreglos unidimensionales como son las cadenas de caracteres, para seguir con los arreglos bidimensionales o matices, se nombraran simplemente los arreglos multidimencionales, y se espera que el estudiante profundice mas sobre este tema, también se profundiza sobre las operaciones fundamentales que se hacen con los arreglos como los son la ordenación y la búsqueda, para lo cual se revisarán diversidad de algoritmos que dan solución a estos temas, al finalizar cada tema se propondrá una serie de ejercicios que le permitan al estudiante realizar una auto evaluación de lo aprendido, lo mismo que interactuar con los compañeros del pequeño grupo colaborativo. Conceptuar referente a estructuras de datos que manipulan volumen mayor de información Propósitos de la unidad Conocer el trabajo que se realiza con vectores, arreglos y cadenas de caracteres Realizar búsquedas y ordenamientos utilizando algoritmos diseñados para tal fin Objetivos de la unidad Tener claridad en la importancia que tienen los vectores, los arreglos y las cadenas de caracteres Tener claridad en los criterios de búsqueda y ordenamiento Competencias de la unidad Dominar las tecnicas de búsqueda y ordenamiento aplicado a estructuras básicas de la programación El estudiante aplica los vectores y arreglos como herramienta fundamental en la programación de computadoras Intencionalidades Formativas 36 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Metas de aprendizaje Realizar programas con un alto grado de complejidad Denominación de capítulos Arreglos y Cadenas Ordenación Búsqueda 37 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 4: ARREGLOS Y CADENAS Introducción Esta unidad nos permite prepararnos un poco en el mundo de los datos estructurados, para tal efecto iniciaremos con los datos más sencillos como son los arreglos unidimensionales, realizando ejemplos de diferente tipo, y se presentará una vez se tenga dominio sobre este tema, abordaremos un tipo especial de arreglos unidimensionales como son las cadenas de caracteres, para seguir con los arreglos bidimensionales o matices, se nombraran simplemente los arreglos multidimencionales, y se espera que el estudiante profundice mas sobre este tema, también se profundiza sobre las operaciones fundamentales que se hacen con los arreglos como los son la ordenación y la búsqueda, para lo cual se revisarán diversidad de algoritmos que dan solución a estos temas, al finalizar cada tema se propondrá una serie de ejercicios que le permitan al estudiante realizar una auto evaluación de lo aprendido, lo mismo que interactuar con los compañeros del pequeño grupo colaborativo. Lección 16: Definición y Declaración Los arreglos son una colección de variables del mismo tipo que se referencian utilizando un nombre común. Un arreglo consta de posiciones de memoria contigua. La dirección más baja corresponde al primer elemento y la más alta al último. Un arreglo puede tener una o varias dimensiones. Para acceder a un elemento en particular de un arreglo se usa un índice. El formato para declarar un arreglo unidimensional es: tipo nombre_arr [ tamaño ] Por ejemplo, para declarar un arreglo de enteros llamado listanum con diez elementos se hace de la siguiente forma: int listanum[10]; En C, todos los arreglos usan cero como índice para el primer elemento. Por tanto, el ejemplo anterior declara un arreglo de enteros con diez elementos desde listanum[0] hasta listanum[9]. La forma como pueden ser accesados los elementos de un arreglo, es de la siguiente forma: 38 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO listanum[2] = 15; /* Asigna 15 al 3er elemento del arreglo listanum*/ num = listanum[2]; /* Asigna el contenido del 3er elemento a la variable num */ El lenguaje C no realiza comprobación de contornos en los arreglos. En el caso de que sobrepase el final durante una operación de asignación, entonces se asignarán valores a otra variable o a un trozo del código, esto es, si se dimensiona un arreglo de tamaño N, se puede referenciar el arreglo por encima de N sin provocar ningún mensaje de error en tiempo de compilación o ejecución, incluso aunque probablemente se provoque el fallo del programa. Como programador se es responsable de asegurar que todos los arreglos sean lo suficientemente grandes para guardar lo que pondrá en ellos el programa. C permite arreglos con más de una dimensión , el formato general es: tipo nombre_arr [ tam1 ][ tam2 ] ... [ tamN]; Por ejemplo un arreglo de enteros bidimensionales se escribirá como: int tabladenums[50][50]; Observar que para declarar cada dimensión lleva sus propios paréntesis cuadrados. Para acceder los elementos se procede de forma similar al ejemplo del arreglo unidimensional, esto es, tabladenums[2][3] = 15; /* Asigna 15 al elemento de la 3ª fila y la 4ª columna*/ num = tabladenums[25][16]; A continuación se muestra un ejemplo que asigna al primer elemento de un arreglo bidimensional cero, al siguiente 1, y así sucesivamente. main() { int t,i,num[3][4]; for(t=0; t<3; ++t) for(i=0; i<4; ++i) num[t][i]=(t*4)+i*1; for(t=0; t<3; ++t) { for(i=0; i<4; ++i) 39 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO printf("num[%d][%d]=%d ", t,i,num[t][i]); printf("\n"); } } En C se permite la inicialización de arreglos, debiendo seguir el siguiente formato: tipo nombre_arr[ tam1 ][ tam2 ] ... [ tamN] = {lista-valores}; Por ejemplo: int i[10] = {1,2,3,4,5,6,7,8,9,10}; int num[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; Lección 17: Arreglos Unidimensionales int vector[X]; Unidimensional de tipo entero. El índice se representaría de forma grafica tal y como lo veis en la figura de mas abajo. Como podéis observar solo necesitamos de un índice (x) para acceder a cada elemento de la “lista”. Por ejemplo si quisiera rellenar la casilla 4 dándole el valor 10, solo tendría que poner: vector[4]=10; FIGURA 4. Vector También son llamados arrays unidimensionales y lo podríamos definir como un conjunto de variables del mimo tipo y tamaño que ocupan posiciones consecutivas en la memoria del ordenador. El tamaño en memoria que ocupa un array es siempre fijo y no puede variar. Para calcular el tamaño en memoria que puede ocuparnos un array solo tenemos que multiplicar el número de elementos denuestro array por el tamaño en bytes del tipo de este. Es decir aplicaremos la siguiente fórmula: bytes totales = sizeof(tipo base) * número de elementos Cuando un array se pasa como argumento de una función, no se pasa una copia completa del array, sino solo la dirección del primer elemento del array. 40 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Para hacer referencia a la dirección de inicio de un array podemos utilizar cualquiera de estas dos formas (siendo más habitual la segunda) Int *P, *Q; P=&array[0]; /* Apunta al inicio del array, posición “0” */ Q=array; /* Realiza la misma función que la línea de código anterior */ Ejemplo del uso de un vector: #include <stdio.h> #include <conio.h> main() { int vector[7]; /* tipo nombre_del_array[Tamaño] */ /* Contador */ int c; for(c=0;c<=6;c++) { printf("Numero para guardar en vector[%d]: ",c); scanf("%d",&vector[c]); } for(c=0;c<=6;c++) { printf("\nValor Vector[%d]=%d",c,vector[c]); } getch(); } Las principales operaciones que se realizan con un array son: - Acceso: cada elemento de un array se nombra con el identificador del array al que perteneces seguido de su posición entre corchetes [n-1]. Es decir, si en un array[10], queremos nombrar la 4 posición, esta sería array[3]. - Asignación: normalmente para asignar valores a un array utilizamos un bucle for. El ejemplo anterior nos muestra perfectamente el comportamiento y la funcionalidad de este bucle. El índice del for ha de ser capaz de recorrer todas las casillas del array. - Iniciación: a un array le podemos dar valores iniciales, para ello se declararía de la siguiente forma: 41 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO (Donde lista de valores es una lista de constante separadas por comas) Tipo nombre_array[tamaño]={lista_valores}; int lista[6]={2,4,6,8,1,5}; int datos[100]={0}; int num[4]={4,5}; // todos se inicializan a 0 // equivale a {4,5,0,0} Es muy importante que se inicialicen los arrays antes de usarlos, ya que la declaración sólo reserva espacio en memoria para el array declarado, sin asignación por defecto por parte del sistema. Lección 18: Arreglos Bidimensionales Se conocen también como MATRICES. Son arreglos de dos dimensiones que utilizan dos índices para indicar la posición de cada elemento, el primero indica el número de la fila y el segundo el número de la columna (los índices inician en 0). Ejemplo de una matriz de 3 filas y 5 columnas, que contiene datos de tipo carácter char matriz[3][5] 0 1 2 3 4 índice de columnas 0 índice de filas 1 2 a e b f c g d h e i j k l m n FIGURA 5. Matríz El carácter g se encuentra en matriz [1][2] Ejemplo: #include <stdio.h> #include <conio.h> main() { char matriz[7][7]; /* Declaramos una matriz de 7*7 caracteres */ int c,d; /* Contadores */ for(c=0;c<=6;c++) { 42 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO for(d=0;d<=6;d++) { printf("Caracter para guardar en matriz[%d][%d]: ",c,d); scanf("%c",&matriz[c][d]); getchar(); } } for(c=0;c<=6;c++) { for(d=0;d<=6;d++) { printf("\nValor matriz[%d][%d]=%c",c,d,matriz[c][d]); } } getch(); } Lección 19: Cadenas de Carácter A diferencia de otros lenguajes de programación que emplean un tipo denominado cadena string para manipular un conjunto de simbolos, en C, se debe simular mediante un arreglo de caracteres, en donde la terminación de la cadena se debe indicar con nulo. Un nulo se especifica como '\0'. Por lo anterior, cuando se declare un arreglo de caracteres se debe considerar un carácter adicional a la cadena más larga que se vaya a guardar. Por ejemplo, si se quiere declarar un arreglo cadena que guarde una cadena de diez caracteres, se hará como: char cadena[11]; Se pueden hacer también inicializaciones de arreglos de caracteres en donde automáticamente C asigna el caracter nulo al final de la cadena, de la siguiente forma: char nombre_arr[ tam ]="cadena"; Por ejemplo, el siguiente fragmento inicializa cadena con ``hola'': char cadena[5]="hola"; El código anterior es equivalente a: char cadena[5]={'h','o','l','a','\0'}; 43 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Para asignar la entrada estándar a una cadena se puede usar la función scanf con la opción %s(observar que no se requiere usar el operador &), de igual forma para mostrarlo en la salida estándar. Por ejemplo: main() { char nombre[15], apellidos[30]; printf("Introduce tu nombre: "); scanf("%s",nombre); printf("Introduce tus apellidos: "); scanf("%s",apellidos); printf("Usted es %s %s\n",nombre,apellidos); } El lenguaje C no maneja cadenas de caracteres, como se hace con enteros o flotantes, por lo que lo siguiente no es válido: main() { char nombre[40], apellidos[40], completo[80]; nombre="José María"; /* Ilegal */ apellidos="Morelos y Pavón"; /* Ilegal */ completo="Gral."+nombre+appellidos; /* Ilegal */ } Lección 20: Ejercicios 1. Escribir un programa que lea un arreglo de cualquier tipo (entero, flotante, char), se podría pedir al usuario que indique el tipo de arreglo, y también escribir un programa que revise el arreglo para encontrar un valor en particular. 2. Leer un texto, un caracter a la vez desde la entrada estándar (que es el teclado), e imprimir cada línea en forma invertida. Leer hasta que se encuentre un final- de-datos (teclar CONTROL-D para generarlo). El programa podría probarse tecleando progrev | progrev para ver si una copia exacta de la entrada original es recreada. Para leer caracteres hasta el final de datos, se puede usar un ciclo como el siguiente char ch; while( ch=getchar(), ch>=0 ) /* ch < 0 indica fin-de-datos */ 44 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO o char ch; while( scanf( "%c", &ch ) == 1 ) /* se lee un caracter */ 3. Escribir un programa para leer un texto hasta el fin-de-datos, y mostrar una estadística de las longitudes de las palabras, esto es, el número total de palabras de longitud 1 que hayan ocurrido, el total de longitud 2 y así sucesivamente. Define una palabra como una secuencia de caracteres alfabéticos. Se deberán permitir palabras hasta de una longitud de 25 letras. Una salida típica podría ser como esta: longitud 1 : 16 ocurrencias longitud 2 : 20 ocurrencias longitud 3 : 5 ocurrencias longitud 4 : 2 ocurrencias longitud 5 : 0 ocurrencias ........ 45 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 5: ORDENACION Introducción El ordenamiento es una labor común que realizamos cotidianamente, es un proceso tan común en nuestras vidas que no nos detenemos a meditar mucho en ello. Ordenar es meramente colocar información de una manera especial basándonos en un criterio de ordenamiento. En la ciencia de la computación el ordenamiento de datos también cumple un rol muy importante, ya sea como un fin en sí o como parte de otros procedimientos más complejos. Se han desarrollado muchas técnicas en este ámbito, cada una con características específicas, y con ventajas y desventajas sobre las demás. El propósito principal de un ordenamiento es el de facilitar la búsqueda de información. El ordenar un grupo de datos significa mover los datos o sus referencias para que queden en una secuencia tal que represente un orden, el cual puede ser numérico, alfabético o incluso alfanumérico, ascendente o descendente. Lección 21: Definición y Declaración La ordenación o clasificación de datos (sort, en inglés) es una operación consistente en disponer un conjunto —estructura— de datos en algún determinado orden con respecto a uno de los campos de elementos del conjunto. Por ejemplo, cada elemento del conjunto de datos de una guía telefónica tiene un campo nombre, un campo dirección y un campo número de teléfono; la guía telefónica está dispuesta en orden alfabético de nombres; los elementos numéricos se pueden ordenar en orden creciente o decreciente de acuerdo al valor numérico del elemento. En terminología de ordenación, el elemento por el cual está ordenado un conjunto de datos (o se está buscando) se denomina clave. Una colección de datos (estructura) puede ser almacenada en un archivo, un array (vector o tabla), un array de registros, una lista enlazada o un árbol. Cuando los datos están almacenados en un array, una lista enlazada o un árbol, se denomina ordenación interna. Si los datos están almacenados en un archivo, el proceso de ordenación se llama ordenación externa. Una lista se dice que está ordenada por la clave k si la lista está en orden ascendente o descendente con respecto a esta clave. La lista se dice que está en orden ascendente si: i < j implica que k[i] <= k[j] y se dice que está en orden descendente si: i > j implica que k[i] <= k[j] para todos los elementos de 46 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO la lista. Por ejemplo, para una guía telefónica, la lista está clasificada en orden ascendente por el campo clave k, donde k[i] es el nombre del abonado (apellidos, nombre). 4 75 5 70 14 35 21 16 32 14 45 12 orden ascendente orden descendente orden descendente Zacarias Rodriguez Martinez Lopez Garcia Los métodos (algoritmos) de ordenación son numerosos, por ello se debe prestar especial atención en su elección. ¿Cómo se sabe cuál es el mejor algoritmo? La eficiencia es el factor que mide la calidad y rendimiento de un algoritmo. En el caso de la operación de ordenación, dos criterios se suelen seguir a la hora de decidir qué algoritmo —de entre los que resuelven la ordenación— es el más eficiente: 1) tiempo menor de ejecución en computadora; 2) menor número de instrucciones. Sin embargo, no siempre es fácil efectuar estas medidas: puede no disponerse de instrucciones para medida de tiempo —aunque no sea éste el caso del lenguaje C—, y las instrucciones pueden variar, dependiendo del lenguaje y del propio estilo del programador. Por esta razón, el mejor criterio para medir la eficiencia de un algoritmo es aislar una operación específica clave en la ordenación y contar el número de veces que se realiza. Así, en el caso de los algoritmos de ordenación, se utilizará como medida de su eficiencia el número de comparaciones entre elementos efectuados. El algoritmo de ordenación A será más eficiente que el B, si requiere menor número de comparaciones. Así, en el caso de ordenar los elementos de un vector, el número de comparaciones será función del número de elementos (n) del vector (array). Por consiguiente, se puede expresar el número de comparaciones en términos de n (por ejemplo, n+4, o bien n2 en lugar de números enteros. Se utiliza el orden ascendente sobre vectores o listas (arrays unidimensionales). Los métodos de ordenación se suelen dividir en dos grandes grupos: directos burbuja, selección, inserción indirectos (avanzados) Shell, ordenación rápida, ordenación por mezcla, Radixsort En el caso de listas pequeñas, los métodos directos se muestran eficientes, sobre todo porque los algoritmos son sencillos; su uso es muy frecuente. Sin embargo, en listas grandes estos métodos se muestran ineficaces y es preciso recurrir a los métodos avanzados. 47 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lección 22: Burbuja El Ordenamiento de Burbuja (Bubble Sort en inglés) es un sencillo algoritmo de ordenamiento. Funciona revisando cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos de posición si están en el orden equivocado. Es necesario revisar varias veces toda la lista hasta que no se necesiten más intercambios, lo cual significa que la lista está ordenada. Este algoritmo obtiene su nombre de la forma con la que suben por la lista los elementos durante los intercambios, como si fueran pequeñas "burbujas". También es conocido como el método del intercambio directo. Dado que solo usa comparaciones para operar elementos, se lo considera un algoritmo de comparación, siendo el más sencillo de implementar. Este es el método más fácil de utilizar y aprender, también se lo conoce como ordenamiento directo o de intercambio, consiste en: que va comparando cada elemento del arreglo con el siguiente; si un elemento es mayor que el que le sigue, entonces se intercambian (dependiendo si queremos ordenar ascendente o descendentemente); esto producirá que en el arreglo quede como su último elemento, el más grande. Este proceso deberá repetirse recorriendo todo el arreglo hasta que no ocurra ningún intercambio. Los elementos que van quedando ordenados ya no se comparan, los pasos son: Los pasos a dar son: 1. se decide como se quiere el resultado del ordenamiento, si ascendente o descendente 2. Comparar A[1] y A[2]; Si están en orden, se mantienen como están; en caso contrario, se intercambian entres sí. 3. A continuación se comparan los elementos 2 y 3; de nuevo se intercambian si es necesario. 4. El proceso continúa hasta que cada elemento del vector ha sido comparado con sus elementos adyacentes y se han realizado los intercambios necesarios. Este será el algoritmo Para i =1 hasta n haga si elemento[i] > elemento [i+1] haga Temporal = Elemento[i] Elemento[i] = Elemento [i+1] Elemento [i+1] = Temporal fin si fin para 48 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Para poder realizar este intercambio nos apoyamos en una variable temporal que permite almacenar uno de los valores por un periodo, para que no se pierda. Ahora miremos el código #include <stdio.h> #include <conio.h> #include <iostream.h> // Prototipos de las funciones. void MostrarVector(int *arreglo, int n); void burbuja(int *arreglo, int n); void main(void) { int n; // Numero de elementos del vector int i; // Contador int arreglo[100]; // Arreglo de enteros clrscr(); cout<<"Digite el numero de elementos < 100:"; cin>>n; for (i=0;i<n;i++) { cout<<"Digite valor para la posición :"<< i+1<<" "; cin>>arreglo[i]; } cout<<"\nVector Leido:\n"; MostrarVector(arreglo,n); cout<<"\nProcesamiento Burbuja:\n"; burbuja(arreglo, n); cout<<"\nVector Ordenado:\n"; MostrarVector(arreglo,n); getch(); } // Muestra en pantalla el vector void MostrarVector(int *arreglo, int n) { int i; // Contador for (i=0;i<n;i++) cout<<arreglo[i]; cout<<"\n"; } 49 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO // Ordenamiento por burbuja. void burbuja(int *arreglo, int n) { int i,j; // Contadores int temporal; // Variable para intercambio de contenidos for (i=0;i<n-1;i++) for (j=0;j<n-1;j++) if (arreglo[j]>arreglo[j+1]) { temporal=arreglo[j]; arreglo[j]=arreglo[j+1]; arreglo[j+1]=temporal; } } Esta es nuestra lista: 4-3-5-2-1 Tenemos 5 elementos. Es decir, n toma el valor 5. Comenzamos comparando el primero con el segundo elemento. 4 es mayor que 3, así que intercambiamos. Ahora tenemos: 3-4-5-2-1 Ahora comparamos el segundo con el tercero: 4 es menor que 5, así que no hacemos nada. Continuamos con el tercero y el cuarto: 5 es mayor que 2. Intercambiamos y obtenemos: 3-4-2-5-1 Comparamos el cuarto y Intercambiamos nuevamente: 3-4-2-1-5 Repitiendo este proceso vamos obteniendo los siguientes resultados: 3-2-1-4-5 2-1-3-4-5 1-2-3-4-5 50 el quinto: 5 es mayor que 1. UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Nuevamente se sugiere la realización de nuevas pruebas de escritorio para entender mejor el comportamiento de este programa. También existen formas de mejorar la efectividad de este algoritmo, se le sugiere tratar de implementar soluciones que mejoren los procesos en este algoritmo Lección 23: Inserción En este tipo de algoritmo los elementos que van a ser ordenados son considerados uno a la vez. Cada elemento es INSERTADO en la posición apropiada con respecto al resto de los elementos ya ordenados. Así por ejemplo, si tenemos el vector 53 15 27 31 29 11 59 7 Podemos insertar el elemento 15 en la posición 1 y mover el 53 a la posición 2, con lo que tendríamos los dos primeros elementos ordenados, como se aprecia en el ¡Error! No se encuentra el origen de la referencia.. 15 53 27 31 29 11 59 7 Repitiendo el proceso anterior pero con la casilla 3, se puede observar que la sublista a la izquierda esta ordenada y los movimientos serían los que se aprecian en el ¡Error! No se encuentra el origen de la referencia.. 15 53 27 31 29 11 59 7 Como resultado: 15 27 53 31 29 11 59 7 Como se puede observar el método se basa en comparaciones y desplazamientos sucesivos. El algoritmo de ordenación de un vector X para N elementos se realiza recorriendo el vector e insertando el elemento correspondiente en el lugar adecuado. De esto tenemos que el siguiente 51 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO pseudocódigo nos da una idea general de la labor a realizar: para i =2 hasta i = n haga Inserte X[i] en la posición adecuada entre X[1] y X[i-1] fin para El desarrollo de está operación de inserción se puede realizar en dos partes principales. La primera determinar en que lugar debe ir el elemento que se está evaluando. lugar = i temporal = X[i] para j =1 hasta j = i - 1 haga si temporal < X[j] haga lugar = j salir para fin si fin para La segunda, empieza con preguntar si se debe mover el elemento y si es así se corren hacia la derecha del lugar de inserción, los elementos así: si lugar < i haga para j = i – 1 hasta j = lugar en decrementos de 1 haga X[j+1] = X[j] fin para X[lugar] = temporal fin si De esta forma el pseudocódigo final queda de la siguiente manera: para i =2 hasta i = n haga lugar = i temporal = X[i] para j =1 hasta j = i - 1 haga si temporal < X[j] haga lugar = j salir para fin si fin para si lugar < i haga para j = i – 1 hasta j = lugar en decrementos de 1 haga X[j+1] = X[j] fin para X[lugar] = temporal 52 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO fin si fin para veamos el comportamiento del código #include <stdio.h> #include <conio.h> #include <iostream.h> #define MAXNUM 100 // Prototipos de las funciones. void MostrarVector(int *arreglo, int n); void insercion(int *arreglo, int n); void main(void) { int n; // numero de elementos del vector int i; // Contador int arreglo[100]; // Arreglo de enteros clrscr(); cout<<"Digite el numero de elementos:"; cin>>n; for (i=0;i<n;i++) { cout<<"por favor escriba el valor en la posicion :" <<i+1; cin>>arreglo[i]; } cout<<"\nVector Leido:\n"; MostrarVector(arreglo,n); cout<<"\nOrdenamiento por inserción:\n"; insercion(arreglo, n); cout<<"\nVector Ordenado:\n"; MostrarVector(arreglo,n); getch(); } // función para mostrar por pantalla void MostrarVector(int *arreglo, int n) { int i; // Contador for (i=0;i<n;i++) cout<< arreglo[i]; cout<<"\n"; } 53 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO // función que realiza el ordenamiento void insercion(int *arreglo, int n) { int i,j; // Contadores int temporal; // Variable que conserva el elemento X[i] int lugar; // Variable del lugar donde se debe insertar for (i=1;i<n;i++) { lugar=i; temporal= arreglo[i]; for (j=0;j<=i-1;j++) { if (temporal<arreglo[j]) { lugar=j; break; } } if (lugar<i) { for (j=i-1;j>=lugar;j--) arreglo[j+1]=arreglo[j]; arreglo[lugar]=temporal; } } } Lección 24: Shell Toma este nombre de su inventor Donald Shell, es como utilizar el ordenamiento burbuja pero comparando e intercambiando los elementos. La idea es seleccionar fragmentos de un arreglo para ser ordenados y ordenarlos por el método directo. Luego se cogen nuevos fragmentos hasta quedar ordenado por completo El algoritmo será: salto = n div 2 mientras salto <> 0 haga repita cambios = 0 para i N1 hasta n – salto haga 54 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO si X[i] > X[i+salto] haga temporal = X[i] X[i] = X[i+salto] X[i+salto] = temporal cambios = 1 fin si fin para hasta que cambios = 0 salto = saldo div 2 fin mientras Es momento de realizar la prueba de escritorio, consideremos el siguiente vector: 4 10 9 3 7 2 1 9 Decidimos ordenarlo en forma ascendente: Salto = 4 y es <> 0 Cambio = 0 I=1 4 10 9 3 7 2 1 9 Como la condición no se cumple 4 no es mayor que siete, se incremente i y continúa el proceso Variable i = 2 4 10 9 3 7 2 1 9 Como podemos observar el número 10 si es mayor que el 2 por lo tanto hay un intercambio y el vector resultante es: 4 10 9 3 7 2 1 9 La variable cambio toma el valor de 1, el proceso continua hasta que i llega a n- salto, para el primer caso hasta 4, luego se divide nuevamente en 2 y luego en uno. Ahora miremos el código #include <stdio.h> #include <conio.h> #include <iostream.h> 55 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO // Prototipos de las funciones. void MostrarVector(int *arreglo, int n); int shell(int *arreglo, int n); void main(void) { int n; // El numero de elementos del vector int i; // Contador int arreglo[100]; // Arreglo de enteros clrscr(); cout<<"Digite el numero de elementos < 100:"; cin>>n; for (i=0;i<n;i++) { cout<<"digite valor para ["<<i+1<<"] "; cin>>arreglo[i]; } cout<<"\nVector Leido:\n"; MostrarVector(arreglo,n); cout<<"\nOrdenamiento por shell:\n"; cout<<"\n Numero iterciones" <<shell(arreglo, n); cout<<"\nVector Ordenado:\n"; MostrarVector(arreglo,n); getch(); } // Muestra en pantalla el vector void MostrarVector(int *arreglo, int n) { int i; // Contador for (i=0;i<n;i++) cout<< arreglo[i]<<" "; cout<<"\n"; } // Ordenamiento por shell. int shell(int *arreglo, int n) { int ciclos=0; // Contador de ciclos i nt i; // Contador int salto; // Variable para el tamaño del salto 56 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO int temporal; // Variable para intercambio de contenidos int cambio; // Variable lógica para detener una iteración salto=n/2; while (salto!=0) { do { cambio=0; for(i=0;i<n-salto;i++) { ciclos++; if(arreglo[i]>arreglo[i+salto]) { temporal=arreglo[i]; arreglo[i]=arreglo[i+salto]; arreglo[i+salto]=temporal; cambio=1; } } } while (cambio!=0); salto=salto/2; } return ciclos; } Lección 25: Quicksort Algoritmo desarrollado por Charles Hoare propuesto en 1962. Este es el método de ordenamiento, que trae a mi mente viejos recuerdos, pues gracias a una exposición magistral de este método, me gane un cinco que necesitaba para pasar el curso de algoritmos en la U donde estudiaba, por el año de 1989 (hace rato.). Bueno dejemos los sentimentalismos con los algoritmos y al grano, es un método de ordenamiento, muy eficiente, a pesar de que han salido variaciones del mismo. El algoritmo consiste en: Proceso interativo. Para cada paso, se escoge un elemento "a" de alguna posición específica dentro del arreglo. Ese elemento "a" es el que se procederá a colocar en el lugar que le corresponda. Por conveniencia se seleccionará a "a" como el primer elemento del arreglo. El elemento "a" se procede a comparar con el resto de los elementos del arreglo. Una forma puede ser: comparar "a" con el último elemento del arreglo. En la comparación, si el elemento "a" toma la ultima posición y el último elemento 57 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO toma la posición 1 se procede a seguir comparando a "a" pero ahora con el segundo elemento. Si "a" resulta ser menor que el segundo elemento se hace el intercambio y se procede a comparar "a" con el penúltimo y así sucesivamente hasta que "a" se compara con todos los elementos restantes del arreglo. Note que cada vez que ocurre un intercambio de valores, la comparación de "a" se hace con los elementos del arreglo que se encuentran en posición contraria a la que se está haciendo. Una vez que se terminó de comparar "a" con todos los elementos, "a" ya se encuentra en su lugar y a la izquierda de "a" quedan todos los elementos menores a él y a su derecha todos los mayores. Se toma el sub-arreglo izquierdo (los menores de "a") y se realiza el mismo procedimiento. Se toma el sub-arreglo derecho (los mayores de "a") y se realiza el mismo procedimiento. Este proceso se realiza hasta que los subarreglos sean de un elemento. Vemos gráficamente tomado el siguiente vector 43 2 90 52 87 100 -10 68 13 7 21 45 Las variables izq (izquierda) y der (derecha), una variable para controlar el punto pívot (pivote), que se puede mirar su comportamiento en los extremos resaltados Izq 0 Der 11 0 43 1 2 2 90 3 50 4 87 5 100 6 10 7 68 8 13 9 7 10 21 11 45 12 50 PosPiv 0 Pivote 43 En este caso la posición más a la izquierda es 0, la más a la derecha es 12, se escoge como "pivote" el primer término de la lista, es decir la posición más a la izquierda, tal como está escrito en la tabla anterior. Se procede a comparar el pivote, 43, con el valor más a la derecha, posición 12 cuyo valor es 50. Se verifica que 43 y 50 están en posiciones relativas, ascendentemente, adecuadas, por esto comenzamos a movernos a la izquierda, decrementando Der, así: Izq 0 Der 11 0 43 1 2 2 90 3 50 4 87 5 100 6 10 7 68 8 13 9 7 10 21 11 45 12 50 PosPiv 0 Pivote 43 O 58 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Se compara ahora el pivote 43, en posición cero, con el número en posición der=11, es decir 45, nuevamente están en posiciones relativas adecuadas a nuestro ordenamiento ascendente, por esto se decremento derecha (Der--): Izq 0 Der 11 0 43 1 2 2 90 3 50 4 87 5 100 6 10 7 68 8 13 9 7 10 21 11 45 12 50 PosPiv 0 Pivote 43 O Se compara ahora 43 con 21 de la posición der=10, no están en posiciones relativas ordenadas, se procederá entonces a su intercambio, quedando el vector, paso a paso así: Izq 0 Der 10 0 21 1 2 2 90 3 50 4 87 5 100 6 10 10 7 68 8 13 9 7 10 21 11 45 12 50 PosPiv 0 10 21 2 90 50 87 100 68 13 7 43 45 50 Pivote 43 Se actualiza la posición del pivote, ahora está en 10, y se comienza a comparar desde la izquierda, como lo señala la flecha en la tabla anterior. Así se compara 43 con 21, los cuales están en posiciones relativas adecuadas: Izq 1 Der 10 0 21 1 2 2 90 3 50 4 87 5 100 6 10 7 68 8 13 9 7 10 43 11 45 12 50 PosPiv 10 Pivote 43 Por esto se incrementa izquierda y se compara el 43 con el 2, igualmente están en orden ascendente relativo; se incrementa izquierda nuevamente llegando a donde está el número 90 en la posición 2 del vector: Izq 1 Der 10 0 21 1 2 2 90 3 50 4 87 5 100 6 10 7 68 8 13 9 7 10 43 11 45 12 50 PosPiv 10 Pivote 43 59 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO El 90 al compararlo con el pivote 43 es mayor, por esto deberán ser intercambiados, y actualizada la posición del pivote: Izq 0 Der 10 0 21 1 2 2 90 3 50 4 87 5 100 6 10 10 7 68 8 13 9 7 10 90 11 45 12 50 PosPiv 10 2 21 2 43 50 87 100 68 13 7 90 45 50 Pivote 43 Siguiendo este proceso se obtiene la siguiente secuencia de posiciones: Izq 2 Der 90 0 21 1 2 2 43 3 50 4 87 5 100 6 10 7 68 8 13 9 7 10 90 11 45 12 50 PosPiv 2 Pivote 43 Izq 2 Der 9 0 21 1 2 2 7 3 50 4 87 5 100 6 10 10 7 68 8 13 9 7 10 90 11 45 12 50 PosPiv 2 9 Pivote 43 21 2 7 50 87 100 68 13 43 90 45 50 Izq 3 Der 9 0 21 1 2 2 7 3 50 4 87 5 100 6 10 7 68 8 13 9 43 10 90 11 45 12 50 PosPiv 9 Pivote 43 Izq 3 Der 9 0 21 21 1 2 2 2 7 7 3 50 43 4 87 87 5 100 100 6 10 10 7 68 68 8 13 13 9 50 50 10 90 90 11 45 45 12 50 50 PosPiv 9 3 Pivote 43 60 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Izq De r 8 0 1 2 3 4 5 6 7 8 9 10 11 12 PosPi v 3 Pivote 3 21 2 7 43 87 10 0 5 10 6 68 13 50 90 45 50 43 Izq 3 De r 8 0 1 2 3 4 7 8 9 1 0 9 0 9 0 11 1 2 5 0 5 0 PosPi Pivote 21 2 7 13 87 100 -10 68 1 3 4 3 5 0 5 0 45 3 8 43 21 2 7 13 87 100 -10 68 45 Izq 4 Der 8 0 21 1 2 2 7 3 13 4 87 5 100 6 10 7 68 8 43 9 50 10 90 11 45 12 50 PosPiv 8 Pivote 43 Izq 4 Der 8 0 21 21 1 2 2 2 7 7 3 13 13 4 87 43 5 100 100 6 10 10 7 68 68 8 87 87 9 50 50 10 90 90 11 45 45 12 50 50 PosPiv 8 4 Pivote 43 Izq 4 Der 7 0 21 1 2 2 7 3 13 4 43 5 100 6 10 7 68 8 87 9 50 10 90 11 45 12 50 PosPiv 4 Pivote 43 Izq 4 Der 6 0 21 1 2 2 7 3 13 4 10 10 5 100 6 10 43 7 68 8 87 9 50 10 90 11 45 12 50 PosPiv 4 6 Pivote 43 21 2 7 13 100 68 87 50 90 45 50 61 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Izq 5 Der 6 0 21 1 2 2 7 3 13 4 10 5 100 6 43 7 68 8 87 9 50 10 90 11 45 12 50 PosPiv 6 Pivote 43 Izq 5 Der 6 0 21 21 1 2 2 2 7 7 3 13 13 4 10 10 5 100 43 6 100 100 7 68 68 8 87 87 9 50 50 10 90 90 11 45 45 12 50 50 PosPiv 6 5 Pivote 43 Al avanzar desde la derecha hacia la izquierda, la variable Der se encuentra con la posición donde está el pivote, e Izq ya estaba en el mismo valor, es decir las tres variables "se encuentran en el mismo sitio", así: Izq 5 Der 5 0 21 1 2 2 7 3 13 4 10 5 43 6 100 7 68 8 87 9 50 10 90 11 45 12 50 PosPiv 5 Pivote 43 Se observa que el valor del pivote, 43, está en el sitio que le corresponde en ordenamiento ascendente, y que a su izquierda se forma una sublista, desordenada, desde la posición 0 a la 4, con todos sus elementos menores; y una sublista a la derecha, desde la posición 6 hasta la 12, en desorden y con todos mayores que el pivote. A partir de este punto se procede con el mismo procedimiento seguido para la lista completa, en cada una de las sublistas y por separado. Con lo anterior podemos describir el siguiente algoritmo para que usted mediante una prueba de escritorio verifique que hace #include <stdio.h> #include <conio.h> #include <iostream.h> // Prototipos de las funciones. void MostrarVector(int *arreglo, int n); void QuickSort(int *arreglo, int l, int r); void intercambiar(int *arreglo, int pos1, int pos2); 62 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO void main(void) { int n; // numero de elementos del vector int i; // Contador int arreglo[100]; // Arreglo de enteros clrscr(); cout<<"Digite el numero de elementos:"; cin>>n; for (i=0;i<n;i++) { cout<<"Digite valor para la posicion :[" <<i+1<<"] "; cin>>arreglo[i]; } cout<<"\nVector Leido:\n"; MostrarVector(arreglo,n); cout<<"\nOrdenamiento por QuickSort:\n"; QuickSort(arreglo,0,n-1); cout<<"\nVector Ordenado:\n"; MostrarVector(arreglo,n); getch(); } // Muestra en pantalla el vector void MostrarVector(int *arreglo, int n) { int i; // Contador for (i=0;i<n;i++) cout<<arreglo[i]<< " "; cout<<"\n"; } // Ordenamiento QuickSort. void QuickSort(int *arreglo, int izquierda, int derecha) { int mayor; // Posicion de un elemento mayor al pivote int menor; // Posicion de un elemento menor al pivote int pivote; // Elemento pivote if (izquierda < derecha) { pivote = arreglo[derecha]; mayor = izquierda-1; menor = derecha; 63 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO while (mayor <= menor) { while (mayor <= derecha) { mayor++; if (arreglo[mayor] >= pivote) break; } while (menor >= izquierda) { menor--; if (arreglo[menor] <= pivote) break; } if (mayor < menor) intercambiar(arreglo,mayor,menor); } intercambiar(arreglo,derecha,mayor); QuickSort(arreglo,izquierda,mayor-1); QuickSort(arreglo,mayor+1,derecha); } } void intercambiar(int arreglo[], int pos1, int pos2) { int temporal; // Variable para intercambio de contenidos temporal = arreglo[pos1]; arreglo[pos1] = arreglo[pos2]; arreglo[pos2] = temporal; } Bueno solo queda que usted que es una persona muy “pila”, indague más acerca de estos métodos, tanto de búsqueda como de ordenamiento , o realice nuevas mejoras a estos programas aquí desarrollados. 64 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 6: BUSQUEDA Introducción La búsqueda es una tarea que se realiza permanentemente, en toda actividad, cuando se está en un supermercado uno busca artículos en particular, en una multitud de gente se busca a alguien en especial, en un directorio se busca a una persona, como se observa la búsqueda está presente en cada una de las actividades. Los algoritmos más utilizados para la realización de búsquedas son: Lineal o Secuencial Binaria. Hash (transformación de claves). Lección 26: Definición Un algoritmo de búsqueda es aquel que está diseñado para localizar un elemento concreto dentro de una estructura de datos. Consiste en solucionar un problema de existencia o no de un elemento determinado en un conjunto finito de elementos, es decir, si el elemento en cuestión pertenece o no a dicho conjunto, además de su localización dentro de éste. Este problema puede reducirse a devolver la existencia de un número en un vector. Lección 27: Lineal Es el método para buscar algo dentro de un arreglo, donde se hace un recorrido de inicio a fin, realizando las comparaciones necesarias hasta encontrar el elemento requerido. Para entenderlo mejor realizamos el algoritmo necesario encontro = FALSE para k= 0 hasta n haga si X[k] = ValorBuscado haga mostrar “Elemento encontrado en la posición “, k encontro = TRUE k=n; fin si fin para 65 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO si encontro = FALSE haga mostrar “No se encontró el elemento“ fin si A continuación un ejemplo de búsqueda lineal #include <stdio.h> #include <conio.h> #include <iostream.h> // Prototipos de las funciones. void mostrar(int *arreglo, int n); int buscar(int valor, int *arreglo, int n); void main(void) { int n; // numero de elementos del vector < 100 int valor; // El numero a buscar int i; // Contador int arreglo[100]; // Arreglo de enteros clrscr(); cout<<"Digite el numero de elementos:"; cin>>n; for (i=0;i<n;i++) { cout<<"Digite la posicion ", i; cin>>arreglo[i]; } cout<<"Digite el numero a buscar:"; cin>>valor; cout<<"\nVector Leido:\n"; mostrar(arreglo,n); cout<<"\nBusqueda lineal:\n"; if ((i=buscar(valor, arreglo, n)) != -1) cout<<"\nEncontrado en la posicion \n"<<i+1; else cout<<"\nNo existe en el arreglo\n"; getch(); } // función que permite mostrar en la pantalla el vector void mostrar(int *arreglo, int n) { 66 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO int i; // Contador for (i=0;i<n;i++) cout<< arreglo[i]; cout<<"\n"; } // función Búsqueda lineal. int buscar(int valor, int *arreglo, int n) { int i; // Contador for (i=0; i<n; i++) if (valor == arreglo[i]) // condicional para encontrar el elemento return i; return -1; } Se recomienda realizar prueba comportamiento del anterior código. de escritorio para determinar el Lección 28: Binaria Este algoritmo permite buscar de una manera más eficiente un dato dentro de un arreglo, para hacer esto se determina el elemento central del arreglo y se compara con el valor que se está buscando, si coincide termina la búsqueda y en caso de no ser así se determina si el dato es mayor o menor que el elemento central, de esta forma se elimina una mitad del arreglo junto con el elemento central para repetir el proceso hasta encontrarlo o tener solo un elemento en el arreglo. Para poder aplicar este algoritmo se requiere que el arreglo este ordenado. Su implementación es la siguiente: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define TAM 15 void main() { int a[TAM], busca, temp, bajo, alto, central; printf("Llenando el arreglo con números aleatorios\n"); randomize(); //Inicializa el generador de aleatorios for (int i=0; i< TAM; i++) a[i]=random(100); 67 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO //Implementacion de Ordenamiento por burbuja de menor a mayor printf ("Ordenando arreglo...\n"); for (int j=1; j <= TAM; j++) for (i=0; i< TAM-1; i++) if (a[i] > a[i+1]) { temp = a[i]; a[i] = a[i+1]; a[i+1] = temp; } //Implementacion de busqueda binaria printf ("\nIntroduce un numero a buscar: "); scanf ("%d", &busca); bajo = 0; alto = TAM-1; central = (bajo+alto)/2; while (bajo < alto && busca != a[central]) { if(busca > a[central]) bajo = central+1; else alto = central-1; central=(bajo+alto)/2; } if (busca == a[central]) printf("\n%d encontrado en posicion %d", busca, central); else printf("\n%d no existe", busca); printf ("\n\nEl arreglo ordenado era\n\n"); for (i=0; i< TAM; i++) printf ("%d ", a[i]); getch(); } Lección 29: De Hash La idea principal de este método consiste en aplicar una función que traduce el valor del elemento buscado en un rango de direcciones relativas. Una desventaja importante de este método es que puede ocasionar colisiones. 68 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO funcion hash (valor_buscado) inicio hash <- valor_buscado mod numero_primo fin inicio <- hash (valor) il <- inicio encontrado <- falso repite si arreglo[il] = valor entonces encontrado <- verdadero en caso contrario il <- (il +1) mod N hasta encontrado o il = inicio fin Lección 30: Ejercicios 1) Imprimir los primeros 3 números PERFECTOS. # include <iostream.h> # include <conio.h> # include <string.h> int main() { int n=0, sum=0 ,cont=0, i; do { n ++ ; for (i=1 ; i<n ; i++) { if ((n % i) == 0) { sum = sum + i ; } } if ( sum == n) { cout<< "El numero "<<n<< " es perfecto "<<endl ; cont = cont + 1; } sum=0; } while (cont < 3); getche(); return 0; } 69 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 2) Cargar 2 vectores con nros enteros, uno de 100 y el otro de 200, sin repetir los nros dentro de cada vector. Se pide realizar una función q devuelva un tercer vector con los elementos repetidos de los vectores ingresados al principio. # include <iostream.h> # include <conio.h> # include <string.h> # include <iomanip.h> void carga1 (int v[]); void carga2 (int v[]); void busqueda (int v[],int c[],int d[],int &ct); void impre (int v[],int &ct); int main() { int a[100],b[200],c[100],ct=0; carga1 (a); carga2 (b); busqueda (a,b,c,ct); impre(c,ct); getche(); return 0; } void carga1 (int v[]) { int i; cout<<"Ingrese los componentes del 1° vector "<<en dl; for (i=0;i<100;i++) { cout<<"ingrese el valor de la posicion "<<i<<endl; cin>>v[I]; } } void carga2 (int v[]) { int i; cout<<"Ingrese los componentes del 2° vector "<<en dl; for (i=0;i<200;i++) { cout<<"ingrese el valor de la posicion "<<i<<endl; cin>>v[i]; } 70 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO } void busqueda (int v[],int c[],int d[],int &ct) { int a=0,i,j; for (i=0;i<100;i++) { for (j=0;j<200;j++) { if (v[i]==c[j]) { d[a++]=v[i]; ct++; } } } } void impre (int v[],int &ct ) { int i; cout<<"el vector con los elementos q se repiten \n"; for (i=0;i<ct;i++) cout<<setw(7)<<setprecision(2)<<v[i]<<endl; } 71 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ACTIVIDADES DE AUTOEVALUACION DE LA UNIDAD 2 1: Recopilación de preguntas de selección múltiple con única respuesta A. Propósito principal de un ordenamiento es a. Facilitar las búsquedas de los miembros de un conjunto ordenado b. Buscar los elementos de un conjunto c. Ordenar en base a su valor B. Cuando es conveniente usar los ordenamientos a. Cuando se requiere hacer una cantidad considerable de búsquedas b. Cuando se tienen varios directorios c. Cuando se considera el factor del tiempo C. En este tipo de algoritmos cada elemento es comparado contra los demás a. Algoritmo de enumeración b. Algoritmo de inserción c. Algoritmo de intercambio D. En este algoritmo los elementos que van a ser ordenados son considerados uno a la vez a. Algoritmo de burbuja b. Algoritmo de shell c. Algoritmos de insercción E. Compara cada elemento del arreglo con el siguiente, si el elemento es mayor que él se sigue, entonces surge un intercambio. a. Método de Burbuja b. Método de Quicksort c. Método de Shell F. Este tipo de algoritmos se selecciona o se busca el elemento más pequeño o más grande de todo el conjunto de elementos y se coloca 72 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO en la posición adecuada a. Algoritmo de Shell b. Algoritmo de selección c. Algoritmo de selección directa G. Este ordenamiento lleva el nombre de su inventor a. Ordenamiento Quicksort b. Ordenamiento de Burbuja c. Ordenamiento de Shell 2) deduzca, indague, consulte, cuáles son las ventajas y/o desventajas de los métodos de búsqueda y ordenamiento aquí expuestos 3) Realice un programa que permita introducir en un arreglo de n elementos valores de tipo entero y a través de un menú, realizar las siguientes funciones: A. Ingreso de datos B. Búsqueda C. Ordenamiento D. Estadística E. Salir En cada uno de los menús se incluirá, un segundo submenú, por ejemplo el item número 3 Ordenamiento puede incluir los métodos de: Por burbuja Por inserción Y así sucesivamente, en el menú estadista, se debe presentar un informe de la cantidad de iteraciones que cumple una opción de las anteriores. 73 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO UNIDAD 3 Nombre de la Unidad Introducción ESTRUCTURAS Y ARCHIVOS Los archivos como colección de datos sirve para la entrada y salida a la computadora y son manejados con programas. Los archivos pueden ser contrastados con Arrays y registros; Lo que resulta dinámico y por esto en un registro se deben especificar los campos, él número de elementos de un arrays (o arreglo), el número de caracteres en una cadena; por esto se denotan como "Estructuras Estáticas". En los archivos no se requiere de un tamaño predeterminado; esto significa que se pueden hacer archivos de datos más grandes o pequeños, según se necesiten. Cada archivo es referenciado por su identificador (su nombre.). Justificación Hasta el momento solo hemos trabajado con datos de un uncí tipo o ilimitados en tamaño, afortunadamente los lenguajes de programación y C++, dejan al usuario construir o combinar diversidad de datos para conformar estructuras complejas de información, esto será la primera parte, pero la segunda es la más importante, si ustedes se han dado cuenta hasta el momento solo hemos trabajado a nivel de memoria, es decir todo funciona si el programa se esta ejecutando, pero en el momento que deja de ejecutarse, se pierde toda la información en el almacenada, la solución llega con la construcción de estructuras que se puedan almacenar y acceder en forma de archivos. Determinar los mecanismos que se utilizan para combinar diferentes tipos de datos Propósitos de la unidad Manipular diversidad de datos en forma simultanea Grabar datos en unidades de almacenamiento físicas Intencionalidades Formativas Objetivos de la unidad Desarrollar programas que manipulen cantidad de datos de diferentes tipos y que puedan almacenarse y recuperase en cualquier momento Competencias de la unidad: Dominar el manejo de estructuras con diversidad de datos Comprender como es que se escriben datos en medios fiscos Metas de aprendizaje Realizar programas que presten un verdadero servicio, cuando se trate de guardar infamación Denominación de capítulos ESTRUCTURAS ARCHIVOS ACCESO A LOS ARCHIVOS 74 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 7: ESTRUCTURAS Introducción Las estructuras están compuestas como ya dijimos por una serie de componentes individuales llamados miembros, para hacerlo más grafico podemos decir que queremos ingresar datos de una persona como su nombre, apellido, dirección, salario, edad… cada miembro de la estructura es de dato diferente, una estructura no tiene restricciones para contener un número determinado de miembros, e inclusive podemos realizar estructuras que contengan otras estructuras.. Lección 31: Declaración de una Estructura En C una estructura es una colección de variables que se referencian bajo el mismo nombre. Una estructura proporciona un medio conveniente para mantener junta información relacionada. Al crear o definir una estructura se forma una plantilla que puede usar el programador para definir una variable de tipo estructura. La variables que conforman la estructura son llamadas (elementos) de la estructura. EJEMPLO: struct dire{ char ; 0]; int int }; Para definir una variable de tipo estructura se procede así: struct dire cliente; La variable en memoria se la puede imaginar así: CLIENTE NOMBRE DIRECCION CIUDAD TELEFONO PREFIJO nombre[30] char dirección[3 char ciudad[30]; telefono; prefijo; De lo anterior se debe sacar como conclusión que la variable cliente 75 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO almacena 5 datos diferentes; CIUDAD, TELEFONO, PREFIJO. que son NOMBRE, DIRECCION, Otra manera de declarar la misma variable es así: typedef struct{ char nombre[30]; char dirección[30]; char ciudad[30]; int telefono; int prefijo; }dire; En este caso hemos definido un tipo de dato de nombre dire que es una estructura Para definir variables de ese tipo solo necesitamos escribir: dire cliente; EJEMPLO: Se desea crear una variable de tipo estructura para almacenar un número complejo. Recuerde que un número complejo, tiene parte real, parte imaginaria Si entendimos lo anterior, entonces podemos escribir: typedef struct { double p_real; double p_imaginario; }complejo; Para definir una variable compleja, escribimos ahora: complejo a, b; Lección 32: Asignación de Estructuras Para entrar datos a una variable de tipo estructura lo podemos hacer de dos maneras: Por medio de una instrucción de lectura o por medio de una instrucción de asignación: ENTRANDO UN DATO CON LA INSTRUCCION cin: Para entrar datos con está instrucción proceda así: cin>>nombre_variable.nombre_campo; EJEMPLO: La instrucción: cin>>a.p_real; Permite entrar un número real a la variable p_real de la variable a 76 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ENTRANDO UN DATO CON LA INSTRUCCION DE ASIGNACION: Para entrar datos con está instrucción proceda así: nombre_variable.nombre_campo=variable ; EJEMPLO: El siguiente programa muestra como podemos utilizar una variable de tipo estructura en un problema de suma de complejos: #include <conio.h> #include <iostream.h> void main() { typedef struct { float parte_real; float parte_imaginaria; }complejo; complejo a,b,c; clrscr(); gotoxy(10,10); clreol(); cout<<"Escriba la parte real de a"; cin>>a.parte_real; gotoxy(10,12);clreol(); cout<<"Escriba la parte imaginaria de a"; cin>>a.parte_imaginaria; gotoxy(10,10);clreol(); cout<<"Escriba la parte real de b"; cin>>b.parte_real; gotoxy(10,12); clreol(); cout<<"Escriba la parte imaginaria de b"; cin>>b.parte_imaginaria; c.parte_real=a.parte_real + b.parte_real; c.parte_imaginaria=a.parte_imaginaria + b.parte_imaginaria; gotoxy(10,13); cout<<a.parte_real<<"+ i"<<a.parte_imaginaria; gotoxy(10,14); cout<<b.parte_real<<"+ i"<<b.parte_imaginaria; gotoxy(10,15); cout<<c.parte_real<<"+ i"<<c.parte_imaginaria; getch(); } Lección 33: Estructuras Anidadas También está permitido anidar estructuras, conseguir superestructuras muy elaboradas. Ejemplo: struct stDireccion { 77 con lo cual se pueden UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO char Calle[64]; int Portal; int Piso; char Puerta[3]; char CodigoPostal[6]; char Poblacion[32]; }; struct stPersona { struct stNombre { char Nombre[32]; char Apellidos[64]; } NombreCompleto; stDireccion Direccion; char Telefono[10]; }; ... En general, no es una práctica corriente definir estructuras dentro de estructuras, ya que tienen un ámbito local, y para acceder a ellas se necesita hacer referencia a la estructura más externa. Por ejemplo para declarar un objeto del tipo stNombre hay que utilizar el operador de acceso (::): stPersona::stNombre NombreAuxiliar; Sin embargo para declarar un objeto de tipo stDireccion basta con declararla: stDireccion DireccionAuxiliar; Lección 34: Estructuras Anónimas Antes dijimos, al hablar sobre la sintaxis de las declaraciones de estructuras, que debe aparecer o bien el identificador de estructura, o bien declararse algún objeto de ese tipo en la declaración. Bien, eso no es del todo cierto. Hay situaciones donde se pueden omitir ambos identificadores. Una estructura anónima es la que carece de identificador de tipo de estructura y de declaración de objetos del tipo de estructura. Por ejemplo, veamos esta declaración: 78 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO struct stAnonima { struct { int x; int y; }; int z; }; Para acceder a los campos x o y se usa la misma forma que para el campo z: stAnonima Anonima; Anonima.x = 0; Anonima.y = 0; Anonima.z = 0; Pero, ¿cual es la utilidad de esto? Pues, la verdad, no mucha, al menos cuando se usa con estructuras. En el capítulo dedicado a las uniones veremos que sí puede resultar muy útil. El método usado para declarar la estructura dentro de la estructura es la forma anónima, como verás no tiene identificador de tipo de estructura ni de campo. El único lugar donde es legal el uso de estructuras anónimas es en el interior de estructuras y uniones. Podemos usar el operador sizeof para calcular el espacio de memoria necesario para almacenar una estructura. Sería lógico suponer que sumando el tamaño de cada elemento de una estructura, se podría calcular el tamaño de la estructura completa, pero no siempre es así. Por ejemplo: #include <iostream> using namespace std; struct A { int x; char a; int y; char b; }; struct B { int x; int y; 79 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO char a; char b; }; int main() { cout << "Tamaño de int: " << sizeof(int) << endl; cout << "Tamaño de char: " << sizeof(char) << endl; cout << "Tamaño de estructura A: " << sizeof(A) << endl; cout << "Tamaño de estructura B: " << sizeof(B) << endl; return 0; } El resultado, usando Dev-C++, es el siguiente: Tamaño de int: 4 Tamaño de char: 1 Tamaño de estructura A: 16 Tamaño de estructura B: 12 Si hacemos las cuentas, en ambos casos el tamaño de la estructura debería ser el mismo, es decir, 4+4+1+1=10 bytes. Sin embargo en el caso de la estructura A el tamaño es 16 y en el de la estructura B es 12, ¿por qué? La explicación es algo denominado alineación de bytes (byte-aling). Para mejorar el rendimiento del procesador no se accede a todas las posiciones de memoria. En el caso de microprocesadores de 32 bits (4 bytes), es mejor si sólo se accede a posiciones de memoria múltiplos de cuatro, de modo que el compilador intenta alinear los objetos con esas posiciones. En el caso de objetos int es fácil, ya que ocupan cuatro bytes, pero con los objetos char no, ya que sólo ocupan uno. Cuando se accede a datos de menos de cuatro bytes la alineación no es tan importante. El rendimiento se ve afectado sobre todo cuando hay que leer datos de cuatro bytes que no estén alineados. En el caso de la estructura A hemos intercalado campos int con char, de modo que el campo int y, se alinea a la siguiente posición múltiplo de cuatro, dejando tres posiciones libres después del campo a. Lo mismo pasa con el campo b. 80 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 0 1 x 2 3 4 a 5 6 7 8 y 9 10 11 12 13 14 15 b vacío vacío En el caso de la estructura B hemos agrupado los campos de tipo char al final de la estructura, de modo que se aprovecha mejor el espacio, y sólo se desperdician los dos bytes sobrantes después de b. 0 1 x 2 3 4 y 5 6 7 8 a 9 b 10 11 vacío Lección 35: Ejercicios 1. Escribir un programa que almacene en un array los nombres y números de teléfono de 10 personas. El programa debe leer los datos introducidos por el usuario y guardarlos en memoria (en el array). Después debe ser capaz de buscar el nombre correspondiente a un número de teléfono y el teléfono correspondiente a una persona. Ambas opciones deben se accesibles a través de un menú, así como la opción de salir del programa. El menú debe tener esta forma, más o menos: a) Buscar por nombre b) Buscar por número de teléfono c) Salir Pulsa una opción: Nota: No olvides que para comparar cadenas se debe usar una función, no el operador ==. 2. Para almacenar fechas podemos crear una estructura con tres campos: año, mes y dia. Los días pueden tomar valores entre 1 y 31, los meses entre 1 y 12 y los años, dependiendo de la aplicación, pueden requerir distintos rangos de valores. Para este ejemplo consideraremos suficientes 128 años, entre 1960 y 2087. En ese caso el año se obtiene sumando 1960 al valor de año. El año 2003 se almacena como 43. Usando estructuras, y ajustando los tipos de los campos, necesitamos 81 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO un char para dia, un char para mes y otro para año. Diseñar una estructura análoga, llamada fecha, pero usando campos de bits. Usar sólo un entero corto sin signo (unsigned short), es decir, un entero de 16 bits. Los nombres de los campos serán: dia, mes y anno. 3. Basándose en la estructura de bits del ejercicio anterior, escribir una función para mostrar fechas: void Mostrar(fecha);. El formato debe ser: "dd de mmmmmm de aaaa", donde dd es el día, mmmmmm el mes con letras, y aaaa el año. Usar un array para almacenar los nombres de los meses. 4. Basándose en la estructura de bits del ejercicio anterior, escribir una función bool ValidarFecha(fecha);, que verifique si la fecha entregada como parámetro es válida. El mes tiene que estar en el rango de 1 a 12, dependiendo del mes y del año, el día debe estar entre 1 y 28, 29, 30 ó 31. El año siempre será válido, ya que debe estar en el rango de 0 a 127. Para validar los días usaremos un array int DiasMes[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};. Para el caso de que el mes sea febrero, crearemos otra función para calcular si un año es o no bisiesto: bool Bisiesto(int); Los años bisiestos son los divisibles entre 4, al menos en el rango de 1960 a 2087 se cumple. Nota: los años bisiestos son cada cuatro años, pero no cada 100, aunque sí cada 400. Por ejemplo, el año 2000, es múltiplo de 4, por lo tanto debería haber sido bisiesto, pero también es múltiplo de 100, por lo tanto no debería serlo; aunque, como también es múltiplo de 400, finalmente lo fue. 5. Seguimos con el tema de las fechas. Ahora escribir dos funciones más. La primera debe responder a este prototipo: int CompararFechas(fecha, fecha);. Debe comparar las dos fechas suministradas y devolver 1 si la primera es mayor, -1 si la segunda es mayor y 0 si son iguales. La otra función responderá a este prototipo: int Diferencia(fecha, fecha);, y debe devolver la diferencia en días entre las dos fechas suministradas. 82 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 8: ARCHIVOS Introducción Los archivos como colección de datos sirven para la entrada y salida a la computadora y son manejados con programas. Los archivos pueden ser contrastados con Arrays y registros; Lo que resulta dinámico y por esto en un registro se deben especificar los campos, él número de elementos de un arrays (o arreglo), el número de caracteres en una cadena; por esto se denotan como "Estructuras Estáticas". En los archivos no se requiere de un tamaño predeterminado; esto significa que se pueden hacer archivos de datos más grandes o pequeños, según se necesiten. Cada archivo es referenciado por su identificador (su nombre.). Lección 36: Definición Los archivos también denominados ficheros (file); es una colección de información (datos relacionados entre sí), localizada o almacenada como una unidad en alguna parte de la computadora. Los archivos son el conjunto organizado de informaciones del mismo tipo, que pueden utilizarse en un mismo tratamiento; como soporte material de estas informaciones. Lección 37: Características de los Archivos Las principales características de esta estructura son: • Independencia de las informaciones respecto de los programas • La información almacenada es permanente • Un archivo puede ser accedido por distintos programas en distintos momentos • Gran capacidad de almacenamiento. Lección 38: Clasificación de los Archivos En base a su función, existen 6 tipos básicos de archivos clasificados por la función que desempeñan en un sistema de información. 83 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO • • • • • • ARCHIVO MAESTRO. ARCHIVO DE TRANSACCIONES. ARCHIVO DE REPORTE. ARCHIVO DE TRABAJO. ARCHIVO DE PROGRAMA. ARCHIVO DE TEXTO. ARCHIVO MAESTRO: Representa una visión estática de algún aspecto de los negocios de una organización en un momento dado. Un Registro en un archivo maestro registra el estado de alguno de sus componentes. Ejemplo: los pagos efectuados a un empleado Un archivo maestro contiene datos relativamente permanentes o datos de estados históricos. Los cambios que han de ser aplicados al archivo maestro, son recolectados en un archivo de transacciones. ARCHIVO DE TRANSACIONES: Puede contener datos para agregar un nuevo registro o para borrar, modificar un registro maestro. Cada registro en un archivo de transacciones representa un vento a un cambio de alguna cosa, esto sucede permanentemente, en las aplicaciones comunes, por ejemplo modificaciones en un editor de texto o en una hoja de cálculo ARCHIVO DE REPORTE: Contiene datos que son formateados para su representación al usuario; ejemplo: Archivo de reporte de una nomina. ARCHIVO DE TRABAJO: Es un archivo temporal en el sistema, no tiene las características de E/S de un archivo de transacciones de reporte; ejemplo: Archivo de trabajo para el ordenamiento de empleados. El archivo de trabajo se usa comúnmente para pasar datos creados por un programa a otro programa. ARCHIVO DE PROGRAMA: Contiene instrucciones para procesar datos, las cuales pueden almacenarse en otros archivos o recibir en la memoria principal. Ejemplo: El código de un lenguaje: de alto nivel (lenguaje c, c++, etc), lenguaje ensamblador, lenguaje máquina. ARCHIVO TEXTO: Contiene datos alfanuméricos y gráficos ingresados a través de un editor de texto. Block de notas En general C++ proporciona la manipulación de tantos tipos de archivos como tipos de datos existen, el paquete Standard de input/output de "C" y por ende de C++, hace disponible 4 métodos o maneras diferentes de leer y escribir los datos a disco. 84 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 1.- Datos a ser grabados o leídos como un carácter a la vez, se utilizaran funciones análogas a getchar y putchar. 2.- Datos que pueden ser leídos o grabados como una string se usaran funciones análogas a gets y puts. 3.- Datos que se capturen o desplieguen con formatos parecidos a los usados por scanf y printf se usaran funciones similares, es decir serán problemas que involucran mezclas de strings, caracteres, floats, etc. 4.- También se podrán leer y escribir datos de tipo arreglo y registros utilizando instrucciones apropiadas, en resumen: Carácter String Formateado Registros y arreglos fread() fwrite() Leer Escribir getc() putc() fgets() fputs() fscanf() fprintf() FIGURA 6. Funciones para trabajo con archivos Lección 39: Tipos de Archivos Los elementos de un archivo pueden ser de cualquier tipo, simples o estructurados o según su función. SEGÚN SU FUNCION. Se define por: a.- Archivos Permanentes: Son aquellos cuyos registros sufren pocas o ninguna variación a lo largo del tiempo, se dividen en: Constantes: Están formados por registros que contienen campos fijos y campos de baja frecuencia de variación en el tiempo. De Situación: Son los que en cada momento contienen información actualizada. Históricos: Contienen información acumulada a lo largo del tiempo de archivos que han sufridos procesos de actualización o bien acumulan datos de 85 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO variación periódica en el tiempo. b.- Archivos de Movimiento Son aquellos que se utilizan conjuntamente con los maestros (constantes), y contienen algunos campos comunes en sus registros con aquellos, para el procesamiento de las modificaciones experimentados por los mismos. c.- Archivo de Maniobra o Transitorio Son los archivos creados auxiliares creados durante la ejecución del programa y borrados habitualmente al terminar el mismo. SEGÚN SUS ELEMENTOS. Los principales archivos de este tipo son: Archivo de Entrada: Una colección de datos localizados en un dispositivo de entrada. Archivo de Salida: Una colección de información visualizada por la computadora. Constantes: están formados por registros que contienen campos fijos y campos de baja frecuencia de variación en el tiempo. De Situación: son los que en cada momento contienen información actualizada. Históricos: Contienen información acumulada a lo largo del tiempo de archivos que han sufrido procesos de actualización, o bien acumulan datos de variación periódica en el tiempo. Archivos de Movimiento o Transacciones: Son aquellos que se utilizan conjuntamente con los maestros (constantes), y contienen algún campo común en sus registros con aquellos, para el procesamiento de las modificaciones experimentados por los mismos. Archivos de Maniobra o Transitorios: Son los archivos auxiliares creados durante la ejecución del programa y borrados habitualmente al terminar el mismo. Lección 40: Ejercicios 86 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 1- Realice un programa que permite manejar el acceso de estudiantes a la sala de computo de la universidad, es responsabilidad de usted, realizar el análisis respectivo, lo que permita tener un programa funcional 2- Realizar un programa que permita elegir el formato (windows o linux) y permita escribir un determinado texto de cualquier tamaño y guardarlo en un archivo ascii con el formato especificado llamado c:\texto.txt. Los archivos de texto windows tienen como marcador de final de línea la secuencia CR (retorno de carro ascii=13) y LF (line feed ascii=10). Los de Linux solo tienen LF. 3- Realizar un programa que lea c:\texto.txt y proporcione las siguientes estadísticas: nº total de caracteres, nº de mayúsculas, nº de consonantes, nº de vocales y las cinco letras mas usadas 4- Escribir un programa que solicite palabras y las agregue a un fichero llamado c:\diccionario de forma que luego se puedan consultar las palabras una a una 87 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO CAPITULO 9: ACCESO A LOS ARCHIVOS Introducción Se refiere al método utilizado para acceder a los registros de un archivo prescindiendo de su organización. Existen distintas formas de acceder a los datos: Secuenciales; los registros se leen desde el principio hasta el final del archivo, de tal forma que para leer un registro se leen todos los que preceden. Directo; cada registro puede leerse / escribirse de forma directa solo con expresar su dirección en el fichero por él numero relativo del registro o por transformaciones de la clave de registro en él numero relativo del registro a acceder. Por Índice; se accede indirectamente a los registros por su clave, mediante consulta secuenciales a una tabla que contiene la clave y la dirección relativa de cada registro, y posterior acceso directo al registro. Dinámico; es cuando se accede a los archivos en cualquier de los modos anteriormente citados. La elección del método esta directamente relacionada con la estructura de los registros del archivo y del soporte utilizado. Lección 41: Tipos de Acceso Acceso Secuencial. Exige el tratamiento de elemento, para esto es necesario una exploración secuencial comenzando desde el primer momento (Pascal permite este acceso) Secuenciales: archivo de texto que debe ser leído del principio hasta el final. Acceso Directo. Permite procesar o acceder a un elemento determinado y referencia directamente por su posición en el soporte de almacenamiento (Turbo Pascal permite este acceso. Aleatorios: es un archivo con registros de un mismo largo. Un programa puede accesar directamente cualquier registro sin tener que leer los registros previos. Binarios: es un archivo que lee byte por byte sin asumir ninguna estructura. Los archivos Binarios no son un nuevo tipo de archivo, pero si una nueva forma de manipular cualquier tipo de archivo. Las técnicas de archivo 88 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO binarios permiten leer o cambiar cualquier byte de un archivo. Son herramientas extremadamente potentes, pero como toda herramienta potente debe manejarse con cuidado Entre otras características, a las técnicas de archivo binario no les preocupa los caracteres EOF intercalados (Control+Z = Chr$(26)) que pueda tener un archivo. Ejemplo Open NombreArchivo for Binary as #NumeroArchivo. Instrucciones para manejar archivos OPEN: reserva un espacio del buffer para la data que moverá entre el programa y los archivos. La estructura es: OPEN filespec FOR {Append|Binary|Input|Outuput|Random} As #filenumber Por ejemplo: OPEN "C:\Windows\AddrBook.ini" FOR Input As #1 Filespec: Es la localización de archivo incluyendo usualmente el drive y path. "C:\Windows\AddrBook.ini" {Append| Binary| Input| Outuput| Random} El programador tiene que seleccionar uno. Binary y Random se utiliza para archivos binarios y aleatorios. Append, Input y Output son usados con archivos secuenciales. Un archivo secuencial no puede ser abierto para leer y escribir simultaneamente. Output es usado para escribir en el archivo. Input es usado para leer del archivo. Append es usado para colocar data al final de un archivo existente. #filenumber: es necesario asignar un número al archivo. El número puede estar en el rango de #1 a #511 y es usado por Visual Basic para identificar el archivo. CLOSE: para cerrar un archivo. La estructura es: CLOSE #filenumber Por ejemplo: CLOSE #1 WRITE: envia data del programa al archivo secuencial. La estructura es: WRITE #filenumber, [OutputList] Por ejemplo: 89 en el que se trabajará, UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO WRITE #1, UserName, UserCompany, SerialNumber WRITE es la operación opuesta al INPUT. Las expresiones en el OutputList son separadas por comas. WRITE inserta comillas y comas a la data que envia al archivo. INPUT: lee data del archivo. La estructura es: INPUT #filenumber, InputList Por ejemplo: INPUT #1, UserName, UserCompany, SerialNumber Declaración y asignación de archivos La declaración de un archivo con tipo se efectúa con la ayuda de las palabras reservadas file of. El procedimiento de asignación es idéntico al utilizado anteriormente. Ejemplo: Type datos = record clave : integer; nombre : string[30]; puesto : string[20]; sueldo : real; estado : boolean; {true activo,false baja lógica} end; Var archivo:file of datos; begin Assign(archivo,'empleado.dat'); SISTEMA DE MANEJO DE ARCHIVOS. Tiene las siguientes funciones: • Controla los datos en almacenamiento secundario [ ] • Proporciona al usuario una abstracción de cómo se manipulan los datos internamente. [ ] 90 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO • Proporciona independencia de E/S con los dispositivos [ ] • Soporte de compartición, protección, recuperación de archivos y posibles caídas del sistema. [ ] • Transmisión de datos de memoria principal a secundaria.[ ] Los archivos dispositivos. de una empresa pueden almacenarse en diferentes Todos los archivos se pueden almacenar por medio de directorios, que no son otra cosa más que tablas de símbolos de archivo, los directorios se pueden utilizar de dos formas: DIRECTORIO DE NIVEL ÚNICO O DIRECTORIO PLANO Con este método, se almacenan todos los archivos en un solo nivel, este método en sistemas donde el volumen de archivos no es grande.[ ] DIRECTORIO JERARQUICO Los archivos son almacenados por medio de directorios, esta clasificación se de acuerdo a la conveniencia del usuario o de la empresa. [ ] .La estructura tiene una forma de árbol con raíz, este método es el más utilizado debido a que la revisión o búsqueda se realiza de forma sencilla. Para accesar a los archivos que se almacenan en un sistema jerárquico, el usuario debe indicar el o los directorios que se deben recorrer para localizar el archivo deseado, a esto se le denomina ruta de acceso del archivo. La ruta de acceso puede ser de dos formas: Ruta absoluta.- Este tipo de ruta de acceso inicia siempre con una diagonal invertida [ ] C:\Edit c:\SOS\sistemas\report.txt Ruta relativa.- Este tipo de ruta de acceso realiza la búsqueda del archivo en el directorio de trabajo actual, si el archivo no se localiza aquí, el S.O. lo buscará en los directorios especificados en el PATH de un archivo con extensión .BAT. C:\Edit report.txt 91 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lección 42: Operaciones que se realizan a los Archivos Existen muchas operaciones asociadas a archivos en c++, las más elementales son: 1.- Creación de Archivo.- En este proceso se pretende solamente crear un archivo nuevo en disco con su nombre, tipo y especialidad de almacenamiento de datos apropiado. archdisco = fopen("c:\\ac\\alumnos.dat","w"); 2.- Apertura de Archivos.- En este caso se pretende abrir un archivo ya existente en disco para procesarlo ya sea para cargar, grabar o modificar estructuras en sus registros o leer algún registro en especial para ser manipulado de acuerdo a la necesidad del usuario Observación: No confundir creación con apertura, creación es un proceso que solo se ejecuta una sola vez en la vida de un archivo, si se ejecuta más de una vez los datos del archivo se pierden, mientras que apertura, siempre se esta realizando por los programas especializados en algún proceso. 3.-Cierre de archivos: Es la operación más importante en cualquier programa que maneje archivos, de no cerrar los archivos existe mucha probabilidad que se pierdan los datos. 4.-Altas en archivo.- En este proceso se captura una estructura en memoria con sus datos pertinentes y después se graba la estructura al archivo en disco. 5.-Lectura de archivo.- En este proceso se abre el archivo, se manda el registro de disco a una estructura en memoria para su procesamiento. 6.- Consulta de archivos: En este proceso se pretende desplegar todos los registros del archivo en disco a la pantalla. o a otro dispositivo como la impresora 7.-Búsqueda en archivos: Una de las operaciones más comunes consiste en que el usuario pide toda la información de algún registro. 8.- Filtros.- En este proceso el usuario esta interesado en algún conjunto de registros con características comunes (condición), por ejemplo todos los alumnos de "introducción a la programación" que tengan notas promedio superiores a 4.5 o todos los empleados que ganen mas de $5500.00 pesos. 9.-Modificaciones de registros o archivos: Problema muy común, donde los datos originales ya grabados se tienen que cambiar o actualizar, por ejemplo elnombre no era "Pedro" sino "José", o la calificación no es 3.5 si no 2.0, .. 92 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 10.- Bajas de registros: también muy común este proceso, por ejemplo el alumno deserto, el cliente se fue del país… Lección 43: Organización de los Archivos Los archivos se encuentran organizados lógicamente como una secuencia de registros de varias longitudes diferentes. Los archivos de registros de longitud fija: son los que almacenan la información en los archivos mediante un encabezado y luego se introducen uno a uno los registros ubicados en posiciones consecutivas. Los registros de longitud variable: es el almacenamiento de registros de varios tipos en un archivo y permite uno o más campos de longitudes variables y dichos campos pueden ser repetidos. La longitud de los registros debe estar definida correctamente para poder leer y escribir de forma efectiva. ENFOQUES GENERALES PARA LA ORGANIZACIÓN DE ARCHIVOS. Los enfoques son: 1. - Enfoque de acceso secuencial: Se refiere al procesamiento de los archivos de acuerdo con el orden especifico. Ejemplo archivo secuenciales y de texto. 2. - Enfoque de acceso Directo Permite recuperar registros individuales sin leer otros registros del archivo, ejemplos archivos indizados. ARCHIVOS SECUENCIALES. Se refiere al procesamiento de los registros, no importa el orden en que se haga, para eso los registros están organizados en forma de una lista y recuperarlos y procesarlos uno por uno de principio a fin. Rudimentos de los archivos Secuenciales; dependiendo del dispositivo de almacenamiento utilizado el archivo se puede mostrar el usuario como si fuera un sistema secuencial. Al finalizar un archivo secuencial se denota con una marca de fin de archivo. (End end-of-file) El usuario de un archivo secuancial puede ver los registros en un orden secuancial simple. 93 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO La única forma de recuperar registros es comenzar al principio y extraerlos en el orden contemplado. Cuestiones de programación; la manipulación de los archivos se hace en el contexto de la programación en un lenguaje por procedimientos de alto nivel. Estos lenguajes tienden a expresar la manipulación de archivos mediante subrutinas que se definen como parte del lenguaje formal o se incluyen como extensiones del lenguaje en una biblioteca estándar. La mayor parte de los lenguajes por procedimiento de alto nivel cuenta con características que ayudan a detectar la marca de fin de archivo. ARCHIVOS DE TEXTO. También conocidos como (Slream File) son utilizados para almacenar documentos que consisten en texto; En ellos, cada registro es un solo símbolo o código de control. El leer estos archivos recibimos la información en orden secuencial en el que aparece cuando lo vemos en un monitor. Los archivos de texto son una secuencia de líneas separadas por marcas de fin de línea. Rudimentos de los archivos de textos; El usuario escribe los archivos de textos mediante un procesador de palabras que le permitirá almacenar la información pero no estrictamente en forma secuencial. El procesador también nos permite desplazarnos por todo el bloque de información y permitirnos realizar modificaciones. Mientras el usuario avance rápidamente en la lectura de registro lograra ver mas archivos. Cuestiones de programación; Casi todos los entornos de programación por procedimientos de alto nivel cuentan con subrutinas para manipular los archivos de texto. Estas subrutinas pueden formar parte de la definición formal del lenguaje o que se ofrezca en biblioteca como extensiones del mismo. ARCHIVOS INDIZADOS. 94 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Es la aplicación de incluir índices en el almacenamiento de los archivos; de esta forma nos será más fácil buscar algún registro sin necesidad de ver todo el archivo. Un índice en un archivo consiste en un listado de los valores del campo clave que ocurren en el archivo, junto con la posición de registro correspondiente en el almacenamiento masivo. Fundamento de los Índices a.- La colocación de un listado al inicio del archivo: para la identificación del contenido. b.- La presentación de un segundo índice: para reflejar la información de cada punto principal del índice anterior. c.- La actualización de los índices: Cuando se insertan y eliminan archivos, es preciso actualizar los índices para evitar contratiempos actualizando un archivo. d.- La organización de un índice: Nos evita examinar archivo por archivo para recuperar algún registro buscado; por lo tanto ahorraríamos tiempo si tenemos una adecuado organización de los índices. Cuestiones de Programación Algunos lenguajes de alto nivel cuentan con subtítulos para manipular los archivos de un registro indizado. Valiéndose de las subrutinas es posible escribir programas sin tener que preocuparse por la estructura real del sistema de índices que se aplique. ARCHIVOS DISPERSOS. También llamados (Hashed Files) representan un sistema de almacenamiento de archivos que solo ofrece acceso directo, y permiten calcular la posición de un registro en el almacenamiento masivo. Rudimentos de los archivos dispersos. El usuario debe dividir el área de almacenamiento asignando al archivo en varias secciones llamadas cubetas para poder ingresar los datos. La distribución de la información en las cubetas es problemática debido a que la estructura de los archivos es dispersa. 95 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Dentro de los archivos se presentan colisiones de información debido al agrupamiento de los registros ingresados. Cuestiones de programación. Casi ninguno de los lenguajes de programación por procedimientos en la actualidad ofrece implantaciones directas de archivos dispersos; esto es debido a las cuestiones dependientes de la aplicación implicadas en el diseño de estos archivos. Lección 44: Archivos Tipo Texto Trabajemos un ejemplo para determinar como se realiza la creación física de un archivo tipo texto: #include <stdio.h> #include <conio.h> #include <string.h> #include <iostream.h> struct { int matricula; char nombre[30]; int edad;}alumno; void main() { clrscr(); //creando y cerrando el archivo en disco FILE *archivo; archivo = fopen("c:\\ac\\alumnos.dat","w"); fclose(archivo); cout<<”ARCHIVO CREADOSATISFACTORIAMENTE”; getchar();getchar(); } Al momento de ejecutarlo FIGURA 7: Ventana de ejecución 1 96 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lo primero que se crea es una variable de tipo puntero o apuntador a un archivo en el disco (instrucción FILE y debe ser en MAYUSCULAS) llamada archivo Variables apuntadores son tipos especiales de variables que tienen la capacidad de almacenar n datos, pero si direcciones ya sean de la memoria del computador o como en este caso de una dirección física del disco. En "C++" una variable apuntador se declara anteponiendo un asterisco antes del nombre, como ya lo vimos en el apartado de apuntadores (recuerdan). En el programa se está creando una variable apuntador bautizada con el nombre de archivo (original no) que almacenara la dirección física de el archivo en disco. Como segundo paso se abre el archivo con la instrucción fopen(): archivo = fopen("c:\\a1212c\\alumnos.dat","w"); Observar que el path es la dirección física en el disco del computador. Observar el doble diagonal (\\) en el parámetro. La función fopen() cuando realiza el trabajo de abrir un archivo, regresa la dirección física donde crea o graba el archivo en disco. El primer parámetro o argumento en esta función es la unidad de disco y el nombre del archivo. El segundo parámetro o argumento es llamado modo y es una de los varios modos que podemos usar. "r" ----> Lectura. "w" ----> Escritura. "a" ----> Append, si el archivo ya existe append empieza a añadir los nuevos datos al final del archivo ya existente. "r+" ---> Lectura y escritura, ya debe existir el archivo. "w+" ---> Crea para lectura y escritura y si ya existe, sobreescribe. "a+" ---> Crea o abre para lectura y append, sino existe el archivo será creado. Existen dos caracteres que permiten determinar el tipo de archivo que estamos creando, pero insertándolo antes del signo + Modo significado. t lo abre en modo texto. b lo abre en modo binario. 97 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Cuando se ha finalizado de escribir al archivo se debe cerrar y esto se hace con la instrucción: fclose(archivo); Si usted ya transcribió el código, lo más seguro es que no haya realizado nada, pero le pregunto, tiene el directorio en su disco llamado ac ?.. Lo sabia NO, pues ahora cree ese directorio o carpeta (ojo en la raíz de la estructura del disco) y vuelva a correr el programa, ahora mire la carpeta y debe tener un archivo creado, si esto es así, puede anotarse un punto en su portafolio FIGURA 8. Recomendación Las funciones para manipular los Archivos se encuentran en el archivo de cabecera <stdio.h> y vale la pena mencionarlos: Función Descripción fopen() Abre un flujo fclose() Cierra un flujo putc Escribe un carácter en un flujo getc() Lee un carácter desde un flujo fputs() Escribe una cadena en un flujo fgets() Obtiene una cadena de un flujo fseek() Salta al byte especificado en un flujo fprintf() Imprime datos con formato en un flujo fscanf() Lee datos con formato en un flujo eof() Devuelve verdadero o falso si se halla el fin del archivo. Miremos el siguiente programa que graba registros básicos de un estudiante, #include <stdio.h> #include <conio.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // captura de campos printf("Numero de matricula :"); 98 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO scanf("%d",&alumno.matricula); getchar(); printf("Nombres :"); gets(alumno.nombre); printf("Edad :"); scanf("%d",&alumno.edad); // grabando a disco FILE *archdisco; archdisco = fopen("c:\\ac\\alumnos.dat","at+"); fwrite(&alumno,sizeof(alumno),1,archdisco); fclose(archdisco); //avisando usuario printf("alumno insertado"); getchar(); getchar(); } FIGURA 9: Ventana de ejecución 2 Observemos: Con respecto al primer ejercicio, 1.- la función fopen(), cambia de w a at+ como miramos en la tabla, esto permite abrir el archivo para agregar datos. 2.- lo nuevo es la utilización de fwrite(&persona,sizeof(alumno),1,archdisco); Como se observa ocupa 4 parámetros que son: a) fwrite() primero conocer cuáles datos va a almacenar en disco, aquí se le esta indicando que es el dato que se tiene en la dirección de 99 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO memoria donde esta el registro "alumno". b) fwrite() conocer cuántos bytes de información debe grabar, para esto se tienen dos opciones o se le da el valor exacto por ejemplo 64 bytes o 39 bytes o mas facil aun se usa sizeof() que regresa el tamaño del dato. c) fwrite() necesita conocer también cuántas estructuras o registros a la vez debe grabar por lo general es un solo registro, pero mas adelante estudiarán que es posible grabar mas de un registro a la vez y esto es de mucho provecho, porque por ejemplo si en un sistema se ocupa grabar 1000 registros y usamos fwrite() de uno en uno, quiere decir que habría mil accesos a disco. d) fwrite() conocer exactamente en que cluster, sector y byte exacto del disco duro debe grabar el registro, la primera opción seria desarmar el disco duro y ver donde hay lugar para poner el archivo X o mejor aun usar la variable archdisco que ya tiene esa dirección física del archivo en disco. Ya sabemos como se crean archivos, como se ingresan datos, lo único que queda es como recuperar la información, eso lo haremos con otro ejemplo: #include <stdio.h> #include <conio.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // leyendo disco FILE *archdisco; archdisco = fopen("c:\\ac\\alumnos.dat","at+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyo while(fread(&alumno,sizeof(alumno),1,archdisco)==1) { // desplegando estructuras printf("MATRICULA =%d ",alumno.matricula); 100 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO printf(" NOMBRE =%s ",alumno.nombre); printf(" MESES =%d ",alumno.edad); printf("\n"); }; // aqui termina while // no olvidar cerrar archivo y siempre fuera de while fclose(archdisco); getchar();getchar(); } Pocas observaciones 1. En fopen() se uso modo "a+". 2. En lugar de fwrite(), se usa fread() con los mismos cuatro parametros. También recordar que fread(), nos regresa la cantidad de registros que existian en el disco, por eso el ciclo while se convierte en falso cuando fread() regresa 0 y esto indica que se llego al fin del archivo. El diseño de impresión es responsabilidad de usted, compruebe este ejercicio con más de 40 registros, organícelos por pantallas Si todo esta bien, pero no quiero mirara todos los registros de una vez, que puedo hacer. Aquí esta la solución: #include <stdio.h> #include <conio.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // cargando clave a buscar printf("dame matricula buscar:"); int clave; scanf("%d",&clave);getchar(); //abriendo, leyendo,cargando estructura FILE *archdisco; archdisco = fopen("c:\\ac\\alumnos.dat","at+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyó 101 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO while(fread(&alumno,sizeof(alumno),1,archdisco)==1) { // desplegando estructura buscada if ( clave == alumno.matricula) { printf("MATRICULA =%d ",alumno.matricula); printf(" NOMBRE =%s ",alumno.nombre); printf(" MESES =%d ",alumno.edad); printf("\n"); } } // aqui termina while // no olvidar cerrar archivo y siempre fuera de while fclose(archdisco); getchar(); } FIGURA 10: Ventana de ejecución 3 Observaciones Recordemos que estamos haciendo ejercicio con archivos secuenciales, por consiguiente a estos no se pueden acceder directamente, si no a través de un recorrido, búsqueda lineal, ahora nos podemos dar cuenta porque este método de búsqueda no es el más apropiado, pensemos en más de mil registros Bueno no todo podemos hacerlo, algo para ustedes 1. Cómo realizar una búsqueda que contenga filtros, por ejemplo: mostrar por pantalla los estudiantes que sean mayores de edad. 2. El borrado es una de opciones de mayor cuidado, podemos hacer borrado físico y borrado lógico, el físico es desapareciendo el registro por completo de la unidad de almacenamiento, y el lógico (método que más degusta), es colocar una marca y tenerlo en cuenta al momento de realizar consultas u o operaciones con los archivitos, la gran ventaja es que no se pierdan los datos históricos, solo se los cubre. Es importante que usted indague mas sobre estos temas y trate de hacer 102 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ejercicios que complemente 3. Realizar un ejercicio que permita llevar registros de una colección de música, esto lo realizara mediante la utilización de menús y funciones. En este momento se presenta un ejercicio que muestra como se realiza las operaciones con archivos: #include <stdio.h> #include <stdlib.h> #include <io.h> #include <conio.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); FILE *arch1; FILE *arch2; arch1 = fopen("c:\\ac\\alumnos.dat","r+"); arch2 = fopen("c:\\ac\\temporal.dat","at+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyó while(fread(&alumno,sizeof(alumno),1,arch1)==1) { // OPERACIONES alumno.edad=alumno.edad +50; //grabando a temporal fwrite(&alumno,sizeof(alumno),1,arch2); }; // aqui termina while //cerrando archivos fclose(arch1); fclose(arch2); // removiendo y renombrando archivos 103 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO // recordar que directorios y archivos de datos no mas de 8 letras+ 3 de la extensión remove("C:\\AC\\ALUMNOS.DAT "); rename("C:\\AC\\TEMPORAL.DAT","C:\\AC\\ALUMNOS.DAT "); //avisando puts("EDADES MAS 50"); getchar(); } Ejecución 1 FIGURA 11. Ventana de Ejecución 4 Ejecución 2 FIGURA 12. Ventana de Ejecución 5 Como se observa la solución es muy sencilla solo se ocupa el registro original y los dos archivos el original y el temporal, se va leyendo registro a registro de archivo original al registro en memoria correspondiente, se realiza la operación u proceso deseado con el registro y se graba el registro modificado en el archivo temporal, al final se elimina archivo original y se renombra el archivo temporal. Lección 45: Archivos de acceso directo Esencialmente se comportan como los archivos antes vistos, pero su ventaja radica en su velocidad para acceder a la información, veamos algunos ejemplos 104 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Un archivo de acceso directo permite posicionar el apuntador de interno de registros, a cualquier registro determinado sin necesidad de pasar por todos los registros anteriores, usando las siguientes funciones. 1) int fseek(apuntador,long offset,origen); Esta función posiciona el apuntador de registro en el byte indicado. Regresa 0 si se pudo posicionar. apuntador=fopen("a:archivo.dat","r+"); fseek(apuntador,(long)(clave)*(sizeof(registro)),0); 0 ---> SEEK_SET principio del archivo. 1 ---> SEEK_CUR posicion actual. 2 ---> SEEK_END fin del archivo. 2) long ftell(apuntador); Regresa un valor long indicando la posición actual del cursor interno de registros de archivo. 3) int rewind(apuntador); Regresa el apuntador al principio del archivo. Ejemplo para hacer modificaciones: fseek(apuntador,(long)(clave)*(sizeof(registro)),0); fread(&registro,sizeof(registro),1,apuntador); hacer las modificaciones. rewind(apuntador); fseek(apuntador,(long)(clave)*(sizeof(registro)),0); fwrite(&registro,sizeof(registro),1,apuntador); Manos a la obra nuevamente, miremos el siguiente código que crea un archivo de este tipo, pero ahora utilizamos los datos de mascotas #include <stdio.h> #include <conio.h> #include <string.h> struct { int clave; 105 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO char nombre[30]; int edad;} mascota; void main() { clrscr(); //creando y cerrando el archivo en disco FILE *archdisco; archdisco = fopen("c:\\ac\\archivo1.dat","wb"); fclose(archdisco); printf("ARCHIVO CREADO SATISFACTORIAMENTE "); getchar(); } FIGURA 13. Ventana de Ejecución 6 Si ya es idéntico a un archivo de acceso secuencial, en apariencia pero démonos cuenta de lo siguiente: La diferencia es poca archdisco = fopen("c:\\ac\\archivo1.dat","wb"); Como observamos hay una b al final de la instrucción, lo que indica que el archivo es de tipo binario Por supuesto el ingreso de los datos será similar, veamos #include <stdio.h> #include <conio.h> #include <string.h> struct { int clave; char nombre[30]; int edad;} mascota; void main() { 106 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO clrscr(); // captura de campos printf("dame clave :");scanf("%d",&mascota.clave);getchar(); printf("dame nombre :");gets(mascota.nombre); printf("dame edad :");scanf("%d",&mascota.edad); // grabando a disco FILE *archdisco; archdisco = fopen("c:\\ac\\archivo1.dat","ab+"); fwrite(&mascota,sizeof(mascota),1,archdisco); fclose(archdisco); //avisando usuario printf("mascota insertado"); getchar(); } Observar que es completamente similar aL programa de archivos secuenciales, solo se recomienda y exige que las claves sigan la secuencia 0,1,2,3,4,5..... Ahora miremos como es una consulta #include <stdio.h> #include <conio.h> #include <string.h> struct { int clave; char nombre[30]; int edad;} mascota; void main() { clrscr(); // leyendo disco FILE *archdisco; archdisco = fopen("c:\\ac\\archivo1.dat","rb+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyó while(fread(&mascota,sizeof(mascota),1,archdisco)==1 107 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO { // desplegando estructuras printf("%d ",mascota.clave); printf("%s ",mascota.nombre); printf("%d ",mascota.edad); printf("\n"); }; // aqui termina while // no olvidar cerrar archivo y siempre fuera de while fclose(archdisco); getchar();; } En este caso no hay nada que comentar, puesto que se despliegan todos los registros Ahora tenemos el mismo ejercicio pero consultando un registro en especial, es realmente aquí donde vamos a encontrar verdades diferencias #include <stdio.h> #include <conio.h> #include <string.h> struct { int clave; char nombre[30]; int edad;} mascota; void main() { clrscr(); // cargando clave a buscar printf("dame clave buscar:"); int claveb; scanf("%d",&claveb); //abriendo, leyendo ,cargando estructura FILE *archdisco; archdisco = fopen("c:\\ac\\archivo1.dat","ab+"); // usar fseek() para posicionarse al principio de registro buscado fseek (archdisco, (long)(claveb)* sizeof(mascota), 0 ); // ahora se lee el registro fread(&mascota,sizeof(mascota),1,archdisco); 108 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO // desplegando estructura y asegurandose printf("%d ",mascota.clave); printf("%s ",mascota.nombre); printf("%d ",mascota.edad); printf("\n"); // no olvidar cerrar archivo fclose(archdisco); getchar(); } Como se desprende del programa usando fseek() es posible posicionarse en cualquier byte del archivo. El formato completo de fseek() es: fseek(apuntador,(long)(clave)*(sizeof(registro)),0); Donde los parámetros son: a. Apuntador al archivo en disco b. El segundo parámetro es el BYTE donde se quiere que empieza la lectura o grabación al archivo en disco. c. Este BYTE debe ser de tipo LONG así que si en algún programa de ejemplo ven fseek( , 387L, ); que no les llame la atención, es otra manera de hacerle cast a un dato. Como va a estar difícil que se apunte a un byte determinado, es por eso que en el programa mejor se deja que sea el propio servidor quien calcule el byte donde empieza un registro determinado con clave * sizeof o tamaño de registro. d. El tercer parámetro es a partir de donde se quiere posicionar el apuntador interno del archivo, los valores pueden ser: 0 ---> SEEK_SET principio del archivo. 1 ---> SEEK_CUR posicion actual. 2 ---> SEEK_END fin del archivo. Recordar que es muy importante que las claves grabadas en un archivo directo tengan la secuencia 0,1,2,3,4,5.....n 109 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Miremos otro ejercicio con operaciones de archivos, donde encontramos alguna diferencia sustancial con los archivos secuenciales #include <stdio.h> #include <io.h> #include <conio.h> #include <string.h> struct { int clave; char nombre[30]; int edad;} mascota; void main() { clrscr(); FILE *arch1; long r=0; arch1 = fopen("c:\\ac\\archivo1.dat","rb+"); while (fread(&mascota,sizeof(mascota),1,arch1)==1) { // sumando 100 a edad mascota.edad = mascota.edad + 100 ; // como ya se leyó se regresa el apuntador al principio del registro fseek(arch1,r*sizeof(mascota),0 ); // y se escribe el registro modificado al archivo fwrite(&mascota,sizeof(mascota),1,arch1); r=r+1; //turboc no permite i/o archivos sin un rewind, fseek, etc fseek(arch1,r*sizeof(mascota),0); }; // aqui termina while //cerrando archivo fclose(arch1); //avisando puts("EDADES + 100"); getchar(); } 110 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Como se observa la solución es muy sencilla solo se ocupa de: 1.- Leer fread() el registro, esto mueve el apuntador al siguiente registro. 2.- Modificar registro 3.- Regresar a posición anterior con fseek() 4.- Gegistro corregido 5.- Volver a usar un fseek() porque turboc no acepta i/o sin rewind, fseek, etc ver ayuda del compilador y no se ocupan los dos archivos como en el caso secuencial. 111 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ACTIVIDADES DE AUTOEVALUACION DE LA UNIDAD 3 1. Realice un programa que permite manejar el acceso de estudiantes a la sala de computo de la universidad, es responsabilidad de usted, realizar el análisis respectivo, lo que permita tener un programa funcional 2. Realizar un programa que permita elegir el formato (windows o linux) y permita escribir un determinado texto de cualquier tamaño y guardarlo en un archivo ascii con el formato especificado llamado c:\texto.txt. Los archivos de texto windows tienen como marcador de final de línea la secuencia CR (retorno de carro ascii=13) y LF (line feed ascii=10). Los de Linux solo tienen LF. 3. Realizar un programa que lea c:\texto.txt y proporcione las siguientes estadísticas: nº total de caracteres, nº de mayúsculas, nº de consonantes, nº de vocales y las cinco letras mas usadas 4. Escribir un programa que solicite palabras y las agregue a un fichero llamado c:\diccionario de forma que luego se puedan consultar las palabras una a una 112 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO BIBLIOGRAFIA AGUILAR, Luis. Fundamentos de programación, algoritmos y estructura de datos (segunda edición). España. McGRAW-HILL. AGUILAR, Luis. Fundamentos de programación, algoritmos, estructura de datos y Objetos (tercera edición). España. 2003. McGRAW-HILL. DEYTEL Y DEYTEL. Como programa C++(segunda Edición). Mexico D.F. 1999. Prentice Hall. McGRAW-HILL FARREL, Joyce, introducción a la programación lógica y diseño. Mexico D.F 2000. Thomson BROOKSHEAR, J. Glenn, Introducción a las ciencias de la Computación (Cuarta Edicón). Edición Española 1995. Addison-Wesley Iberoamericana Estructura de Datos en Pascal, Autor Aarón M. Tenenbaum, Moshe J. Augentein. Primera edición. Diseño y Administración de Base de Datos Gary W. Hansen, James V. Hansen, Segunda Edición. Guía de Estructura y Procesamiento de Datos Profesor David López, Segundo semestre U.N.I.R. (Maracaibo). Sitios WEB http://kataix.umag.cl/~mmarin/topinf/cs23/c++/Indice.html http://www.geocities.com/david_ees/Algoritmia/curso.html http://members.tripod.com/~MoisesRBB/c.html http://www.ilustrados.com/publicaciones/EpZVVEZpyEdFpAKxjH.p hp http://www.programacionfacil.com/cbueno/indice.html http://www.ilustrados.com/buscar.php http://www.lafacu.com/apuntes/informatica/estructura/default.htm http://www2.ing.puc.cl/iic1102/materia/cap10.htm http://www.uady.mx/sitios/matemati/enlinea/admin_arch/materiales/ material1.html http://coqui.lce.org/cadiaz/CEDU5120V/Contenido/ArchExt.htm http://www.itlp.edu.mx/publica/tutoriales/pascal/u8_8_8.html 113 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ANEXO Tipos de Datos C++ soporta básicamente tres tipos de dato: Enteros Reales (de coma o punto flotante) Caracteres La siguiente tabla indica el tipo de dato, la declaración y los limites en los cuales se pude mover una determinada variable Tipo Entero Entero Corto Entero Largo Entero sin Signo Entero con Signo Real Real Doble Real Largo Caracter Declaración Int A; Short Int A; Long Int A; Unsigned Int A; Signed Int A; Float A; Double A; Long DoubleA; Char A; Limite Inferior -32768 -128 2E -6 0 -65000 -3.4E37 -1.7E -304 3.4E -4932 -128 Limite Superior 32767 127 2E 6 65535 65000 3.4E 38 1.7E 308 1.1E 4932 127 TABLA 2. Tipos de datos Tipo de dato bool., esta incorporado en los compiladores que siguen la norma ANSI (Instituto Nacional Americano de Estándares) 2, cuyos valores pueden ser verdadeo8true) o falso (false), aunque en la realidad, muchos programadores no utilizan este tipo de datos, lo remplazan por una variable bandera numérica “bandera”, que pude tomar un valor 0 o 1 dependiendo la situación Operadores y expresiones Expresiones: “es un conjunto de datos compuesto de operandos unidos por operadores. Los operandos pueden ser constantes, variables o funciones” Operadores: se utilizan para procesar adecuadamente los operandos de acuerdo a sus tipos de datos. Por la característica de operación que realizan, los operadores también se dividen en: aritméticos, relacionales, lógicos, entre otros, a continuación se muestra una tabla identificando el orden de la categoría, el operador y una pequeña definición. 114 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO # 1 Categoría Mayor Operador () [] -> :: . Qué es (o qué hace) Invocación función Suscritos arreglos Selector indirección Resolución ámbito Selector componentes Negación lógica (NOT) Complemento binario Más Menos de de de de de 2 Unarios ! ~ + ++ en Preincremento postincremento -Predecremento postdecremento & Dirección * sizeof o o new delete 3 Multipli * / Valor en la dirección de Tamaño del operando en bytes Espacio en memoria dinámica Desasigna espacio en memoria Multiplicación División Resto en división entera Separador campo 4 Acceso % . -> Separador campo 115 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 5 Aditivos + - Más binario Menos binario Izquierda Derecha Menor que Menor o igual que Mayor que Mayor o igual que Igual a No igual a AND para bits XOR para bits OR para bits AND lógico OR lógico a?x: significa: "Si a Entonces x, SI_NO y" Asignamiento simple 6 Desplaza- << >> 7 Relacional < < > > 8 Igualdad == != 9 10 11 12 13 14 Y o exclusivo O Y O Condicional & ^ | && || ?: 15 Asignación * / Producto 116 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO % + & ^ | << >> 16 Coma , División Suma Diferencia AND sobre bits XOR sobre bits OR sobre bits Desplazamiento a la izquierda Desplazamiento a la derecha Separador de expresiones TABLA 3. Operadores Observación: Muchos de los operadores relacionados en el cuadro anterior, no se utilizan a lo largo de este curso. 117 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ANEXO Índice de funciones A Función Arc Librería Graphics Fichero de cabecera C graphics.h B Función Bar bar3d Librería Graphics Graphics Fichero de cabecera C graphics.h graphics.h C Función cgets Circle cleardevice Clearviewport Closegraph Clreol Clrscr Cprintf Cputs Cscanf Librería Conio Graphics Graphics Graphics Graphics Conio Conio Conio Conio Conio Fichero de cabecera C conio.h graphics.h graphics.h graphics.h graphics.h conio.h conio.h conio.h conio.h conio.h 118 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO D Función Delline Detectgraph Drawpoly Librería Conio Graphics Graphics Fichero de cabecera C conio.h graphics.h graphics.h E Función Ellipse Librería Graphics Fichero de cabecera C graphics.h F Función Fillellipse Fillpoly Floodfill Librería Graphics Graphics Graphics Fichero de cabecera C graphics.h graphics.h graphics.h G Función Getarccoords Getaspectratio Getbkcolor Getch Getche Getcolor Getdefaultpalette Librería Graphics Graphics Graphics Conio Conio Graphics Graphics Fichero de cabecera C graphics.h graphics.h graphics.h conio.h conio.h graphics.h graphics.h 119 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Getdrivername Getfillpattern Getfillsettings Getgraphmode Getimage Getlinesettings Getmaxcolor Getmaxmode Getmaxx Getmaxy Getmodename Getmoderange Getpalette Getpalettesize Getpass Getpixel Gettext Gettextinfo Gettextsettings Getviewsettings Getx Gety Gotoxy Graphdefaults Grapherrormsg Graphfreemem Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Graphics Conio Graphics Conio Conio Graphics Graphics Graphics Graphics Conio Graphics Graphics Graphics graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h conio.h graphics.h conio.h conio.h graphics.h graphics.h graphics.h graphics.h conio.h graphics.h graphics.h graphics.h 120 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Graphgetmem Graphresult Graphics Graphics graphics.h graphics.h H Función Highvideo Librería Conio Fichero de cabecera C conio.h I Función Imagesize Initgraph Inport Insline Installuserdriver Installuserfont Librería Graphics Graphics Conio Conio Graphics Graphics Fichero de cabecera C graphics.h graphics.h conio.h conio.h graphics.h graphics.h K Función Kbhit Librería Conio Fichero de cabecera C conio.h L Función Line Linerel Lineto Librería Graphics Graphics Graphics Fichero de cabecera C graphics.h graphics.h graphics.h 121 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Lowvideo Conio conio.h M Función Moverel Movetext Moveto Librería Graphics Conio Graphics N Función Normvideo Librería Conio Fichero de cabecera C conio.h Fichero de cabecera C graphics.h conio.h graphics.h O Función Outport Outtext Outtextxy Librería Conio Graphics Graphics Fichero de cabecera C conio.h graphics.h graphics.h P Función Pieslice Putch Putimage Putpixel Librería Graphics Conio Graphics Graphics Fichero de cabecera C graphics.h conio.h graphics.h graphics.h 122 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Puttext Conio conio.h R Función Rectangle Registerbgidriver Registerbgifont Restorecrtmode Librería Graphics Graphics Graphics Graphics Fichero de cabecera C graphics.h graphics.h graphics.h graphics.h S Función Sector Setactivepage Setallpalette Setaspectratio Setbkcolor Setcursortype Setfillpattern Librería Graphics Graphics Graphics Graphics Graphics Conio Graphics Fichero de cabecera C graphics.h graphics.h graphics.h graphics.h graphics.h conio.h graphics.h Setfillstyle Setgraphbufsize Setgraphmode Setlinestyle Setpalette Graphics Graphics Graphics Graphics Graphics graphics.h graphics.h graphics.h graphics.h graphics.h 123 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO Setrgbpalette Settextjustify Settextstyle Setusercharsize Setviewport Setvisualpage Setwritemode Graphics Graphics Graphics Graphics Graphics Graphics Graphics graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h graphics.h T Función Textattr Textbackground Textcolor Textheight Textwidth Librería Conio Conio Conio Graphics Graphics Fichero de cabecera C conio.h conio.h conio.h graphics.h graphics.h U Función Ungetch Librería Conio Fichero de cabecera C conio.h W Función Wherex Wherey Window Librería Conio Conio Conio Fichero de cabecera C conio.h conio.h conio.h 124 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO ANEXO Errores comunes de programación Buenas prácticas de programación Por: MIGUEL Á. TOLEDO MARTÍNEZ (http://www.galeon.com/neoprogramadores/soyc-cpp.pdf) • ERRORES COMUNES DE PROGRAMACIÓN • BUENAS PRÁCTICAS DE PROGRAMACIÓN ERRORES COMUNES DE PROGRAMACIÓN 1. Si al utilizar funciones de la biblioteca matemática no incluye el archivo de encabezado matemático, se producirá un error de sintaxis. Por cada función de la biblioteca estándar que utilice en un programa, debe indicar un archivo de encabezado estándar. 2. La omisión de la clase de valor devuelto de una definición de función es un error de sintaxis si el prototipo especifica una clase devuelto distinto de int. 3. No devolver un valor desde una función que supuestamente debe hacerlo es un error de sintaxis. 4. La devolución de un valor desde una función cuya clase de devolución se ha declarado como void es un error de sintaxis. 5. La declaración de parámetros de función de la misma clase como float x, y, en lugar de float x, float y, causará un error de compilación debido a que para cada parámetro de la lista de parámetros se requiera una clase de datos. 6. Un punto y coma después del paréntesis derecho de la lista de parámetros de una definición de función es un error de sintaxis. 7. Volver a definir un parámetro de función como variable local en la función es un error de sintaxis. 8. El ( ) de una llamada de función de hecho es un operador de C++. Provoca que se invoque a la función. Omitir el () de una llamada de función que no tiene argumentos no es un error de sintaxis. Sin embargo si pretendía que se llamara a la función, esto no sucederá. 125 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 9. Definir una función dentro de otra es un error de sintaxis. 10. Sucede un error de sintaxis si el prototipo de función, el encabezado de la función y las llamadas de la función no coinciden en el número, clase de datos y orden de los argumentos y parámetros, así como en el tipo de valor devuelto. 11. La omisión del punto y coma al final de un prototipo de función es un error de sintaxis. 12. Las llamadas de función que no sean iguales a su prototipo provocan errores de sintaxis. 13. Cuando el prototipo de función y la definición de la función no son iguales, sucede un error de sintaxis. 14. La conversión de una clase de datos más alto en la jerarquía de promoción a un tipo menor puede cambiar su valor. 15. Omitir el prototipo de una función cuando esta no ha sido definida antes de ser llamada por primera vez es un error de sintaxis. 16. El intento por generar números aleatorios con srand() en lugar de rand() es un error de sintaxis, debido a que la función srand() no devuelve un valor. 17. Asignarle el equivalente entero de una constante de enumeración a una variable del tipo de la enumeración es un error de sintaxis. 18. Si después de definir una constante de enumeración intenta asignarle otro valor, provocará un error de sintaxis. 19. Indicar varios especificadores de clase de almacenamiento para un identificador es un error de sintaxis. Sólo se le puede aplicar un especificador de clase de almacenamiento a un identificador. Por ejemplo, si incluye register, no incluya también auto. 20. Por lo general es un error de lógica utilizar el mismo nombre para un identificador dentro de un bloque interno que para un identificador que es parte de un bloque externo cuando, de hecho, el programador quiere que el identificador del bloque externo esté activo en el bloque interno. 21. El no devolver un valor desde una función recursiva cuando sea necesario, causará que casi todos los compiladores generen un mensaje de advertencia. 126 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 22. La omisión del estado primitivo o la escritura incorrecta del paso de recursión de modo que no converja al estado primitivo, provocará una recursión infinita y agotará tarde o temprano la memoria. Esto es análogo al problema de los ciclos infinitos en las soluciones iterativas (no recurrentes) La recursividad infinita también puede ser provocada al proveer una entrada no esperada. 23. La codificación de programas que dependen del orden de evaluación de los operandos de los operadores que no sean &&, ||, ?: ni coma (,) puede generar errores, pues los compiladores no necesariamente evaluarán los operandos en el orden que el programador espera. 24. Es un error de lógica que una función no recursiva se llame a sí misma, ya sea directa o indirectamente, a través de otra función. 25. Los programas en C++ no se compilan a menos que se indiquen prototipos de función para todas las funciones o que se definan las funciones antes de usarlas. 26. Debido a que los parámetros de referencia se mencionan sólo por nombre en el cuerpo de la función llamada, el programador podría tratarlos inadvertidamente como parámetros de una llamada por valor. Esto puede provocar efectos secundarios inesperados si el invocador modifica las copias originales de las variables. 27. Declarar múltiples referencia en una instrucción suponiendo que el & se distribuye a través de una lista de nombres de variables separada por comas. Para declarar las variables x, y y z como referencias a un entero emplee la notación int &x = a, &y = b, &z = c; en lugar de la notación incorrecta int& x = a, y = b, z = c; o la otra notación incorrecta común int &x, y, z. 28. No inicializar una variable de referencia al declararla es un error de sintaxis. 29. Intentar reasignar una referencia declarada previamente como alias de otra variable es un error de lógica. El valor de la otra variable simplemente se le asigna a la localidad para la que la referencia es un alias. 30. Devolver un apuntador o referencia a una variable automática en una función llamada es un error de lógica. Algunos compiladores presentarán un mensaje de aviso al encontrar esto en un programa. 31. Especificar e intentar utilizar un argumento predeterminado que no sea 127 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO el de más a la derecha (último) sin tomar los predeterminados de todos los argumentos a su derecha es un error de sintaxis. 32. Intentar acceder a una variable no global desde un bloque exterior por medio del operador unario de resolución de alcance es un error de sintaxis si no existe una variable global con el mismo nombre que la variable del bloque exterior, y es un error de lógica si es que existe. 33. La creación de funciones sobrecargadas con listas de parámetros idénticas y diferentes tipos de devolución es un error de sintaxis. 34. Una función a la que se le han omitido los argumentos predeterminados podría ser llamada de manera idéntica a otra función sobrecargada; esto es un error de sintaxis. Por ejemplo, cuando un programa tiene tanto una función que explícitamente no recibe argumentos como otra con el mismo nombre que contiene sólo argumentos predeterminados, sucede un error de sintaxis cuando se intenta utilizar dicho nombre de función en una llamada que no pasa argumentos. 35. No poner la palabra clave class antes de cada parámetro de tipo de una plantilla de función es un error de sintaxis. 36. No emplear todos los parámetros de tipo de una plantilla de función en la firma de la función es un error de sintaxis. BUENAS PRÁCTICAS DE PROGRAMACIÓN 1. Familiarícese con el vasto conjunto de funciones y clases de la biblioteca estándar de C++. 2. Ponga una línea en blanco entre las definiciones de función para separarlas y simplificar la lectura del programa. 3. Aunque lo predeterminado cuando se omite el tipo de devolución es int, siempre indique explícitamente el tipo de valor de devuelto. 4. Aunque no es incorrecto hacerlo, no utilice los mismos nombres para los argumentos pasados a una función y para los parámetros correspondientes de la definición de la función. Con esto se evitan ambigüedades. 128 UNIVERSIDAD NACIONAL ABIERTA Y A DISTANCIA – UNAD ESCUELA DE CIENCIAS SOCIALES, ARTES Y HUMANIDADES CONTENIDO DIDÁCTICO DEL CUSO: 90001 – METODOLOGÍA DE TRABAJO ACADÉMICO 5. Seleccione nombres de función y de parámetros que tengan significado para simplificar la lectura de los programas y para ayudar a evitar demasiados comentarios. 6. Muchos programadores indican los nombres de los parámetros en los prototipos de las funciones con fines documentativos. El compilador ignora estos nombres. 7. Ponga con mayúsculas la primera letra de los identificadores que sean nombres de clase definidos por el usuario. 8. Sólo indique letras mayúsculas para los nombres de constantes de enumeración. Con esto se resaltan las constantes en el programa, recordándole al programador que las constantes de enumeración no son variables. 9. Utilice enumeraciones en lugar de constantes enteras; con esto sus programas serán más claros. 10. Evite los nombres de variables que oculten nombres en los alcances exteriores. Esto puede lograrse evitando utilizar identificadores duplicados en el programa. 11. Siempre indique prototipos de función, aun cuando sea posible omitirlos al definir las funciones antes de utilizarlas. Al indicar los prototipos se evita enlazar el código al orden en que se definen las funciones (el cual puede cambiar fácilmente con la evolución del programa) 12. El calificador inline sólo debe utilizarse con funciones pequeñas de uso frecuente. 13. Los argumentos predeterminados pueden simplificar la escritura de las llamadas de función. De cualquier forma, algunos programadores sienten que resulta más claro indicar explícitamente todos los argumentos. 14. Evite utilizar variables con el mismo nombre cuyos fines sean diferentes. Aunque es válido bajo varias circunstancias, puede generar confusiones. 15. Sobrecargar funciones que realicen tareas puede simplificar la lectura de los programas. muy relacionadas 129
Copyright © 2024 DOKUMEN.SITE Inc.