Progra
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
4,502
On Slideshare
4,501
From Embeds
1
Number of Embeds
1

Actions

Shares
Downloads
93
Comments
0
Likes
1

Embeds 1

http://www.slideshare.net 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Fundamentos de programaciónPrograma Desarrollado Cuatrimestre dos Programa de la asignatura: Fundamentos de Programación Clave: 150910206 ESAD Agosto, 2010Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 1
  • 2. Fundamentos de programaciónPrograma Desarrollado Índice I. Información general de la asignatura 3 a. Ficha de identificación...................................................................................................................................... 3 b. Descripción ........................................................................................................................................................ 3 c. Propósito ............................................................................................................................................................ 4 II. Competencia(s) a desarrollar 5 Competencia general:........................................................................................................................................... 5 Competencias específicas: .............................................................................................................................. 5 III. Temario 6 IV. Metodología de trabajo 8 V. Evaluación 10 VI. Materiales de apoyo 12 VII. Desarrollo de contenidos por unidad 13 Unidad 1: Introducción a la computadora y desarrollo de software ........................................................... 13 Unidad 2: Diseño de algoritmos ........................................................................................................................ 31 Unidad 3: Introducción al lenguaje C ............................................................................................................... 49 Unidad 4: Estructuras de control....................................................................................................................... 78 Unidad 5: Estructuras de datos ....................................................................................................................... 118 Unidad 6: Funciones ......................................................................................................................................... 148Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 2
  • 3. Fundamentos de programaciónPrograma Desarrollado I. Información general de la asignatura a. Ficha de identificación Ingeniería en logística y transporte, Ingeniería en Nombre de la Licenciatura o Ingeniería: telemática Nombre del curso o asignatura Fundamentos de Programación Clave de asignatura: 150910206 Bases de Datos, Análisis Orientado a Objetos, Seriación: Programación Orientada a Objeto Cuatrimestre: Dos Horas contempladas: 72 b. Descripción La asignatura de Fundamentos de Programación tiene como meta principal que desarrolles las competencias necesarias para construir programas que resuelvan problemas reales. Constituye un pilar primordial para aquellos alumnos que, como tú, están estudiando una carrera relacionada con computación -como Desarrollo de Software y Telemática- pues los conocimientos y habilidades que desarrollen en este curso serán indispensables para la varias de las asignaturas subsecuentes del plan de estudios de ambas ingenierías, tal es el caso de bases de datos, programación orientada a objetos, programación web, estructura de datos, entre otras. El lenguaje de alto nivel que se ha elegido para implementar los programas es C, ya que es uno de los lenguajes, estructurados y modulares, utilizados actualmente; además cuenta con entornos de trabajo de software libre, como el que utilizaremos llamado Dev-C. Para facilitar que desarrolles las competencias establecidas, los contenidos del curso se han dividido de forma estratégica en seis unidades. En la primera se delinea el concepto de computadora y su funcionamiento, para ello se describen los elementos que la integran; posteriormente, se hace una aproximación a los lenguajes de programación y los paradigmas que existen en la actualidad, resaltando la programación modular y estructurada. En la siguiente unidad se expone la metodología de la programación y se introduce el concepto de algoritmo, que es la solución sistemática de problemas,Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 3
  • 4. Fundamentos de programaciónPrograma Desarrollado así que también se presentan dos formas de representación: el pseudocódigo y los diagramas de flujo. Asimismo, se ilustran las estructuras secuenciales, selectivas y repetitivas. A continuación, en la unidad tres, se presentan los elementos básicos para construir un programa simple en lenguaje C: datos, contantes, variables y las operaciones básicas de entradas/salidas para describir el uso de los operadores aritméticos, relacionales y lógicos para la manipulación de operaciones y expresiones en C. En la unidad cuatro se distinguen y utilizan las distintas estructuras de control, tanto selectivas (if, if- else, switch) como repetitivas (while, do-while, for), que ofrece el lenguaje C; se introduce su representación en diagrama de flujo y algoritmo, además de su sintaxis en C. En la unidad cinco se introducen las estructuras de datos: arreglos y registros, se explica qué son, cómo funcionan y para qué sirven, además, se plantean problemas en donde su uso es indispensable para su resolución. Por último, en la unidad seis se reconoce la importancia de la programación modular, construyendo soluciones modulares utilizando funciones en lenguaje C. c. Propósito El curso tiene como finalidad proporcionarte las bases para que comiences a desarrollar programas estructurados que solucionen problemas simples, a través del desarrollo de algoritmos en pseudocódigo y diagrama de flujo y su codificación en lenguaje C, además se te describe el proceso de compilación de un programa y su ejecución identificando los elementos de la computadora que intervienen en cada paso.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 4
  • 5. Fundamentos de programaciónPrograma Desarrollado II. Competencia(s) a desarrollar Competencia general: Desarrollar programas estructurados y modulares que resuelvan problemas simples, mediante el análisis del problema, el diseño de un algoritmo y su codificación en lenguaje C. Competencias específicas: • Describir los elementos de la computadora y el ciclo de vida de software mediante el análisis un programa simple, con el fin de identificar los pasos que se realizan para construirlo y determinar qué elementos de la computadora intervienen en su ejecución. • Diseñar algoritmos para resolver problemas mediante su representación en un diagrama de flujo y la elaboración del pseudocódigo. • Utilizar el lenguaje de programación C para resolver problemas a través de la implementación de algoritmos secuenciales. • Utilizar estructuras de control selectivas y repetitivas para resolver problemas simples a través del desarrollo de programas en lenguaje C. • Utilizar estructuras de datos para almacenar y manipular los datos de un programa por medio del desarrollo de programas en lenguaje C. • Implementar funciones para resolver problemas a través del desarrollo de programas modulares escritos en lenguaje C.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 5
  • 6. Fundamentos de programaciónPrograma Desarrollado III. Temario 1. Introducción a la computadora y desarrollo de software 1.1. ¿Qué es una computadora? 1.2. Estructura y funcionamiento de una computadora 1.2.1. Modelo de Von Neumann 1.2.2. Ejecución de programas en la computadora 1.2.3. Almacenamientos de programas y datos 1.3. Lenguajes de programación 1.3.1. Evolución de los lenguajes de programación 1.3.2. Paradigmas de los lenguajes de programación 1.4. Ciclo de vida del software 2. Diseño de algoritmos 2.1. Concepto de algoritmo y características 2.2. Representaciones de algoritmos 2.2.1. Pseudocódigo 2.2.2. Diagrama de flujo 2.3. Estructuras de control 2.3.1. Secuenciales 2.3.2. Selectivas 2.3.3. Repetitivas 3. Introducción al lenguaje C 3.1. Componentes de un programa 3.1.1. Instrucciones 3.1.2. Comentarios 3.1.3. Palabras reservadas 3.1.4. Estructura general de un programa 3.2. Tipos de datos 3.3. Variables y constantes 3.3.1. Identificadores 3.3.2. Declaración e inicialización de variables 3.3.3. Tipos de constantes 3.3.4. Declaración de constantes 3.4. Expresiones matemáticas 3.4.1. Tipos de operadores 3.4.2. Evaluación de expresiones 3.5. Bibliotecas y funciones 3.5.1. Funciones matemáticas 3.5.2. Funciones de entrada y salida 3.6. Codificación de algoritmosEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 6
  • 7. Fundamentos de programaciónPrograma Desarrollado 4. Estructuras de control 4.1. Estructuras selectivas 4.1.1. Estructura selectivasimple (if) 4.1.2. Estructura selectiva doble (if-else) 4.1.3. Estructura selectiva múltiple (switch-case) 4.2. Estructuras repetitivas 4.2.1. Estructura Mientras (while) 4.2.2. Estructura Desde-mientras (for) 4.2.3. Estructura Hacer-mientras (do-while) 4.3. Estructuras anidadas 5. Estructuras de datos 5.1. Arreglos 5.1.1. Definición y tipos 5.1.2. Declaración e inicialización 5.1.3. Acceso a los elementos de un arreglo 5.1.4. Ciclos y arreglos 5.1.5. Cadenas 5.2. Estructuras 5.2.1. Definición, declaración e inicialización 5.2.2. Acceso a los elementos 6. Funciones 6.1. Diseño descendente 6.2. Definición, declaración e invocación de funciones en C 6.3. Alcance de las variables 6.4. Paso de parámetros 6.4.1. Por valor 6.4.2. Por referenciaEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 7
  • 8. Fundamentos de programaciónPrograma Desarrollado IV. Metodología de trabajo Para trabajar en esta asignatura, se ha propuesto la metodología del Aprendizaje Basado en Problemas, pues debido a la naturaleza de los contenidos, tendrás que resolver problemas de manera constante para poner en práctica lo aprendido. Como el propósito de este curso es que desarrolles programas de software que resuelvan problemas simples, por cada unidad se ha propuesto uno o más problemas a partir de los cuales sete presentan los contenidos correspondientes, la intención de esto es que primero se te planteen los problemas para que los analices y posteriormente se te presente la solución de los mismos mediante algoritmos o programas; lo que se busca es que alcances las competencias específicas de cada unidad a través de, primero la observación y el análisis de los problemas ejemplo que te ayudarán a identificar patrones comunes, y posteriormente la resolución de problemas un poco más complejos a través del desarrollo de estrategias de solución similares. Ahora bien, para que puedas resolver un problema mediante un programa de computadora, primero tienes que tener claro el funcionamiento principal de la misma, tanto para almacenar la información como para llevar a cabo el conjunto de instrucciones que integran la solución de un problema, es decir, el programa. Por tal motivo, en la primera unidad se expone la arquitectura tradicional de las computadoras conocida como el Modelo de Von Neumann a través de la cual se te explica cómo se almacenan los programas y los datos de un problema en una computadora y qué elementos intervienen en la ejecución de las instrucciones. Lo anterior se expone utilizando un programa que se encarga de calcular el área de un rectángulo, de esta manera podrás aprender los contenidos mediante un ejemplo simple. Posteriormente, se describen los pasos que llevan a la construcción de un programa, nuevamente, utilizando un ejemplo simple. La evaluación de esta unidad se realizará mediante una prueba de opción múltiple en la que se incluyen los temas expuestos. Para exponer los temas relacionados con la elaboración de los algoritmos, se recurre al mundo de la ardilla, un ejemplo en el cual se supone que una ardilla ha sido entrenada para realizar un conjunto limitado de instrucciones precisas, de tal manera que para solucionar un problema únicamente se puede recurrir a este conjunto. De esta forma se pretende que reconozcas intuitivamente que la computadora –al igual que la ardilla– sólo es capaz de realizar un conjunto limitado de instrucciones precisas, por lo que la solución de un problema sólo puede incluir instrucciones reconocidas por ésta. Así mismo, mediante este ejemplo, se te muestra qué es un algoritmo, cuáles son sus características y sus formas de representación; posteriormente se te presentan las estructuras de control básicas de la programación estructurada ejemplificando su uso a través de la construcción de algoritmos que dirigen a la ardilla en la realización de una tarea específica. Así se te introduce en el diseño de soluciones estructuradas de problemas simples representadas de manera formal, ya sea con un diagrama de flujo o con un pseudocódigo. Es importante mencionar que la ventaja de presentar el tema desde un ejemplo tan simple y limitado como el mundo de la ardilla, facilita que puedas proponer soluciones estructuradas en un lenguaje específico, que es justo de lo que se trata la programación.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 8
  • 9. Fundamentos de programaciónPrograma Desarrollado En las siguientes unidades la estrategia de aprendizaje es similar, se te presentan los contenidos al mismo tiempo que se utilizan para solucionar problemas, sólo que en este caso se proponen situaciones reales que te son familiares, de tal manera que cuentes con los conocimientos necesarios para solucionarlos y solo te tengas que enfocar en representar la solución utilizando las estructuras de control definidas, es decir, las instrucciones permitidas. En general, en las actividades formativas deberás realizar algunas modificaciones a los algoritmos o programas presentados en los contenidos, o bien, los escribirás en lenguaje C para que puedas ver su ejecución, además debes ingresar al foro de cada unidad para realizar los comentarios que tengas al respecto. Es importante que realices cada una de las actividades propuestas por que a través de ellas se complementan los temas expuestos. De igual manera, para poner en práctica los conocimientos adquiridos y evaluar que se haya alcanzado la competencia específica a lo largo del curso desarrollarás un proyecto integrador que consiste en el planteamiento, análisis, diseño de la solución e implementación de un programa que involucre el uso de todas las estructuras de control y de datos que se estudiarán. En este caso, tú serás el responsable de plantear el problema que deseas solucionar y junto con tu facilitador delimitarás las fases y/o versiones que realizarás en cada unidad. El papel que juega tu facilitador (a) en el proceso de aprendizaje es fundamental, pues su tarea es guiarte en la solución de problemas a partir del análisis que tú realices y las ideas o dudas que te surjan con el mismo. El facilitador por ningún motivo debe darte la solución completa de un problema, en lugar de ello debe propiciar el intercambio de ideas y experiencias de los estudiantes mediante foros de discusión, favoreciendo el aprendizaje colaborativo; si después de esto siguen existiendo dudas se recomienda que resuelva problemas similares para que tanto tú como tus compañeros refuercen los conocimientos y habilidades de una manera inductiva y así logren dar solución al problema en cuestión. Por lo anterior, existe un foro de discusión general en el cual cualquiera puede exponer sus dudas respecto a un tema o problema para que sean retroalimentados por tu facilitador y los compañeros de grupo. Es importante que el facilitador promueva un clima de respeto mutuo y libertad de expresión para que tanto tú como tus compañeros se sientan cómodos al externar sus dudas y propuestas, permitiendo la disensión de manera fundamentada y deferente. En lo referente a la evaluación de las actividades y evidencias, tu facilitador debe revisar cuidadosamente los entregables que hagas y retroalimentarlos de manera positiva, clara y concisa; haciendo evidente el avance que hayas alcance y sin perder de vista que los errores que comentas debe ser utilizados a favor de tu aprendizaje, por lo que debe prestar principal atención a éstos indicándote en qué consiste el error y cómo se corrige, fundamentando su anotación en los contenidos del curso.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 9
  • 10. Fundamentos de programaciónPrograma Desarrollado V. Evaluación La evaluación del curso corresponderá en su totalidad al trabajo en el aula virtual, que se divide en: las actividades formativas, equivalentes al 20% de toda la calificación y, el portafolio de evidencias que representa el 80% restante. De tal manera que, mediante las actividades formativas propuestas para cada unidad se refuerzan los conocimientos abortados y se desarrollan las habilidades que el requieres para solucionar por ti mismo problemas similares a los que se presentan y resuelven. En cambio, el propósito de las evidencias de aprendizaje propuestas para cada unidad (portafolio de evidencias) es comprobar que hayas alcanzado la competencia específica, de tal manera que el conjunto de todas las evidencias sean la prueba de que has logrado la competencia general. Es requisito indispensable que realices y/o entregues todas las actividades formativas y las evidencias de aprendizaje en el tiempo establecido, de esta manera se garantiza la retroalimentación en tiempo y forma que tu facilitador realizará para que tengas claro el avance de tu aprendizaje, lo cual te servirá para que desarrolles las actividades o evidencias subsecuentes. En el caso de las evidencias de aprendizaje la calificación se obtendrá a partir de las escalas establecidas para cada una, las cuales conocerás de antemano. En el caso de las actividades formativas, serán revisadas por el facilitador(a), quién te hará llegar una retroalimentación que te ayude a ver tu avance y los puntos que puedes mejorar. Únicamente se considerará aprobado el curso si tu promedio total es mayor o igual a la calificación mínima establecida por el ESAD. Los trabajos que se tomarán como evidencias de aprendizaje son: Unidad 2: Planteamiento del problema Especificación clara y precisa del problema que se resolverá mediante un programa en C Unidad 3: Análisis del problema Datos de entrada, salida y bosquejo de la solución. Unidad 4: Programa en C. Estructuras de control. Primera versión de la solución del problema (algoritmo y codificación) que incluya estructuras secuenciales, selectivas y repetitivas. Unidad 5: Programa en C. Estructuras de datos Segunda versión de la solución del problema (algoritmo y codificación) que incluya estructuras de datos. Unidad 6: Programa en C. Modular (versión final) Entrega final del programa que soluciona el problema de forma modularEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 10
  • 11. Fundamentos de programaciónPrograma Desarrollado A continuación se te presenta la ponderación de las evidencias de aprendizaje, las cuales tendrás que enviar a tu facilitador (a) por medio del Portafolio de Evidencias. Recuerda que el 100% de éstas, equivale al 80% de la calificación final del curso en la que se promedian actividades formativas y sumativas: ACTIVIDAD PORCENTAJE Evidencia de la unidad 2 13% Evidencia de la unidad 3 17% Evidencia de la unidad 4 36% Evidencia de la unidad 5 17% Evidencia de la unidad 6 17% Total 100%Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 11
  • 12. Fundamentos de programaciónPrograma Desarrollado VI. Materiales de apoyo Bibliografía básica: Böhm, C., & Jacopini, G. (1966). Flow diagrams, Turing machines, and languages only with two formation rules". Communications of the ACM, 9 (5), 366-371. Cairó, O. (2005). Metodología de la programación: Algoritmos, diagramas de flujo y programas. México, D.F.: Alfaomega. Guerrero, F. (s.f.). mailxmail.com. Recuperado el 15 de 8 de 2010, de http://www.mailxmail.com/curso- introduccion-lenguaje-c Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. España: Mc Graw Hill. Kernighan, B., & Ritchie, D. (1991). El lenguaje de programción C. México: Prentice-Hall Hispanoamericana. López, L. (2005). Programación estructurada en lenguaje C. México: Alfaomega. Reyes, A., & Cruz, D. (2009). Notas de clase: Introducción a la programación. México, D.F.: UACM. Villela, H. T. (20 de agosto de 2010). Manual de C. Obtenido de http://www.fismat.umich.mx/mn1/manual/ Viso, E., & Pelaez, C. (2007). Introducción a las ciencias de la computación con Java. México, D.F.: La prensas de ciencias, Facultad de Ciencias, UNAM.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 12
  • 13. Fundamentos de programaciónPrograma Desarrollado VII. Desarrollo de contenidos por unidad Unidad 1: Introducción a la computadora y desarrollo de software Propósitos de la unidad En esta unidad: • Identificarás los conceptos básicos relacionados con la computadora y los lenguajes de programación. • Distinguirás los elementos de una computadora que intervienen en la ejecución de un programa a través del modelo de Von Neumann. • Distinguirás los paradigmas de programación y los lenguajes asociados a éstos. • Reconocerás las fases que se siguen para solucionar un problema mediante la computadora. Competencia específica Describir los elementos de la computadora y el ciclo de vida de software mediante el análisis un programa simple, con el fin de identificar los pasos que se realizan para construirlo y determinar qué elementos de la computadora intervienen en su ejecución. Introducción Bienvenido a la primera unidad del curso fundamentos de programación, en esta unidad estudiaremos qué son las computadoras y cómo pueden ayudarnos para resolver problemas. Lo primero que tienes que tener claro es que las computadoras no poseen inteligencia alguna, ya que por sí solas no son capaces de resolver ningún problema, su importancia está en la capacidad de datos que pueden almacenar y manipular; de tal manera que para lograr nuestro fin– resolver problemas mediante la computadora – es necesario desarrollar programas escritos en un lenguaje de programación para que puedan ser ejecutados por una computadora. Los orígenes de las computadoras se remontan a dispositivos mecánicos como el ábaco que sirve para contar y ya se utilizaba en el año 2000 a.C, seguido de la Pascalina que fue la primera calculadora mecánica del mundo inventada por el francés Blaise Pascal en el año de 1642, y que después fue perfeccionada por Gottfried Leibniz. Dos siglos después, en el año de 1834, Charles Babbage anticipó la estructura de la computadora electrónica moderna, sin lograr su objetivo dadas las limitaciones de ingeniería del siglo XIX. Fue hasta la segunda guerra mundial (1936) que se cumplieron sus expectativas, cuando Alan Turing desarrolló la primera computadora electromecánica: el Colossus,Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 13
  • 14. Fundamentos de programaciónPrograma Desarrollado encargada de descifrar los mensajes alemanes escritos en código Enigma. 1 Una década después Wallace J Eckert y Jonh W. Mauchly construyeron la primera computadora digital totalmente electrónica, llamada ENIAC (por sus siglas en inglés Electronic Numerical Intregrator And Computer). La característica principal de este invento es que se trataba de un componente de propósito general, ya que se podía programar para que resolviera diferentes problemas, pero la programación se realizaba modificando o reconstruyendo algunas partes del hardware. Con el fin de remediar esto, en 1945 el matemático Jonh Von Neumann propuso una arquitectura de computadoras cuya programación no era por medio de cables sino por medio de la creación de programas, a la que se le conoce como Modelo de Von Neumann, y que es, hasta hoy en día, la arquitectura base de las computadoras. Por lo anterior, en esta unidad se estudiarán los siguientes temas: el Modelo de Von Neumann, los pasos para realizar un programa y los principales paradigmas y lenguajes de programación utilizados actualmente. Actividad 1. Foro Fundamentos de programación Para facilitar el estudio de la asignatura, hemos creado un foro de discusión general, a través del cual podrás comentar cualquier asunto relacionado con Fundamentos de programación. Accede al foro desde el aula virtual. 1.1 ¿Qué es una computadora? Para fines de este curso entenderemos que una computadora es una máquina electrónica que recibe datos de entrada y los procesa de acuerdo al conjunto de instrucciones, llamado programa, para obtener nuevos datos que son el resultado del proceso, tal como se ilustra en la siguiente figura. 1 Se conoce como código Enigma al lenguaje de codificación de la máquina con el mismo nombre, utilizada en Europa a inicios de 1920, para cifrar y descifrar mensaje.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 14
  • 15. Fundamentos de programaciónPrograma Desarrollado Figura 1.1:Computadora Lo anterior nos lleva a clasificar los componentes de una computadora en dos clases: hardware y software. Los recursos de hardware son todos aquellos elementos de la computadora que se pueden palpar, como por ejemplo: el monitor, el teclado, el disco duro, la memoria, entre otros. En cambio, los recursos de software son aquellos elementos intangibles sin los cuales la computadora no funcionaría, esto es, el soporte lógico: programas y datos, entre los cuales se encuentran los sistemas operativos, editores de texto, compiladores, bases de datos, videojuegos, entre otros. 1.2 Estructura y funcionamiento de una computadora Si nos cuestionamos ¿cómo funciona y se estructura internamente la computadora?, ¿cómo se obtienen los resultados? y ¿cómo se guardan los programas y datos en la memoria?, cuando tenemos un primer acercamiento con estos equipos, a pesar de manejarlos a diario, estas preguntas no son tan fáciles de contestar. Es por eso que en esta sección explicaremos y responderemos a estos cuestionamientos mediante el Modelo de Von Neumann. 1.2.1 Modelo de Von Neumann El Modelo de Von Neumann propone que tanto el programa como los datos sean almacenados en la memoria, de esta forma la computadora no tendría que reconstruirse, pues para programarla únicamente debe introducirse el programa por el dispositivo indicado, y posteriormente alimentar con los datos de entrada para que calcule la salida correspondiente. Los elementos que componen esta arquitectura son: la unidad central de procesamiento integrada por la unidad aritmética-lógica y la unidad de control, la memoria y los dispositivos de entrada/salida. A continuación se describe brevemente la función de cada uno de los elementos que integran el Modelo de Von Neumann:Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 15
  • 16. Fundamentos de programaciónPrograma Desarrollado • Unidad Central de Procesamiento(CPU, Central Process Unit), controla y coordina la ejecución de las instrucciones, para ello utiliza la Unidad Aritmético-Lógica encargada del procesamiento de los datos y la Unidad de Control para el procesamiento de las instrucciones. o Unidad Aritmético-Lógica(ALU, Arithmetic Logic Unit), realiza todas las operaciones aritméticas (suma y resta) y lógicas (operaciones del Algebra de Boole). Además de los circuitos que le permiten realizar dichas operaciones, la ALU incluye un elemento auxiliar donde se almacenan temporalmente los datos que manipula conocido como acumulador o registro temporal (TR, Temporal Register). o Unidad de Control(CU, Control Unit), se encarga de leer las instrucciones almacenadas en memoria, decodificarlas y después enviar las señales a los componentes que están involucrados en su ejecución, para lo cual tiene dos elementos auxiliares el Contador del Programa(PC, Program Counter) y el Registro de Instrucción(IR, Instruction Register). En el IR se guarda temporalmente la instrucción que debe ser ejecutada, mientras que en el PC se almacena la dirección de memoria que contiene la siguiente instrucción que se ejecutará. • Memoria principal, es la parte de la computadora donde se almacenan los datos y las instrucciones durante la ejecución de un programa. Físicamente está compuesta por circuitos integrados. Las computadoras actuales cuentan con un área de memoria de sólo lectura – a la que se le conoce como memoria de tipo ROM (Read Only Memory) –y otra en la cual es posible escribir y leer datos – denominada de tipo RAM (Random Access Memory). La memoria RAM tiene el inconveniente de ser volátil pues al apagarse la computadora los datos almacenados se pierden. Para resolver este inconveniente, se cuenta con otro tipo de memoria, denominada memoria secundaria, en ella se pueden almacenar una gran cantidad de información permanentemente, mientras el usuario no la borre. La desventaja de este tipo de dispositivos es que no son tan rápidos como la memoria RAM. Los discos duros, los discos ópticos (CD o DVD), la memoria flash (USB) y las cintas magnéticas, entre otras, son ejemplos de dispositivos de almacenamiento secundario. • Dispositivos de entrada y salida (Input/Output), son responsables de la comunicación con el usuario del sistema. Los dispositivos de entrada permiten introducir en la computadora datos e instrucciones, mismas que son transformadas en señales binarias de naturaleza eléctrica para almacenarlas en la memoria. Por otro lado, los dispositivos de salida permiten enviar los resultados a los usuarios de las computadoras, transformando las señales eléctricas binarias en información que éstos puedan comprender. El teclado está considerado como el dispositivo de entrada estándar pero existen otros del mismo tipo, por ejemplo: el ratón, el escáner, la lectora óptica, el micrófono o la tabla digital. A su vez el monitor es el dispositivo de salida estándar; otros ejemplos de dispositivos de salida son: impresora, bocinas, plotter, etc.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 16
  • 17. Fundamentos de programaciónPrograma Desarrollado Es así que todas las unidades de la computadora se comunican a través del sistema de buses que son cables mediante los cuales se envían señales y dependiendo de la información que transmiten se clasifican en: a) El bus de direcciones transmite la dirección de memoria de la que se quiere leer o en la que se quiere escribir. b) El bus de control selecciona la operación a realizar en una celda de memoria (lectura o escritura). c) El bus de datos transmite el contenido desde o hacia una celda de memoria seleccionada en el bus de direcciones según la operación elegida en el bus de control sea lectura o escritura. Ahora ya sabemos cómo está estructurada internamente la computadoras, qué elementos la integran y cuál es la función de cada uno de ellos, el siguiente paso es descubrir cómo colaboran para llevar a cabo la ejecución de un programa, en seguida lo explicamos: los datos de entrada que requiere un programa se introducen a la computadora, a través de los dispositivos de entrada; posteriormente se almacenan en la memoria RAM, para que la CPU pueda procesarlos, conforme a las instrucciones del programa, hasta obtener el resultado deseado, mismo que envía al usuario por medio de los dispositivos de salida. Todas estas acciones son coordinadas por la unidad de control que envía las señales y datos a cada uno de los dispositivos de la computadora involucrados en la ejecución de las instrucciones del programa a través del sistema de buses. En la siguiente sección se describe con mayor detalle este proceso. 1.2.2Ejecución de programas en la computadora Para que entender mejor lo que sucede en el interior de la CPU al ejecutar cualquier programa, a continuación se describen de manera general los pasos que se realizan, una vez que el programa y los datos fueron almacenados en la memoria principal: a) Primero, la unidad de control consulta en la memoria la instrucción indicada en el contador del programa y la almacena en el registro de instrucciones, actualizando el contador del programa con la dirección de memoria de la siguiente instrucción. b) Después de que se almacenó la instrucción en el registro del programa, la unidad de control se encarga de decodificarla, detectando qué dispositivos están implicados en su ejecución, estos pueden ser: la ALU, cuando se tiene que hacer una operación; los dispositivos de entrada y/o salida, cuando se tiene que enviar o recibir un dato; o la memoria, si se quiere guardar o consultar un dato; posteriormente envía las señales de control a los mismos indicándoles la acción y, si es el caso, los datos y/o la dirección de memoria correspondiente. c) Cuando los dispositivos realicen su tarea enviarán una señal a la unidad de control, para que esta repita el mismo procedimiento con la siguiente instrucción, así hasta ejecutar todo el programa. Al período en el que se ejecuta una instrucción se le conoce como ciclo de instrucción o ciclo fetch.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 17
  • 18. Fundamentos de programaciónPrograma Desarrollado Con el fin de ilustrar este procedimiento, analizaremos la ejecución del siguiente programa escrito en un lenguaje de programación ficticio. Ejemplo 1.1: El siguiente conjunto de instrucciones calcula el área de un rectángulo. Imprimir “Ingresa la base:” Leer b Imprimir “Ingresa la altura:” Leer h area← b*h Imprimir área Programa 1.1:Calcula área de un rectángulo Antes de definir paso a paso la ejecución de este programa describiremos la función de cada una de las instrucciones que lo integran. Instrucción Descripción Imprime en el dispositivo de salida estándar los <Datos> Imprimir <Dato> indicados en la instrucción, que pueden ser un mensaje de texto o el valor de una variable. Lee por medio del teclado un dato, lo almacena en la variable Leer <X> <X> indicado y lo almacena en la memoria RAM. La flecha representa una asignación, esta acción actualiza la <X> ← <Dato> dirección de memoria asignada a <X> con el valor <Dato>. Tabla 1.1: Lista de instrucciones en lenguaje de programación ficticio Cabe señalar que en los lenguajes de programación, las direcciones de memoria se representan por medio de variables, para hacerlos más legibles. De tal manera que <X> representa una variable y <Dato> puede ser un mensaje o cualquier valor. Ahora sí, de acuerdo con la información anterior, en la siguiente tabla se describen paso a paso las acciones que realiza la unidad de control junto con las otras unidades de la computadora involucradas en la ejecución de cada una de las instrucciones del programa. Instrucción Descripción de la instrucción Imprimir “Ingresa base: ”  La unidad de control envía señales al monitor para que imprima elEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 18
  • 19. Fundamentos de programaciónPrograma Desarrollado mensaje “Ingresa base:”.  La unidad de control coordina las acciones necesarias para que, por Leer b medio del teclado ,el usuario introduzca un número y lo almacene en la memoria principal, en el espacio correspondiente a la variable b.  La unidad de control, nuevamente, envía una señal al monitor para que Imprimir “Ingresa altura:” imprima el mensaje “Ingresa altura:”.  La unidad de control coordina las acciones necesarias para que el Leer h usuario introduzca un número, por medio del teclado, y lo almacene en el espacio de memoria correspondiente a la variable h.  La unidad de control envía la señal indicada a la ALU para que realice la multiplicación posteriormente envía la señal a la memoria junto con el area← b *h resultado de la multiplicación, para que se almacene en el espacio de memoria a.  La unidad de control trae de la memoria el dato almacenado en el Imprimir area espacio asignado a la variable area y coordina las acciones para que el monitor imprima este valor. Tabla 1.2: Ejecución paso a paso de un programa 1.2.2 Almacenamiento de programas y datos La computadora sólo entiende señales binarias: ceros y unos, encendido y apagado, ya que todos los dispositivos de una computadora trabajan con dos únicos estados: hay corriente eléctrica y no hay corriente, respectivamente. Por tal motivo, los datos y programas almacenados en la memoria están codificados como cadenas de 1´s y 0´s para que la unidad de control pueda interpretarlos. A esta codificación se le llama lenguaje de máquina. Cabe mencionar que la memoria está dividida en varias celdas, en cada una de ellas se puede almacenar únicamente 0s ó 1s, a estos valores se les denomina valores binarios o BIT´s (BInary DigiT). Las celdas se agrupan para formar registros (también llamados palabras), a cada uno le corresponde una dirección de memoria, así cuando se desea escribir o leer de la memoria un dato o una instrucción se debe especificar la dirección dónde se encuentra. Como podrás imaginar, para un ser humano resultaría sumamente complicado escribir los programas en lenguaje de máquina, es por eso que los programas se escriben en lenguaje de programación entendibles para los seres humanos y después se traducen mediante un software especial –que pueden ser un compilador o un traductor– a cadenas de 0´s y 1´s. De tal manera que a cada instrucción le corresponde un código binario específico y para cada dato también existe una codificación única. PorEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 19
  • 20. Fundamentos de programaciónPrograma Desarrollado ejemplo, la palabra “Hola” se representa como “0100 1000 0110 1111 0110 1100 0110 0000”, ya que a cada letra le corresponde una codificación: H O L A 0100 1000 0110 1111 0110 1100 0110 0000 El número 80 se puede representar como “0101 0000” y la instrucción “MOV R2, R7” se codifica de la siguiente manera “0010 0000 1000 0100.” Conforme fueron evolucionando las computadoras se inventaron diversas maneras de representar la información en código binario, hoy en día existen codificaciones estándar para los símbolos y los números, al igual que para las instrucciones; sin embargo, para nuestros objetivos es suficiente tener claro que cualquier dato o instrucción puede ser representado mediante cadenas de 0s y 1s. Por otro lado, escribir programas en lenguaje binario es sumamente complicado para los seres humanos, por lo que en las últimas décadas se han desarrollado diversos lenguajes de programación que son más cercanos al lenguaje natural (humano), de los cuales hablaremos en la siguiente sección. 1.3 Lenguajes de Programación Los lenguajes de programación sirven para escribir programas de computadora orientados a resolver algún problema o necesidad. Cada lenguaje de programación se define a partir de un conjunto de símbolos básicos, llamado alfabeto; un conjunto de reglas, llamado sintaxis, que definen la forma de manipularlos o combinarlos para representar instrucciones; y las reglas que especifican los efectos de dichas instrucciones cuando son ejecutadas por la computadora, conocidas como semántica. De esta manera tenemos que: ó = + + á Por otro lado, dependiendo de su legibilidad para el ser humano los lenguajes de programación se clasifican en lenguajes de bajo nivel y lenguajes de alto nivel. Los primeros se caracterizan porque sus instrucciones se parecen más a las acciones elementales que ejecuta una computadora, como son: sumar, restar, guardar en memoria, etc. En cambio, las instrucciones de los lenguajes de alto nivel son más parecidas a un lenguaje humano, por lo regular inglés. Por otro lado, los programas escritos en bajo nivel describen a detalle lo que sucede a nivel de hardware, mientras que los programas escritos en un lenguaje de alto nivel lo ocultan, teniendo como ventaja que son más fáciles de entender para las personas. 1.3.1. Evolución de los lenguajes de programación Con las primeras computadoras surgió el primer lenguaje de programación que –como es de imaginarse– fue el lenguaje de máquina, el cual es considerado el lenguaje de primera generación. Las instrucciones en lenguaje de máquina dependían de las características de cada equipo, por lo que dadaEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 20
  • 21. Fundamentos de programaciónPrograma Desarrollado la dificultad de desarrollar programas en unos y ceros, los investigadores de la época desarrollaron el lenguaje ensamblador, cuyo conjunto de instrucciones consta de palabras nemotécnicas que corresponden a las operaciones básicas que una computadora puede ejecutar. Para ilustrar esto revisemos la siguiente instrucción: 2 Mueve el contenido del registro 8 al contenido del registro 10 En lenguaje de máquina esta se podría representar como: 0010 0000 1000 0100 Lo cual es ilegible para el ser humano, en cambio en lenguaje ensamblador esta instrucción se puede representar de la siguiente forma: MOV R2, R7 Aunque sigue estando en clave, es más amigable que las cadenas de ceros y unos. Otra característica del lenguaje ensamblador es que las instrucciones dependían de las características físicas (arquitectura) de la computadora. Para traducir de lenguaje ensamblador a lenguaje de máquina, se desarrollaron programas llamados ensambladores (en inglés, assemblers). Este lenguaje fue considerado de segunda generación. Posteriormente, en la década de los 50´s aparecieron los primeros lenguajes de alto nivel, cuyas instrucciones son más parecidas al idioma inglés y, por lo tanto, más fácil de utilizar para los programadores, además de que son independientes de la arquitectura de las computadoras. Algunos ejemplos son: FORTRAN y COBOL (que son los primeros lenguajes que aparecieron y en sus inicios se utilizaron para aplicaciones científicas), C, Pascal, Ada, Lisp y Prolog (utilizados principalmente en inteligencia artificial), Java, C++, C#, entre otros. Al igual que el lenguaje ensamblador, los programas escritos en un lenguaje de alto nivel deben ser codificados a lenguaje de máquina, así que junto con ellos se desarrollaron programas traductores, que de acuerdo con la forma en que trabajan se dividen en dos tipos: compiladores e intérpretes. • Los compiladores traducen todo el programa escrito en un lenguaje de alto nivel, llamado programa fuente, generando un nuevo programa objeto que está escrito en lenguaje de máquina y a partir de este se genera un programa ejecutado, el cual puede ejecutarse cada vez que se desee sin tener que compilar el programa fuente de nueva cuenta. Además, como parte del proceso de traducción el compilador detecta los errores que hay en el código fuente, 2 Este ejemplo es una adaptación de la versión original que aparece en (Joyanes & Zohanero, 2005, pág. 32) (Joyanes & Zohanero, 2005, pág. 32)Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 21
  • 22. Fundamentos de programaciónPrograma Desarrollado informándole al programador para que los corrija, pues un programa sólo se compila si no tiene errores. • En cambio, un intérprete revisa una a una cada línea de código, la analiza y enseguida la ejecuta, sin revisar todo el código y sin generar un programa objeto, así que cada vez que se quiere ejecutar el programa se vuelve a traducir el programa fuente línea por línea. Por lo anterior, los compiladores requieren una fase extra antes de poder generar un programa ejecutable, y aunque esto pareciera menos eficiente en cuanto a tiempo, los programas creados con compiladores se ejecutan mucho más rápido que un mismo programa ejecutado con un intérprete. Además, cuando un programa ya ha sido compilado puede ejecutarse nuevamente sin tener que compilarse, mientras que los programas que son interpretados, cada vez que se ejecutan se deben volver a traducir. Conforme han ido evolucionando las computadoras también lo han hecho las estrategias para solucionar problemas, generando nuevos programas programación con diferentes filosofías, llamadas paradigmas de programación, de esto hablaremos a continuación. 1.3.2 Paradigmas de los lenguajes de programación Un paradigma de programación representa un enfoque particular o filosofía para diseñar soluciones. Los paradigmas difieren unos de otros en los conceptos y la forma de abstraer los elementos involucrados en un problema, así como en los pasos que integran su solución del problema, en otras palabras, el cómputo. Un lenguaje de programación siempre sigue un paradigma de programación, aunque también podemos encontrar lenguajes con la influencia de dos paradigmas, tal es el caso del lenguaje C++, que surgió bajo el paradigma procedimental y se transformó al paradigma orientado a objetos, de tal manera que puede soportar ambos paradigmas. Los paradigmas más importantes son: • Paradigma imperativo o procedural. Es el método de programación tradicional, donde los programas describen la forma de solucionar un problema a partir de una lista de instrucciones que se ejecuta de forma secuencial, a menos que se trate de estructuras de controlEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 22
  • 23. Fundamentos de programaciónPrograma Desarrollado condicionales o repetitivas, o bien, saltos de secuencia representados por la instrucción GOTO. 3 La programación imperativa se define a partir del cambio de estado de las variables que se produce por la ejecución de las instrucciones, por ejemplo, el programa 1.1, que calcula el área de un rectángulo, es un ejemplo de un programa imperativo, ya que describe paso a paso como solucionar el problema y el resultado corresponde al estado final de la variable area. Sin embargo, el lenguaje en el que está escrito no corresponde a ningún lenguaje de programación real, pero el lenguaje de máquina es un ejemplo de este paradigma. Otros lenguajes imperativos son: Fortran, Cobol, Pascal, Basic, Ada y C. • Paradigma declarativo. En contraste con el paradigma imperativo, el objetivo de este paradigma no es describir cómo solucionar un problema, sino describir un problema mediante predicados lógicos o funciones matemáticas. Dentro de este paradigma se encuentran los lenguajes de programación funcionales y los lenguajes de programación lógicos. Los primeros representan el problema utilizando funciones matemáticas, por ejemplo, un programa que calcule el área de un rectángulo utilizando un lenguaje funcional se vería así: (, ℎ) = ∗ ℎ De tal manera que para calcular el área de un rectángulo de base igual a 5 unidades y altura igual a 10 unidades, se ejecuta la función con los parámetros 5,10, es decir, areaRectángulo (5,10), la cual devuelve como resultado 50. Los lenguajes de programación más representativos del paradigma funcional son: Lisp, ML y Haskell. En el caso de los lenguajes lógicos la solución se representa a través de un conjunto de reglas, á(, ℎ, ) ∶ −ó(, ℎ, ) por ejemplo: Esta regla dice que el valor de la variable area corresponde al área del rectángulo con base b y altura h sólo si area es el resultado de multiplicar b por h. Estamos suponiendo que se ha definido el predicado multiplicación(a, b, c). En este caso para calcular el resultado se utiliza el principio de razonamiento lógico para responder a las preguntas planteadas, por ejemplo si se desea calcular el área del mismo rectángulo, la pregunta sería la siguiente: ? (5,10, ) 3 De esto hablaremos en unidades posteriores.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 23
  • 24. Fundamentos de programaciónPrograma Desarrollado Y después de que se realicen los cálculos (en este caso llamadas inferencias) el resultado que arrojaría sería: = 50 El lenguaje más representativo del paradigma lógico es Prolog. • Paradigma orientado a objetos. En este caso la solución de un problema se plantea en términos de objetos y relaciones entre ellos. Está basado en varias técnicas, incluyendo, herencia, polimorfismo, modularidad y encapsulamiento. En este caso se definen clases que son las plantillas para crear objetos, por ejemplo, un si se quiere un programa orientado a objetos que calcule el área de un rectángulo, se debe definir una clase rectángulo que contenga un método encargado de calcular el área. El lenguaje Java y C#, que actualmente son los más utilizados, son ejemplos de este paradigma. 1.4 Ciclo de vida del software Independientemente del paradigma que se siga y del lenguaje que se utilice para programar, existe un conjunto de fases que deben seguirse para realizar un programa de computadora, al cual se le conoce como ciclo de vida del software, en la siguiente figura se lista cada una de ellas.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 24
  • 25. Fundamentos de programaciónPrograma Desarrollado Planteamiento Análisis del del problema problema Diseño del algoritmo Ciclo de vida del software Mantenimiento Implementación o codificación Documentación Pruebas y delprograma validación En las siguientes secciones aprenderemos en qué consiste cada una de las fases, para lo cual nos apoyaremos en la resolución del siguiente problema con la intención de que se entienda mejor: Problema 1.1: Se requiere construir un programa que calcule el área de un rectángulo, con base b y altura h. 1.4.1 Análisis del problema En esta fase se determina ¿qué hace el programa? Por lo cual debe definirse de manera clara y concisa el problema en cuestión, se debe establecer el ámbito del problema, las características, limitaciones y modelos de lo que se desea resolver. Este paso debe conducir a una especificación completa del problema en donde se describa cuáles son los datos requeridos para resolverlo (datos de entrada) y cuál es el resultado deseado (salida). El análisis de nuestro ejemplo es muy simple y se resume en la siguiente tabla: ¿Cuál es la salida deseada? El área de un cuadrado, la cual identificaremos como ¿Qué método(s) se pueden El área de un rectángulo se puede utilizar para llegar a la calcular con la siguiente fórmula:Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 25
  • 26. Fundamentos de programaciónPrograma Desarrollado solución? Á = ∗ ¿Qué datos de entrada se Por el planteamiento del problema y requieren? dado el método anterior, los únicos datos que se requieren son: la medida de la base que se representa por b y la medida de la altura indicada por h ¿Qué datos o información En este caso no se requiere más adicional es necesaria para información. solucionar el problema? ¿Existe algún problema o Las únicas restricciones son que las condiciones que deban medidas de la base y altura sean cumplirse? mayores a cero. Tabla 1.3: Análisis del problema 1 1.4.2Diseño de la solución Es en esta fase se define ¿cómo el programa resuelve el problema? Para ello, se describe paso a paso la solución del mismo, lo cual se conoce como algoritmo. Cuando el problema es grande se recomienda dividirlo en subproblemas más pequeños y resolver por separado cada uno de ellos. A esta metodología se le conoce como diseño descendente (top-down) o modular. Existen diferentes formas de representar un algoritmo algunas formales, como una fórmula matemática, o informales, como es el caso del lenguaje natural. En la siguiente unidad estudiaremos a mayor profundidad los algoritmos y su representación, pero para seguir con el desarrollo de nuestro programa ejemplo, plantearemos la solución como una secuencia de pasos en español. 2. Calcular: á = ∗ 1. Obtener la medida de la base () y la altura () 3. Imprimir el resultado (á) Algoritmo 1.1: Calcula el área de un rectángulo El programa 1.1es otra forma de representar la solución de este problema, se conoce como pseudocódigo. 1.4.3 Implementación (codificación) El algoritmo no puede ser ejecutado por una computadora por ello debe traducirse a un lenguaje de programación (como por ejemplo C) para obtener un programa fuente que se traduzca a lenguaje de máquina para que sea ejecutado por la computadora.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 26
  • 27. Fundamentos de programaciónPrograma Desarrollado En el siguiente cuadro se muestra la codificación en lenguaje C del algoritmo, por ahora no es necesario que lo comprendas puesto que esto lo podrás hacer conforme vayas aprendiendo a programar, por lo pronto solamente se muestra con fines ilustrativos. #include<stdio.h> #include<stdlib.h> main() { int b,h, area; printf("Ingresa la base y altura:"); scanf("%d %d", &b,&h); area = b * h; printf("Area = %d", area); } Programa 1.2: Programa en C que calcula área de un rectángulo 1.4.4 Validación y pruebas Esta fase debe hacerse una vez que se ha diseñado el algoritmo y después de que se codifica, sirve para verificar que son correctos. Existen diferentes formas de probar que la solución es correcta, algunas de ellas formales y otras informales: las primera se utilizan para garantizar que el programa o algoritmo siempre calcula el resultado deseado para cualquier conjunto de datos de entrada; en cambio, en las segundas sólo se prueba que funciona correctamente para algunos datos de entrada, tratando de encontrar posibles errores, en este caso no se puede garantizar el programa o algoritmo calcule la salida correcta para cualquier conjunto de datos. En cualquiera de los dos casos, si se encuentra alguna falla se debe corregir y volver a realizar pruebas. En este curso utilizaremos las pruebas de escritorio, las cuales se explicarán en la unidad 2. El ejemplo es muy sencillo y si ejecutamos manualmente el programa o algoritmo mostrado en la fase anterior, con un caso específico de rectángulo veremos que ambos son correctos. En la siguiente figura se ilustra la ejecución del programa:Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 27
  • 28. Fundamentos de programaciónPrograma Desarrollado Figura 1.2: Ejecución del programa 1.2 1.4.5 Documentación Cualquier proyecto de software por la complejidad que tiene requiere tanto las ideas principales como el desarrollo de principio a fin sea documentado, con el fin de que cualquiera puedan entender la lógica del programa y de ser necesario pueda modificarlos sin tantas complicaciones. Es común que si se desea modificar un programa y no se tiene información acerca de cómo fue construido sea más fácil volverlo a hacer que intentar entenderlo. Uno de los mejores ejemplos de la importancia de la documentación es el software libre, en el cual colaboran diversos desarrolladores para su elaboración, los cuales se encuentran en diferentes puntos geográficos de globo terráqueo, así que la forma de entender que está haciendo cada uno y bajo que método es la documentación. Además de que se debe tomar en cuenta que se llama software libre porque está disponible el código fuente para que cualquier persona pueda modificarlo a su conveniencia. Como parte de la documentación también deben incluirse manuales de usuario y las normas de mantenimiento para que se haga un buen uso del software. 1.4.6 Mantenimiento Esta fase tiene sentido una vez que fue terminada una primera versión del programa y ya está siendo utilizado. Ya que en ésta se actualiza y modifica para corregir errores no detectados o para cambiar y/o agregar una nueva función. Por ejemplo, se puede extender el programa 1.1, que calcula el área de un rectángulo para que también calcule su perímetro. Ejemplo 1.2: El siguiente conjunto de instrucciones calcula el área y perímetro de un rectángulo. #include<stdio.h> #include<stdlib.h> main() { int b,h, area, perimetro; printf("Ingresa la base y altura:"); scanf("%d %d", &b,&h);Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 28
  • 29. Fundamentos de programaciónPrograma Desarrollado perimetro = 2*b + 2*h; area = b * h; printf("Perimetro = %d", perimetro); printf("Area = %d", area); } Programa 1.3: Calcula el área y perímetro de un rectángulo En el programa se resaltan las instrucciones que se añadieron al programa para calcular el perímetro. Actividad de Autoevaluación Ingresa al aula virtual para realizar las dos actividades de autoevaluación, la primera trata de un pequeño juego tipo maratón en el que pondrás a prueba tus conocimientos, la segunda consiste en un cuestionario de opción múltiple. Consideraciones específicas de la unidad Para alcanzar los objetivos de esta unidad se ha propuesto una actividad formativa en la cual revises la ejecución de un problema apoyándote en una animación que muestra paso a paso la ejecución del programa 1.1 que se presentó en esta unidad, en dicha animación se especifica cada uno de los elementos que están involucrados en la ejecución de las instrucciones. Referencias: • Guerrero, F. (s.f.). mailxmail.com. Recuperado el 15 de agosto de 2010, de http://www.mailxmail.com/curso-introduccion-lenguaje-c • Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. España: Mc Graw Hill. • Reyes, A., & Cruz, D. (2009). Notas de clase: Introducción a la programación. México, D.F.: UACM. • Viso, E., & Pelaez, C. (2007). Introducción a las ciencias de la computación con Java. México, D.F.: La prensas de ciencias, Facultad de Ciencias, UNAM.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 29
  • 30. Fundamentos de programaciónPrograma DesarrolladoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 30
  • 31. Fundamentos de programaciónPrograma Desarrollado Unidad 2: Diseño de algoritmos Propósitos En esta unidad: • Identificar los datos de entrada y la salida de un algoritmo • Diseñar un algoritmo que solucione un problema. • Representar el algoritmo en diagrama de flujo y pseudocódigo • Verificar que el algoritmo calcule el resultado correcto Competencia específica Diseñar algoritmos para resolver problemas mediante su representación en un diagrama de flujo y la elaboración del pseudocódigo. Introducción En la unidad anterior se describieron los pasos que se requieren para construir un software, sin lugar a dudas, la fase más importante es el diseño de la solución, ya que es aquí donde se debe crear un modelo que corresponde a los pasos que llevan a la solución del problema en cuestión, y se conoce como algoritmo. Para construir esta solución se requiere no sólo de inteligencia, sino también de creatividad, ya que el programador sólo cuenta con la especificación del problema y su experiencia en resolver problemas de una forma estructurada. En este apartado se introduce formalmente el concepto de algoritmo, hablaremos de sus características y estudiaremos dos formas de representarlos: una gráfica, conocida como diagramas de flujo; y la otra similar a un lenguaje humano, en este caso español, la cual se llama pseudocódigo. También se describen los tres tipos de estructuras de control: secuenciales, selectivas y repetitivas, que son las instrucciones con que se cuenta en la programación estructurada para diseñar soluciones. Para logar nuestro objetivo se introduce “el mundo de la ardilla”, en el cual se deben solucionar problemas mediante un conjunto de instrucciones específicas que puede ejecutar una ardilla sobre un tablero. 2.1 Concepto de algoritmo y características La palabra algoritmo proviene del nombre de un matemático persa conocido como Mohammad Al- KhoWârizmi, nacido alrededor del 780 d.c. en KhoWârizm, de ahí el su seudónimo. Se considera como el padre de la algoritmia porque definió las reglas paso a paso para sumar, restar, multiplicar y dividir números decimales. La traducción al latín de Al-Khwārizmī es algoritmi, que da origen a la palabra algoritmo (Joyanes & Zohanero, 2005).Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 31
  • 32. Fundamentos de programaciónPrograma Desarrollado Formalmente, un algoritmo se define como una secuencia finita de instrucciones precisas y eficaces para resolver un problema, que trabaja a partir de cero o más datos (entrada) y devuelve un resultado (salida). 4 Para ilustrar este concepto se presenta el siguiente escenario ficticio, que hemos llamado: El mundo de la ardilla Supongamos que una ardilla ha sido entrenada para realizar las instrucciones que se muestran en la tabla 2.1, sobre un tablero. INSTRUCCIÓN DESCRIPCIÓN DE LOS MOVIMIENTOS DE LA ARDILLA avanza() Se mueve una ubicación en la dirección actual giraIzquierda() Voltea a la izquierda dejaBellota() Coloca una bellota en la ubicación actual hayBellota() Responde si hay o no bellotas en la posición actual hayPared() Responde si hay o no pared en la ubicación siguiente La ardilla coloca en su boca una bellota que está en la recogeBellota() ubicación actual 5 bellotasRecogidas() Dice el número de bellotas que tiene en la boca Tabla 2.1: Lista de instrucciones que puede ejecutar la ardilla Los paréntesis al final de cada instrucción sirven para identificar que se trata de una orden que puede ejecutar la ardilla. Si observas la lista de instrucciones podrás darte cuenta que, la ardilla no es capaz de voltear a la derecha y mucho menos de responder a órdenes más complejas como “mueve una bellota que se encuentra en la primera casilla del tablero al final del mismo”. Sin embargo, podría realizar ambas tareas si se le dan las instrucciones precisas en términos de las acciones que sabe hacer. Por ejemplo, para que la ardilla gire a la derecha tendríamos que ordenarle tres veces que girará a la izquierda, es decir, la secuencia de instrucciones que debe ejecutar es: giraIzquierda() giraIzquierda() giraIzquierda() 4 Esta definición es una adaptación de la que aparecen en (Viso & Pelaez, 2007, pág. 3) 5La ardilla poseen una bolsa donde almacena cualquier cantidad de bellotas.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 32
  • 33. Fundamentos de programaciónPrograma Desarrollado Estos pasos constituyen un algoritmo, el cual soluciona el problema de hacer que la ardilla gire a la derecha. Una de las características principales de los algoritmos es que cada paso debe estar definido de forma clara y precisa, sin ambigüedades, de tal manera que pueda ejecutarse de manera inequívoca, por ejemplo, en el mundo de la ardilla, la instrucción gira() sería una instrucción ambigua, ya que la ardilla no sabría si debe girar a la derecha o a la izquierda. Otra característica de los algoritmos es que siempre terminan, por lo que no puede ser una lista infinita de pasos. Y tampoco puede contener pasos que sean irrealizables o cuya ejecución sea infinita, pues en este caso no sería posible calcular el resultado deseado, si una instrucción está bien definida y es eficaz se puede asegurar que su ejecución termina con éxito, sin embargo, esto no garantiza, de ninguna manera, que el algoritmo también termine. Por lo anterior, al diseñar un algoritmo se debe garantizar que dada cualquier entrada siempre termine y calcule la respuesta correcta. De tal manera que todo algoritmo debe tener las siguientes características: 1.Entrada. 2. Salida. 3. Definido. 4. Eficaz. 5. Terminación. Una vez que se ha diseñado un algoritmo, se recomienda realizar una prueba de escritorio para verificar si funciona correctamente, ésta consiste en ejecutar el algoritmo utilizando papel y lápiz, se propone datos de entrada específicos y se realiza cada una de las instrucciones en el orden establecido, registrando los cambios que se producen después de la ejecución de cada instrucción. De esta manera, se valida que el resultado obtenido en la prueba de escritorio corresponda al resultado deseado (el correcto). 2.2. Representación de algoritmos Existen diversas formas de representar un algoritmo, en la unidad anterior expusimos diversas formas de representar la solución del problema de calcular el área de un rectángulo, por ejemplo, en el programa 1.1 se expresa la solución en pseudocódigo, después en el algoritmo 1.1 se representa en lenguaje natural (español) y en el programa 1.2 se utiliza el lenguaje de programación C, o se puede expresar mediante la fórmula matemática: á = × Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 33
  • 34. Fundamentos de programaciónPrograma Desarrollado Todas estas representaciones, excepto el lenguaje natural, se consideran formales, y cabe mencionar que existen más, sin embargo, las representaciones más comunes son el pseudocódigo y los diagramas de flujo. La primera, generalmente se utilizar por su parecido con el lenguaje natural (español, inglés, francés o cualquier otro) y porque su codificación en un lenguaje de programación estructurado y modular, como C, es directa. En cambio, los diagramas de flujo son totalmente gráficos, lo que hace más fácil seguir el orden en que se ejecutan las instrucciones. Es importante mencionar que se puede utilizar cualquiera de las dos representaciones para diseñar un algoritmo, pues en cualquiera de los dos se puede expresar cualquier algoritmo estructurado, de tal manera que la más conveniente depende de cada programador. En las siguientes secciones se presenta cada uno de ellos y así podrás decidir cuál prefieres. 2.2.1. Pseudocódigo El pseudocódigo es un lenguaje de especificación formal de algoritmos. La solución de un problema se representa de manera narrativa utilizando palabras claves, generalmente verbos, escritos en un lenguaje natural, que en nuestro caso será español. Para ilustrarlo construyamos un algoritmo que resuelva el siguiente problema. Problema 2.1: En la figura 2.1.a. se muestra el estado inicial de un tablero, el cual contiene en la primer casilla (de izquierda a derecha) una bellota, representada por un asterisco (*), y a la ardilla, representada por una flecha que apunta hacia la dirección que está mirando. El problema consiste en diseñar un algoritmo que la ardilla pueda ejecutar para llegar al estado meta representado en la figura 2.1.b., que implica que la ardilla lleve la bellota a la última casilla. Para resolverlo se tiene la siguiente información: a) El mundo es conocido, es decir, se sabe de antemano que el tablero está cercado por paredes y sólo tiene seis casillas colocadas en línea. b) Al inicio la ardilla está en la primera casilla volteando hacia arriba y no tiene ninguna bellota en la boca. c) En la primera casilla hay una bellota. * * Estado inicial (a) Estado final (b) Figura 2.1: Primer mundo linealEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 34
  • 35. Fundamentos de programaciónPrograma Desarrollado Análisis: Haciendo un rápido análisis del problema, nos podemos dar cuenta que la ardilla debe recoger la bellota, avanzar cinco casillas y soltar la bellota, esto traducido en un algoritmo queda de la siguiente forma: Inicio recogeBellota() giraIzquierda() giraIzquierda() giraIzquierda() avanza() avanza() avanza() avanza() avanza() dejaBellota() Fin Algoritmo 2.1. Primer mundo de la ardilla En este caso las instrucciones son parecidas al lenguaje natural. 2.2.2. Diagrama de flujo Los diagramas de flujo son una representación gráfica de un algoritmo que utiliza símbolos para representar las instrucciones y flechas para unirlas e indicar el orden en que deben ejecutarse -llamadas líneas de flujo. Estos símbolos fueron normalizados por el Instituto Norteamericano de Normalización ANSI (American National Standars Institute, por sus siglas en inglés). Los símbolos más utilizados se muestran en la siguiente tabla. Símbolo Descripción Terminal. Representa el inicio y el final de un algoritmo. TerminalEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 35
  • 36. Fundamentos de programaciónPrograma Desarrollado Entrada y Salida (E/S). Representa la lectura de datos desde el E/S dispositivo de entrada estándar, así como la impresión de datos en el dispositivo de salida estándar. Proceso. Representa cualquier tipo de operación que pueda Proceso originar un cambio de la información almacenada en memoria, asignaciones u operaciones aritméticas. Decisión. Nos permite analizar una situación, con base en los valores verdadero y falso. Toma una decisión de las instrucciones Decisión que a continuación ejecuta el algoritmo. Conector. Sirve para enlazar dos partes cualesquiera del diagrama que están en la misma página. Línea de flujo. Indica el orden de la ejecución de las operaciones. La flecha indica cuál es la siguiente instrucción que se debe realizar. Conector. Conecta a dos puntos del diagrama cuando éstos se encuentran en páginas diferentes. Representa el inicio y el final de un programa. Llamada a subrutina. Llama a un proceso determinado o Subrutina subrutina. Una subrutina es un módulo independiente del módulo principal, que realiza una tarea determinada y al finalizar regresa el control de flujo al módulo principal. Tabla 2.2 Símbolos de los diagramas de flujo Problema 2.2: Ahora la tarea de la ardilla es que cambie las bellotas que están en la primera fila (ver figura 2.2.a) a la segunda y viceversa, dejándolas en la misma columna (ver figura 2.2.b). Las condiciones de inicio son: a) El mundo es conocido y sabemos exactamente dónde hay bellotas. b) La ardilla no tiene ninguna bellota en la boca al inicio. c) El mundo está encerrado por paredes y si la ardilla choca contra una se considerará un error garrafal. d) En este punto los científicos ya entrenaron a la ardilla para ejecutar la orden giraDerecha(), por lo tanto, ya puede ser usada en el algoritmo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 36
  • 37. Fundamentos de programaciónPrograma Desarrollado * * * * * * * * * * * * Estado inicial (a) Estado final (b) Figura 2.2:Segundo mundo de la ardilla Análisis: De acuerdo con la figura 2.2, inciso a, para que la ardilla cumpla con su tarea debe realizar los siguientes pasos: recoger la bellota, girar a la derecha, avanzar, dejar la bellota, girar a la izquierda, avanzar, recoger la bellota, girar a la izquierda, avanzar, dejar la bellota, voltear a la derecha y avanzar. Hasta este punto las coordenadas de la ardilla son: primera fila y tercera casilla (volteando a la derecha, como al inicio). * * * * * * Si la ardilla repite otra vez este bloque de instrucciones, logrará cambiar las siguientes dos bellotas; al repetirlo nuevamente cambiaría las últimas dos, salvo que cuando la ardilla avance después de haber dejado la bellota chocará contra la pared, por lo tanto, antes de que avance –última instrucción del bloque – tenemos que verificar que no haya pared. La condición para que la ardilla repita el bloque de instrucciones es que no haya pared. De lo anterior tenemos el siguiente algoritmo representado en diagrama de flujo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 37
  • 38. Fundamentos de programaciónPrograma Desarrollado Algoritmo 2.2. Solución problema 2.2 Actividad 1. Representación de algoritmos En esta actividad, reflexionarás sobre el uso de los diagramas de flujo y pseudocódigos a partir de varias preguntas. Posteriormente, ingresarás un comentario al respecto en el Foro Representación de algoritmos. Evidencia de aprendizaje. Planteamiento del problema Como primera evidencia de aprendizaje para esta unidad deberás elegir un problema que se pueda solucionar mediante un programa de computadora y realizarás la descripción precisa del mismo. 2.3. Estructuras de control Los primeros lenguajes de programación de alto nivel permitían realizar “saltos” a diferentes líneas del código mediante la instrucción GOTO, esto tiene el gran inconveniente que cuando se hacía una modificación en el programa, era necesario modificar todas las instrucciones GOTO para asegurar queEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 38
  • 39. Fundamentos de programaciónPrograma Desarrollado los saltos se hicieran a las líneas de código correctas. Además de lo tedioso que podía ser estar corrigiendo el programa, las instrucciones GOTO lo hacían difícil de leer. En 1966 Corrado Böhm y Giuseppe Jacopini demostraron que “cualquier algoritmo puede diseñarse e implementar utilizando únicamente tres tipos de estructuras de control: secuenciales, condicionales y repetitivas; esto es, sin utilizar GOTO”(Böhm & Jacopini, 1966), basándose en este resultado, a principios de los años 70´s Edsger Dijkstra se dio cuenta que la forma en la que los lenguajes de programación de alto nivel podían modificarse sin problemas era eliminando las instrucciones GOTO (o similares), así que propuso un nuevo estilo de programación al que llamó programación estructurada, ésta incluye estructuras secuenciales, selectivas y repetitivas, conocidas como estructuras de control. 2.3.1. Estructuras secuenciales Las estructuras secuenciales son un bloque de instrucciones que se ejecutan una tras otra, en el mismo orden en el que están escritas. Un ejemplo de este tipo de instrucciones son todas las que se utilizaron en el algoritmo 2.1. Veamos otro ejemplo. Problema 2.3: Ahora la ardilla se enfrenta a un nuevo mundo (ver figura 2.3) en el que su tarea consiste en recoger las dos bellotas colocadas en la posiciones indicadas por la figura 2.3.a y llevarlas a la última casilla de la primera fila, como se muestra en la figura 2.3.b. Considerando que tenemos un mapa del nuevo mundo y sabemos en qué casillas están colocadas las bellotas diseñemos un algoritmo para que la ardilla realice su cometido. * ** * Estado inicial (a) Estado final (b) Figura 2.3.Tercer mundo de la ardilla Análisis: Nuevamente el problema planteado es muy sencillo de analizar, la ardilla debe hacer los movimientos que le permitan recoger la primera bellota, después ir por la segunda y llegar a la última casilla de la prime fila. Otra posible opción es que recoja la primera bellota, la lleve a la primera casilla,Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 39
  • 40. Fundamentos de programaciónPrograma Desarrollado regrese por la segunda bellota y también la lleve a la primera casilla. Esta última opción requiere más esfuerzo por parte de la ardilla, dado que la ardilla no tiene limitado el número de bellotas que puede llevar en la boca, entonces la primera opción es más eficiente. El algoritmo quedaría como: Inicio avanza() giraIzquierda() avanza() avanza() recogeBellota() giraIzquierda() avanza() giraDerecha() avanza() avanza() recogeBellota() avanza() dejaBellota() dejaBellota() Fin Algoritmo 2.3. Solución problema 2.3. Las instrucciones selectivas, más usuales, que una computadora es capaz de realizar son: Imprimir, Leer y Asignar. La representación en diagrama de flujo de estas instrucciones se ilustra en la siguiente tabla, en cuanto que la representación en diagrama de flujo se utilizan los mismos verbos y símbolos pero encerrados entre un símbolo de proceso.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 40
  • 41. Fundamentos de programaciónPrograma Desarrollado Tipo Pseudocódigo Diagrama de flujo Descripción Asigna el valor de la expresión Asignación <var> ← <Expresión> <var> ← <Expresión> a la variable <var> Envía a pantalla un mensaje o el valor de la variable indicada. En caso de que se imprima un Imprimir imprimir mensaje debe estar escrito <mensaje/variable> var/mens entre comillas, si es el valor de Entrada y una variable sólo se pondrá el Salida nombre de la variable (sin comillas) leer Lee un dato del teclado y lo Leer <variable> almacena en la variable variable indicada. Tabla 2.3 Estructuras secuenciales 2.3.2 Estructuras selectivas En esencia, las estructuras selectivas se utilizan cuando la solución de un problema conlleva tomar una decisión, ya que se ejecuta un conjunto determinado de instrucciones dependiendo de si se cumple o no una condición en un momento determinado. Por ejemplo, la ardilla solamente puede avanzar si se no hay pared, en este caso la condición es no hayPared() y la acción que se realiza es avanza(). Revisemos el siguiente ejemplo: Problema 2.4: Nuevamente la ardilla está en el mundo lineal que se ilustra en la figura 2.4.a, tiene que recoger una bellota y llevarla a la última casilla como se muestra en la figura 2.4.b, sólo que ahora no sabe con precisión en que casilla está la bellota y la única información con la que cuenta es la siguiente: a) En el tablero hay una sola bellota. Las casillas donde puede estar son la tercera o la quinta, lo cual se representa con un círculo en la figura 2.4.a. b) Al inicio la ardilla no tiene ninguna bellota en la boca. c) Es un error ordenar a la ardilla que recoja una bellota en una casilla cuando esta no contiene nada pues la ardilla no sabrá que hacer. d) La ardilla ya ha sido entrenada para decir si hay bellota.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 41
  • 42. Fundamentos de programaciónPrograma Desarrollado * Estado inicial (a) Estado final (b) Figura 2.4.Cuarto mundo de la ardilla Análisis: En este caso es necesario asegurarnos que en la casilla hay una bellota, antes de ordenarle a la ardilla que la recoja, para ello vamos a utilizar una estructura selectiva, como la ardilla ya fue entrenada para decir si hay una bellota, entonces esto lo utilizaremos como condición. Ya que tenemos dos posibles lugares dónde la ardilla puede encontrar la bellota, ordenaremos a la ardilla que avance hasta la tercera casilla, si hay una bellota entonces lo recoge y después la lleva a la última casilla, sino la ardilla avanza hasta la quinta casilla y ahí recoge la bellota, esto sin preguntar si ahí se encuentra pues una de las aseveraciones en el planteamiento del problema es que en el tablero hay una bellota, así que si éste no estaba en la tercera casilla es seguro que está en la quinta. Inicio avanza() avanza() Si hayBellota() entonces recogeBellota() avanza() avanza() avanza() dejaBellota() Sino avanza() avanza() recogeBellota() avanza() dejaBellota() Fin Si-Sino Fin Algoritmo 2.4. La ardilla toma decisiones en un mundo lineal, versión 1 Observa que tanto en el primer caso (Si) como en el segundo (Sino) cuando la ardilla está en la quinta casilla y ya recogió la bellota, las siguientes órdenes es que avance y deje la bellota (ambas están remarcadas), de tal manera que podemos modificar el algoritmo de la siguiente forma:Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 42
  • 43. Fundamentos de programaciónPrograma Desarrollado Inicio avanza() avanza() Si hayBellota() entonces recogeBellota() avanza() avanza() Sino avanza() avanza() recogeBellota() Fin Si-Sino avanza() dejaBellota() Fin Algoritmo 2.5. La ardilla toma decisiones en un mundo lineal, versión 2 También podemos utilizar la estructura Si dos veces, una para preguntar si la bellota está en la tercera casilla y otra para preguntar en la quinta, como se muestra en el siguiente algoritmo. Inicio avanza() avanza() Si hayBellota() entonces recogeBellota() Fin Si avanza() avanza() Si hayBellota() entonces recogeBellota() Fin Si avanza() dejaBellota() Fin Algoritmo 2.6. La ardilla toma decisiones en un mundo lineal, versión 3Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 43
  • 44. Fundamentos de programaciónPrograma Desarrollado A diferencia de los dos algoritmos anteriores, en éste la ardilla va a verificar en las dos casillas si hay bellota, aunque la haya encontrado en la primera opción, esto implica un poco más esfuerzo para la ardilla. Por otro lado, observa que en los algoritmos 2.4 y 2.5 se definieron instrucciones para el caso que se cumple la condición (Si) y para el caso que no (Sino); en cambio, en este último algoritmo sólo se ha definido un conjunto de instrucciones que se ejecuta si la condición se cumple, de no ser así no hay instrucciones específicas y la ardilla continuará realizando las siguientes instrucciones del algoritmo. Es importante destacar que ambas estructuras son equivalentes, es decir, que los problemas que se solucionan con una también es posible hacerlo con la otra. Existen tres tipos de estructuras selectivas que se clasifican de acuerdo al número de alternativas: a) Simples (Si): involucra un único bloque de instrucciones que se ejecuta sólo si una condición se cumple. b) Dobles (Si-Sino): abarca dos bloques de instrucciones, uno se ejecuta cuando la condición es verdadera y el otro cuando es falsa. c) Múltiples (Seleccionar): tiene más de dos bloques de instrucciones que se pueden ejecutar conforme al valor que tenga una variable, cada bloque equivale a un valor diferente. En la siguiente tabla se muestra la representación en pseudocódigo y diagrama de flujo de estas estructuras. Tipo Pseudocódigo Diagrama de flujo Descripción Si la condición es Estructuras Si <condición> entonces verdadera, se ejecuta el selectivas <instrucciones> conjunto de instrucciones. simples Fin_Si Si <condición> entonces Si la condición se cumple Estructuras <instrucciones V> se ejecuta el conjunto de selectivas Sino instrucciones V, en caso dobles <instrucciones F> contrario se realizan las Fin_Si-Sino instrucciones F.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 44
  • 45. Fundamentos de programaciónPrograma Desarrollado Seleccionar <expresión> caso <valor1>: Compara el valor de <instrucciones1> expresión con cada uno caso <valor2>: los valores Estructuras <Instrucciones2> correspondientes a cada selectivas . caso, es decir cada valor múltiples . K y sólo si son iguales . realiza las instrucciones otro: correspondientes. <instruccionesOtro> Fin_Seleccionar Tabla 2.4 Estructuras selectivas En la unidad cuatro estudiaremos a mayor detalle cada una de estas estructuras. Actividad 2.Diseño de un algoritmo con estructuras selectivas Diseña un algoritmo, en pseudocódigo o diagrama de flujo, usando estructuras selectivas para resolver el problema que te proporcionará tu facilitador(a). 2.3.3. Estructuras repetitivas Las estructuras repetitivas, también llamadas ciclos, permiten ejecutar varias veces un bloque de instrucciones en función de una condición. Para ilustrar esto, volvamos al problema 2.1 del subtema 2.2.1; en este mundo la ardilla debe llevar una bellota desde la primera casilla hasta la última en un mundo lineal (ver figura 2.1). Observa que una vez que la ardilla recoge la bellota y está viendo de frente, debe avanzar una y otra vez mientras no se tope con la pared, esto se puede modelar con un ciclo de la siguiente manera. Inicio recogeBellota() giraIzquierda() giraIzquierda() giraIzquierda() Mientras no (hayPared()) hacer avanza() Fin Mientras dejaBellota() Fin Algoritmo 2.7. Solución problema 2.1 utilizando ciclosEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 45
  • 46. Fundamentos de programaciónPrograma Desarrollado Generalmente, un ciclo se utiliza cuando descubrimos un patrón, tal como se hizo en el análisis del problema 2.2. Si observas el algoritmo 2.2, verás que al final hay una flecha que regresa a la primera instrucción, representado con ello un ciclo. La presentación en pseudocódigo de este algoritmo sería la siguiente: Inicio Mientras no(hayPared()) hacer recogeBellota() giraIzquierda() giraIzquierda() giraIzquierda() avanza() dejaBellota() giraIzquierda() avanza() recogeBellota() giraIzquierda() avanza() dejaBellota() giraIzquierda() giraIzquierda() giraIzquierda() Si no(hayPared()) entonces avanza() Fin Si Fin Mientras Fin Algoritmo 2.8:Solución del problema 2.2 utilizando ciclos La clave para utilizar un ciclo es identificar el conjunto de instrucciones que se deben repetir y la condición para que se ejecuten. Al igual que en las estructuras selectivas, existen diferentes estructuras repetitivas que se diferencian, principalmente, por el orden en el que se evalúa la condición. Éstas son: a) Mientras-hacer: en este ciclo primero se verifica que la condición sea verdadera y en tal caso se ejecuta el bloque de instrucciones y se repite nuevamente el ciclo. b) Hacer-Mientras: en esta estructura primero se realizan las instrucciones y después se verifica la condición, si se cumple se repite el ciclo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 46
  • 47. Fundamentos de programaciónPrograma Desarrollado c) Desde-mientras: funciona igual que Mientras pero tiene asociada una variable que sirve como contador para controlar el número de veces que se repite un ciclo, de tal manera que la condición involucra al contador. La representación en pseudocódigo y diagrama de flujo de estas estructuras se muestran en la siguiente tabla: Tipo Pseudocódigo Diagrama de flujo Descripción Mientras<condición>hac Verifica si la condición se er cumple, en tal caso ejecuta Ciclo el conjunto de instrucciones Mientras <instrucciones> y se vuelve a repetir el (while) ciclo. Fin_Mientras A diferencia del Mientras¸ Hacer esta estructura primero Ciclo Hacer- ejecuta el conjunto de <instrucciones> Mientras instrucciones y después (do while) verifica que la condición se Mientras <condición> cumpla, en caso de ser verdadera se repite el ciclo. Desde <inicialización>mientras Inicializa el valor del <condición>, contador, verifica si la <incremento/decremento condición se cumple y en Ciclo Desde- > tal caso ejecuta las mientras instrucciones, (for) <instrucciones> posteriormente incrementa o decrementa la variable Fin_Desde contador. Tabla 2.5 Estructuras repetitivasEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 47
  • 48. Fundamentos de programaciónPrograma Desarrollado En la unidad 4 estudiaremos con mayor detalle cada una de estas estructuras. Actividad 3: Diseño de un algoritmo con estructuras repetitivas Diseña un algoritmo, en pseudocódigo o diagrama de flujo, que resuelva el problema que te presentará tu facilitador(a) utilizando ciclos. Actividad de Autoevaluación Ingresa al aula virtual para realizar el cuestionario de autoevaluación. Consideraciones específicas de la unidad Como evidencias de la unidad se proponen dos problemas en el mundo de la ardilla, el primer algoritmo tendrás que realizarlo utilizando pseudocódigo en tanto que el segundo tendrás que representarlo en diagrama de flujo. Además de las instrucciones que aparecen en la tabla 2.1 puedes utilizar la instrucción giraDerecha() que hace que la ardilla de vuelta a la derecha. Referencias: • Böhm, C., & Jacopini, G. (1966). Flow diagrams, Turing machines, and languages only with two formation rules". Communications of the ACM, 9 (5), 366-371. • Cairó, O. (2005). Metodología de la programación: Algoritmos, diagramas de flujo y programas. México, D.F.: Alfaomega. • Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. España: Mc Graw Hill. • Reyes, A., & Cruz, D. (2009). Notas de clase: Introducción a la programación. México, D.F.: UACM. • Viso, E., & Pelaez, C. (2007). Introducción a las ciencias de la computación con Java. México, D.F.: La prensas de ciencias, Facultad de Ciencias, UNAM.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 48
  • 49. Fundamentos de programaciónPrograma Desarrollado Unidad 3: Introducción al lenguaje C Propósitos En esta unidad: • Distinguirás la estructura de un programa en lenguaje C. • Declararás las variables y constantes que se utilizan en un algoritmo en lenguaje C • Codificarás expresiones matemáticas en lenguaje C. • Utilizarás funciones de la biblioteca estándar de C para codificar instrucciones de entrada y salida y funciones matemáticas. • Utilizarás un entorno de trabajo de C para escribir, compilar y ejecutar programas escritos en C. Competencia específica Utilizar el lenguaje de programación C para resolver problemas a través de la implementación de algoritmos secuenciales. Introducción En la unidad anterior se presentó un conjunto de instrucciones que una ardilla (ficticia) podría realizar y se mostró cómo, a través de éstas, la ardilla podía resolver varios problemas siempre y cuando se definiera un algoritmo. Ahora veamos qué relación hay entre el mundo de la ardilla y las computadoras: la ardilla representa la computadora, que sólo puede ejecutar un conjunto de instrucciones definidas; además, al igual que la ardilla, la computadora por sí misma es incapaz de resolver ningún problema, para hacerlo necesita un programa que pueda seguir (ejecutar) para obtener el resultado deseado, así como la ardilla necesitaba un algoritmo que le indicara cómo realizar una tarea específica. Por lo anterior, en esta unidad se mostrará la forma en que se crean programas en el lenguaje de programación C, desarrollado por Dennis M. Ritche en el año de 1972, en los laboratorios Bell de la AT&T, y que posteriormente fue estandarizado por un comité del ANSI (por sus siglas en inglés American National Standard Institute) dando lugar al ANSI C, a través del cual se garantiza que cualquier programa creado bajo este estándar pueda ser ejecutado en cualquier computadora (Kernighan & Ritchie, 1991). A lo largo de la unidad se introducen los elementos básicos del lenguaje de programación C: tipos de datos, variables y constantes, expresiones aritméticas, funciones matemáticas y funciones de entrada y salida, con el fin de empezar a crear programas secuenciales que resuelvan problemas simples. Como primer tema analizaremos la estructura del programa “hola mundo”, pues como ya es costumbre en programación es el primer programa que se realiza cuando se aprende un nuevo lenguaje de programación. A partir de este ejemplo se revisa la estructura de un programa y los elementos que lo integran.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 49
  • 50. Fundamentos de programaciónPrograma Desarrollado 3.1. Componentes de un programa En general, “un programa es una secuencia de instrucciones mediante las cuales se ejecutan diferentes acciones de acuerdo con los datos que se estén procesando (López, 2005)”. En la unidad 1 se explicó que un programa sólo puede ser ejecutado por una computadora solamente si está escrito en lenguaje de máquina, pero existen lenguajes de programación, que son fáciles de entender para los seres humanos, mediante los cuales se pueden escribir programas más legibles conocidos como programas fuentes –en C los programas fuente tiene extensión .c–, que son traducidos a lenguaje de máquina mediante compiladores o traductores. En el caso de C es un lenguaje compilado, por lo que se genera un programa ejecutable con extensión .exe, que puede ser ejecutado cada vez que se desee sin necesidad de volver a compilar el programa fuente, a menos que se realice algún cambio. De acuerdo con su creador un programa fuente en C, cualquiera que sea su tamaño, consta de funciones y variables. Una función contiene un conjunto de instrucciones, también llamadas preposiciones o enunciados, que especifican las operaciones que la computadora debe realizar; en tanto, las variables son los espacios de memoria donde se almacenan los valores utilizados en dichas operaciones(Kernighan & Ritchie, 1991, pág. 6). Como se ha mencionado, el primer programa que se debe escribir cuando se aprende un nuevo lenguaje es “hola mundo”, así que para no perder la tradición a continuación se muestra cómo se implementa este programa en lenguaje C. /*Directivas de preprocesador*/ #include<stdio.h> /* Definición de función Principal */ main( ) { printf(“Hola mundo… n”); } Programa 3.1: hola.c El programa hola.c solo tiene una función: main; generalmente se puede dar cualquier nombre a las funciones que se definan en un programa, sin embargo, main es una función especial que siempre debe aparecer en algún lugar del programa, ya que es el punto desde el cual se inicia la ejecución (equivale a la instrucción de inicio de un algoritmo). Los paréntesis que aparecen después de la palabra main indican que se trata de una función; las instrucciones que forman parte de ésta, llamadas cuerpo de la función, van encerradas entre llaves “{ }”, señalando el inicio y fin de la misma, respectivamente.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 50
  • 51. Fundamentos de programaciónPrograma Desarrollado Las instrucciones que comienzan con “/*” y terminan con “*/”, se llaman comentarios e indican que todo lo que está escrito entre esos símbolos no son instrucciones que la computadora debe ejecutar sino información de interés para el programador; por ejemplo la primera línea de código: /*Directivas de preprocesador*/ Otro tipo de instrucciones especiales son las directivas del preprocesador, que son instrucciones que se realizan antes de la compilación del programa, un ejemplo es: #include<stdio.h> Se distinguen porque inician con el carácter gato “#”, en este caso esta instrucción le indica al compilador que debe incluir la información que está definida en el archivo de biblioteca stdio.h, en el cual se encuentran todas las funciones de salida y entrada, como printf. Los compiladores de lenguaje C ofrecen distintas directivas, sin embargo las que utilizaremos son: • #define, que sirve para definir de constantes y/o macros • #include, que se utiliza para incluir otros archivos En el cuerpo de la función main, del programa 3.1, sólo aparece una instrucción que es la invocación a la función printf con el argumento “Hola mundo… n”. printf(“Hola mundo… n”); Invocamos o llamamos una función cuando requerimos que se ejecute con un conjunto de datos específicos, a los cuales llamamos argumentos. Una función se invoca o llama al nombrarla, es decir, escribiendo su nombre seguido de la lista de argumentos, separados por comas y encerrados entre paréntesis. En otras palabras, los argumentos son los valores que una función necesita para realizar la tarea que tiene encomendada, por ejemplo, la función printf tiene como fin imprimir la cadena de caracteres que recibe como parámetro, en este caso particular imprimirá la frase “Hola mundo…” seguida de un salto de línea, que es lo que representa la secuencia de caracteres “n”. Actividad 1.Introducción al lenguaje C - Presentación Como sabes, la intención de esta asignatura es que aprendas a diseñar programas en C que te sean de utilidad para resolver problemas por medio de la computadora. Para lograrlo, es necesario que perseveres y practiques constantemente hasta habituarte en el manejo de los elementos de C; con ese propósito, durante toda esta Unidad y las que siguen, te presentaremos varios ejercicios que deberás realizar como complemento de las demás Actividades y Evidencias de Aprendizaje. Para conocer los detalles ingresa al aula virtual.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 51
  • 52. Fundamentos de programaciónPrograma Desarrollado Actividad 1. Introducción al lenguaje C –Ejercicio A El primer ejercicio consiste en la elaboración del programa hola_mundo.c. Para conocer más detalles ingresa al aula virtual. 3.1.1. Instrucciones Una instrucción o enunciado en lenguaje C se puede definir como una expresión que tiene alguna consecuencia, generalmente la consecuencia se ve reflejada en el cambio del valor que está almacenado en las variables. De acuerdo con su estructura sintáctica se pueden clasificar en dos tipos: simples y compuestas. Las instrucciones simples se distinguen porque terminan con punto y como “;”. La sintaxis es: <instrucción>; Como ejemplo de instrucciones simples tenemos la declaración de variables, la llamada de funciones y la asignación. int x; x = 2*y; printf(“Hola”); En cambio las instrucciones compuestas son un conjunto de instrucciones que se escriben entre llaves “{…}”, para formar, lo que conocemos como, un bloque de instrucciones. La sintaxis es { <instrucción>; <instrucción>; … <instrucción>; } Un ejemplo de este tipo de instrucciones es el cuerpo de la función main, del programa 3.1.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 52
  • 53. Fundamentos de programaciónPrograma Desarrollado 3.1.2. Comentarios Los comentarios son textos que sirven como información al programador y no son procesados por el compilador, es decir, no son instrucciones que debe realizar la computadora y por lo tanto no son traducidos a lenguaje de máquina. Para que un texto sea comentario debe estar entre los símbolos /* (marca el comienzo) y*/ (marca el final de comentario).Pueden ir en cualquier parte del programa. Un buen programador debe comentar sus programas para que otras personas puedan entender la lógica del programa, e incluso, los comentarios también le sirven al programador cuando en un tiempo futuro requiera realizar cambios. También es recomendable incluir al inicio del programa: el nombre del programa, el nombre del programador, una breve descripción de la tarea que realiza, las fechas de creación y de la última modificación, todo esto encerrado entre comentarios. Por ejemplo, al inicio del programa 3.1 sería conveniente incluir el siguiente comentario: /* Programa: hola.c Programador: Pedro Pérez Descripción: El programa imprime la cadena “hola mundo” Fecha de creación: Agosto, 2010 Última modificación: Septiembre, 2010 */ Los comentarios también se pueden incluir al lado de una instrucción para describir de qué se trata, por ejemplo: printf(“Hola mundo”); /* Imprime el mensaje “Hola mundo” en la pantalla*/ 3.1.3. Palabras reservadas Las palabras reservadas de cualquier lenguaje de programación, se llaman así porque tienen un significado especial para el compilador, el lenguaje C tiene 32 palabras reservadas (27 fueron definidas en la versión original y cinco añadidas por el comité del ANSI: enum, const, signed, void y volatile), todas ellas escritas con minúsculas. 6 En la siguiente tabla se muestran todas las palabras claves o reservadas de lenguaje C. 666 En este punto es importante destacar que el lenguaje C distingue entre mayúsculas y minúsculas.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 53
  • 54. Fundamentos de programaciónPrograma Desarrollado asm continue float register struct volatile auto default for return switch while break do goto short typedef case double if signed union char else int sizeof unsigned const enum long static void Tabla 3.1: Palabras reservadas de C Una vez que se han descrito los diferentes elementos que integran un programa de lenguaje C, en la siguiente sección se describe la estructura general de un programa en C. 3.1.4. Estructura general de un programa Si observas el programa hola.c, la primera instrucción en el programa es la directiva al preprocesador, seguida de la función main y las instrucciones que la integran, esta estructura corresponde a los programas más simples, pero es similar a la de cualquier programa en C. La forma general de cualquier programa en C es la siguiente: <instrucciones para el preprocesador> <declaraciones globales> <tipo_devuelto> main(<lista de parámetros>) { <lista de instrucciones> } Y como se ha mencionado, se pueden incluir comentarios en cualquier parte del código. A continuación se presenta un programa que calcula el área de una circunferencia dada la medida de su radio. /* Directivas del procesador (bibliotecas) */ #include<stdio.h> /* Declaraciones globales */ const float PI = 3.1416; /* Función Principal */ main( ) { /* Declaraciones de variables locales la función main*/ float radio, area; printf(" Calcula el area de una circunferencian");Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 54
  • 55. Fundamentos de programaciónPrograma Desarrollado printf(" Ingresa el radio: "); scanf("%f", &radio); area = PI * radio * radio; printf(" Area = %.2f",area); getchar(); getchar(); } Programa 3.2: areaCircunferencia.c Por el momento, basta con que observes la estructura del programa, que se hace evidente con los comentarios, el significado de cada una de las líneas de código se irá definiendo en las siguientes secciones. Para cerrar esta sección en la siguiente figura se muestra la ejecución del programa con la entrada radio=3. Figura 3.2: Ejecución del programa areaCircunferencia.c utilizando Dev-C++ Actividad 1. Introducción al lenguaje C –Ejercicio B En esta ocasión, lo que tienes que hacer es escribir y compilar el programa en la computadora utilizando DevC++, posteriormente ejecútalo con diferentes valores para el radio e ingresa un comentario al respecto al Foro Introducción al lenguaje C. 3.2. Tipos de datos En la Unidad 1 se mencionó que todos los datos que son procesados por una computadora se almacenan en la memoria principal y, no importa de qué tipo sean, se representan por medio de unos y ceros, sin embargo, no todos se pueden representar con el mismo número de bits 7, esto sí depende del tipo que se trate. Por ejemplo, los caracteres como: ‘a’, ‘@’,’Z’, entre otros, se representan utilizando 8 bits, en cambio para representar un número decimal se utilizan, al menos, 32 bits; por lo que cuando se crea un espacio de memoria es necesario indicar qué tipo de dato se desea almacenar ahí, para que se 7 Recuerda que un bit se definió como la unidad mínima de información, esto es, 1 ó 0.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 55
  • 56. Fundamentos de programaciónPrograma Desarrollado reserve la cantidad de celdas de memoria que se necesitan y las operaciones que se pueden realizar con ellos. En general, los tipos de datos que existen, independientemente de un lenguaje de programación, se pueden clasificar de la siguiente forma: Enteros  Numéricos Decimales Simples  Lógicos (verdadero o falso)  Alfanuméricos (caracteres) Unidimensionales  Arreglos Estructurados Multidimensionales  Estructuras o registros Tabla 3.2: Tipos de datos Por el momento, sólo nos enfocaremos en los tipos de datos simples definidos en el estándar de C, en la Unidad 5 se estudiarán los datos estructurados. En la siguiente tabla se muestran los tipos de datos simples en C: Tipo Descripción Ejemplo Su tamaño equivale a ocho ´a´, bits, capaz de contener un ´C´, ´3´ char carácter del conjunto de caracteres ASCII. Un entero, normalmente ocupa mínimo 16 bits, pero 1024, int su tamaño es según la -258 máquina en que se ejecute. Número de punto flotante de 10.5, Float precisión normal. -11.6 Punto flotante de doble Double 0.00045, precisión -0.55236 Tabla 3.3: Tipos básicos en CEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 56
  • 57. Fundamentos de programaciónPrograma Desarrollado Es posible aumentar o disminuir la capacidad de representación de los números utilizando los modificadores long, short y unsigned. De esta manera las combinaciones que se ajustan al estándar ANSI, junto con sus rangos mínimos, son: Tipo Bits Rango Char 8 -127 a 127 unsigned char 8 0 a 255 signed char 8 -127 a 127 Int 16 -32767 a 32767 unsigned int 16 0 a 65535 signed int 16 -32767 a 32767 short int 16 -32767 a 32767 unsigned short int 16 0 a 65535 signed short int 16 -32767 a 32767 long int 32 -2147483647 a 2147483647 signed long int 32 -2147483647 a 2147483647 unsigned long int 32 0 a 4294967295 Float 32 seis dígitos de precisión Double 64 diez dígitos de precisión long double 64 diez dígitos de precisión Tabla 3.4: Tipos básicos y modificadores Una vez que conocemos lo tipos de datos que se pueden representar en lenguaje C, es conveniente saber cómo se reservan espacios de memoria donde son almacenados, esto es justo lo que se explica en el siguiente tema. 3.3. Variables y constantes Las variables y las constantes en lenguaje C se utilizan para almacenar valores, la diferencia que existe entre ellas es que el valor almacenado en una variable puede ser modificado en cualquier instante del programa en tanto que las constantes no pueden modificarse. Formalmente, una variable es un espacio de memoria que tiene asignado un nombre (también llamado identificador) y se utiliza para almacenar un valor que puede ser modificado durante la ejecución de un programa, a este valor que se encuentra almacenado en una variable en un momento dado se le llama estado de la variable. Por lo contrario, una constante es un dato cuyo valor se establecen en tiempo de compilación y no pueden cambiar durante la ejecución del programa. Existen dos tipos de constantes: literales y simbólicas. Las segundas, al igual que las variables, también tienen asignado un nombre. A lo largo de esta sección descubrirás cómo puedes construir variables y constantes en lenguaje C, así que lo primero será listar las reglas que debes seguir para nombrarlas.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 57
  • 58. Fundamentos de programaciónPrograma Desarrollado 3.3.1. Identificadores En lenguaje C hay una serie de restricciones en cuanto a los nombres o identificadores, ya sea de variables, constantes o funciones. Éstas son: a) Los identificadores se integran por letras y dígitos pero es necesario que el nombre siempre comience con una letra, por ejemplo: enteroA, arco3, S184. b) No puede contener caracteres especiales, por ejemplo, acentos (á,í), la letra eñe (Ñ), gato (#), guión (-). El carácter de subrayado “_”es el único carácter especial que puede utilizarse, generalmente se usa para darle una mejor legibilidad al nombre de una variable. Por ejemplo: entero_A, area_Circulo, i_elemento. c) El lenguaje C distingue entre letras mayúsculas y minúsculas, esto significa que los siguientes identificadores son distintos: area, Area, AREA. d) No pueden contener espacios en blanco. e) No pueden ser palabras reservadas. Aunque no es una regla, se recomienda que los identificadores sean significativos, es decir, que el nombre indique qué dato se está almacenando ahí. Ejemplo 3.1: 1) Se requiere una variable para almacenar el radio de un círculo Las opciones sugeridas son: radio, radioCirculo, radio_circulo. 2) Se requiere un identificador para una variable que almacene el promedio de ventas anuales de una tienda departamental. Opciones sugeridas: promedioVentas, prom_Ventas, promAnual. 3) Almacenar el número telefónico de una persona. Opciones sugeridas: tel, telefono. Una vez definidas las reglas de cómo escribir los nombres de las variables y los tipos básicos que pueden tener, estás listo para descubrir cómo se crean las variables en lenguaje C. A esta acción se le denomina declaración de variables.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 58
  • 59. Fundamentos de programaciónPrograma Desarrollado 3.3.2. Declaración e inicialización de variables La declaración de una variable es una instrucción que proporciona información de la variable al compilador, para que éste reserve en memoria el espacio adecuado y la referencia (identificador) para tener acceso a ella. Las declaraciones en general tienen la siguiente sintaxis: <tipo><identificador>; Donde <tipo> se refiere un tipo básico de C y el <identificador> se refiere al nombre con el cual se identificará el espacio de memoria reservado, puede ser cualquier nombre siempre y cuando se respeten las reglas vistas previamente.Veamos los siguientes ejemplos: int edad; /* declara una variable de tipo entero con el identificador edad*/ float area; /* declara una variable de tipo float a la cual identificará por area*/ También es posible declarar una lista de variables de un mismo tipo separando los nombres con comas “,” <tipo><identificador1>, … , <identificadorN>; Podemos ver un ejemplo de este tipo de declaración en el programa que calcula el área de una circunferencia (programa 3.2), cuando declaramos las variables locales a la función main float radio, area; Siempre es posible asignarles un valor inicial a las variables cuando las declaramos, a esta operación se conoce como inicialización. La sintaxis es: <tipo><identificador>=<valor>; Del mismo modo, podemos inicializar varias variables: <tipo><identificador1> = <valor1>, … , <identificadorN> = <valor2>; Para ilustrar esto, se presentan las siguientes instrucciones: int edad = 18; float radio = 3.0, area = 0.0; En la figura 3.2 se muestra una representación gráfica de estas declaraciones e inicializaciones, la columna de Dirección representa la dirección física de los registros en la memoria RAM y si ha sidoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 59
  • 60. Fundamentos de programaciónPrograma Desarrollado asignada a una variable también se escribe su identificador, en contenido se muestra el dato que está almacenado en dicha dirección. El estado de una variable (memoria) hace referencia al valor que hay almacenado en un momento determinado. MEMORIA Dirección Contenido Dirección Contenido 51 01 3.0 Radio 02 52 18 Edad 03 53 54 04 0.0 Area 05 55 … 56 Figura 3.2: Memoria y declaración e inicialización de variables De lo anterior tenemos que: a la variable edad le corresponde la dirección de memoria 02 y su estado es 18; a la variable radio le corresponde la dirección 51 y su estado es 3.0; y por último, a la variable area le corresponde la dirección 54 y el estado es 0.0. 3.3.3. Tipos de constantes Las constantes son expresiones con un significado invariable, en un programa puede haber dos tipos de constantes: literales y simbólicas. Las constantes literales son valores de un determinado tipo escritos directamente en un programa y pueden ser de los siguientes tipos: a) Constantes numéricas, que son números representados en sistema decimal, algunas veces se estila escribir una letra que indique el tamaño o tipo de la constante numérica: Enteros: Por ejemplo 123, 2006, -38… Enteros Largos: Se consideran números enteros que superan un entero (int) generalmente valores mayores a 32,000; se le agrega los sufijos l ó L por ejemplo: 123456789L. Enteros sin Signo: Aquí se define que el valor de la constante se va a considerar como un número positivo o mayor a cero, en estos casos se agrega el sufijo U o u así por ejemplo podemos escribir: 123456789LU. Flotantes: Los valores numéricos que impliquen precisión decimal se pueden escribir de dos formas, la primera sería: 14324.983 o 3.1416. También se puede representar en representaciónEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 60
  • 61. Fundamentos de programaciónPrograma Desarrollado exponencial (e-n), por ejemplo: 1.1434E2 o 1.1432e-5. También se ocupan los sufijos f o F y l o L para especificar los tipos double. Como puedes observar, las constantes reales con representación exponencial, tienen como valor una parte entera o real en forma decimal, seguida por la letra E, seguida de una constante entera, que se interpreta como exponente de la base 10. b) Constantes carácter, que se representada internamente por el lenguaje C como un número entero corto (short int). Una constante carácter siempre debe ir entre apóstrofes, por ejemplo: ‘x’, ‘A’. También existen constantes carácter que aparentan ser compuestas pero sólo son representaciones de caracteres de formato o caracteres especiales, y en C se les conoce como secuencias de escape. ‘n’ Salto de línea ‘t’ Tabulador ‘b’ Espacio hacia atrás ‘f’ Salto de página ‘”’ Comillas ‘’ Barra invertida Tabla 3.5: Secuencias de escape c) Constantes cadena, que son una secuencia de caracteres entre comillas, incluyendo secuencias de escape, por ejemplo: “hola”, “hola mundo n”. Por otro lado, las constantes simbólicas representan datos permanentes que nunca cambian. Ahondaremos en este tema en la siguiente sección. 3.3.4. Declaración de constantes En C existen dos formas de declarar una constante simbólica. La primera es utilizando la directiva de preprocesador #define, la cual asocia un identificador a un valor constante, sin reservar espacio en memoria, por lo que no podemos decir que se declara, sólo se define. La sintaxis general es la siguiente: #define<identificador><valor_constante> Por ejemplo: #define PI 3.1416Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 61
  • 62. Fundamentos de programaciónPrograma Desarrollado Con esta instrucción cada vez que en el programa se escriba el identificador PI éste será sustituido por el compilador con el valor de 3.1416 (no se almacena el valor 3.1416 en ningún espacio de memoria sólo se hace una sustitución textual en el momento de compilación). La segunda forma de declarar una constante simbólica es reservando espacio de memoria que tenga la restricción de sólo lectura, para impedir que el valor sea cambiado, en este caso si la declaramos. La sintaxis general es similar a la forma de declarar una variable sólo que se antepone al tipo la palabra reservada const y es obligatorio asignar el valor. const<tipo><identificador> = <valor_constante>; Por ejemplo: const float PI = 3.1416 ; La directiva #define debe ser al principio del programa antes del main, en cambio, la declaración de una constante mediante const puede ser dentro o fuera de las funciones al igual que las declaraciones de variables. Se recomienda escribir el nombre de una constante con letras mayúsculas para diferenciarlas de las variables, pero las reglas son exactamente las mismas que para los identificadores de las variables. Evidencia de aprendizaje. Programa en C. Análisis del problema En la unidad anterior describiste el problema que resolverás a lo largo del curso, como evidencia de esta unidad debes realizar el análisis del problema, definiendo claramente los datos de entrada y la salida del programa junto con su tipo de datos, además debes considerar que los identificadores respeten las reglas de C. 3.4. Expresiones matemáticas Una expresión matemática puede ser un número, una variable, una constante o la combinación de operadores y todas las anteriores. Toda expresión al ser evaluada produce un valor. Se dividen en dos tipos de acuerdo al tipo de datos que devuelven cuando son evaluadas: expresiones aritméticas cuando el resultado de la evaluación es un número y expresiones booleanas cuando el resultado de la evaluación es un valor booleano (verdadero o falso). En este punto es importante destacar que el modo en que el lenguaje C maneja los valores booleanos es por medio de valores enteros: cero equivale a falso y cualquier entero distinto de cero representa verdadero. Las expresiones matemáticas permiten modelar situaciones reales, por ejemplo, mediante las expresiones aritméticas podemos modelar la forma de calcular el área de cualquier figura, también podemos representar la forma de calcular las raíces de un polinomio de segundo grado, o calcular elEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 62
  • 63. Fundamentos de programaciónPrograma Desarrollado monto de una venta, etc. En cambio las expresiones booleanas son la base para construir programas que pueden tomar decisiones. Veamos los siguientes ejemplos: Ejemplo 3.2: a) La hipotenusa es igual a la raíz cuadrada de la suma de los cuadrados de catetos. Expresión aritmética: ← √2 + 2 Codificación en C: c =sqrt(a*a + b*b); b) ¿x es un número par? Sabemos que un número es par si es divisible entre 2, en otras palabras, si el residuo de la división entre dos es cero, lo cual se puede expresar con el operador de módulo, que devuelve el residuo de una división. Expresión booleana: 2 = 0 Codificación en C: x % 2 == 0 En el siguiente subtema se presentan los operadores básicos del lenguaje C, tanto aritméticos como booleanos. 3.4.1. Tipos de operadores Los operadores son palabras o símbolos que hacen que permiten realizar operaciones con los datos de un programa, para cada tipo de datos hay una serie de operadores definidos. Entre todos los operadores se distingue el operador de asignación “=”, que se puede leer como “guarda un valor en la variable indicada”, el valor puede ser una constante literal o el resultado de una expresión. Cabe señalar que este operador en pseudocódigo o diagrama de flujo lo hemos representado con una flecha apuntado hacia la izquierda ←. Veamos algunos ejemplos: radio = 3.0; /* modifica el estado de la variable radio con el valor 3.0*/ area = PI * radio *radio; /* modifica el estado de la variable por el resultado de evaluar la expresión PI * radio * radio */ Los operadores aritméticos definidos en C son: “+” (suma), “-” (resta), “*” (multiplicación),“/” (división) y “%”(módulo). Este último representa el residuo de dividir dos números enteros, por ejemplo si realizamosEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 63
  • 64. Fundamentos de programaciónPrograma Desarrollado la división de 6 entre 15 (15/6), el cociente es 2 y el residuo es 3, al aplicar el operador módulo a estos valores tenemos: 15 % 6 → 3 21 % 4 → 1 En C también existen los operadores de incremento “++” y decremento “--“, éstos tienen el efecto de aumentar o decrementar en una unidad el valor de una variable, supongamos que estamos trabajando con la variable x: x++;/* equivale a hacer: x = x + 1;*/ x--;/* equivale a hacer: x = x – 1;*/ Por ejemplo, si el valor de x es 5 el resultado de aplicar ++ y -- es: x++; → 6 x--; → 4 Los operadores que permiten construir expresiones booleanas son: • Operadores relacionales, que manipulan expresiones aritméticas y son:“>” (mayor que), “<” (menor que), “>=” (mayor o igual), “<=” (menor o igual), “==” (igual), “!=” (distinto) • Operadores booleanos, también llamados lógicos, manipulan únicamente expresiones booleanas y son: “!” (negación), “||” (disyunción) y “&&” (conjunción). Observa que el operador de igualdad se escribe con dos símbolos de igualdad seguidos (==). El error más común es escribir una comparación con un sólo símbolo de igualdad, recuerda que (=) es el operador de asignación y su significado es totalmente distinto. En cuanto a los operadores booleanos, su significado es el siguiente: • Negación“!”, es un operador unario que cambia el valor de verdad de la expresión a la cual se le aplica. Por ejemplo, si el valor de verdad de expresión es verdadero entonces devuelve falso, y viceversa. Por ejemplo, si x=2, y=3, z=5. !(z > x ) → !(5 > 2 )→ !(1)→ 0 (falso) !(x > y ) → !(2 > 3 )→ !(0)→ 1 (falso) En pseudocódigo o diagrama de flujo se representa con la palabra en inglés NOT. • Conjunción“&&”, es un operador binario que se evalúa como verdadero sólo cuando las dos expresiones involucradas son verdaderas, en caso contrario devuelve falso. Por ejemplo, si evaluamos las siguientes expresiones en el estado x=2, y=3, z=5.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 64
  • 65. Fundamentos de programaciónPrograma Desarrollado (x>y) && (z>y) → (2 > 3) && (5 > 3) → 0&&1 → 0 (falso) !(x > y) && (z>y) →!(2 > 3) && (5 > 3) → ! (0) &&1 → 1&&1 → 1 (verdadero) En pseudocódigo y diagrama de flujo se representa con la palabra en inglés AND. • Disyunción“||”, también es un operador binario que devuelve únicamente devuelve falso si los dos operadores son falsos, en caso contrario devuelve verdadero. Nuevamente, tomemos el mismo estado de las variables x=2, y=3, z=5. (x>y)||(z>y) →(2>3)||(5>3) → 0||1 → 1 (verdadero) (x>y)||(y>z) →(2>3)||(3>5) → 0||0 → 0 (falso) En pseudocódigo y diagrama de flujo se representa con la palabra en inglés OR. En C existen otro tipo de operadores, sin embargo, su estudio supera los objetivos de este curso por lo que no los revisaremos, si deseas saber más puedes consultar (Joyanes & Zohanero, 2005). 3.4.2. Evaluación de expresiones La evaluación de las expresiones depende de tres cosas, principalmente, el estado de las variables que aparecen en la expresión, el significado de los operadores y su precedencia. Esta última se refiere a la prioridad de los operadores, es decir, el orden en el que se evalúan, eliminando con esto la ambigüedad de las expresiones, por ejemplo, si tenemos la expresión: 2+3*5 Podríamos evaluarla de dos diferentes formas: La primera es hacer primero la suma 2+3 (=5) y después multiplicar el resultado por 5. De tal manera obtendríamos como resultado final 25. Otra manera sería realizar primero la multiplicación 3*5 (=15) y sumar el resultado a 2, obteniendo 17 como resultado final. Pero sabemos que en matemáticas primero se realiza la multiplicación y después la suma, en otras palabras, tiene mayor prioridad la multiplicación que la suma. Por lo tanto, el resultado correcto de la expresión 2 + 3 * 5 es 17. En la siguiente tabla se muestra la precedencia de operadores de lenguaje C que se han presentado.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 65
  • 66. Fundamentos de programaciónPrograma Desarrollado Operadores Prioridad ( ) Mayor -(unario), ++, -- *, /, % +, - <, >, >= , <= ==, != &&, || = Menor Tabla 3.6: Prioridad de operadores Los operadores que se encuentran en el mismo nivel de precedencia se ejecutan de izquierda a derecha según aparecen en la expresión. Veamos el siguiente ejemplo: Ejemplo 3.3: Dada la siguiente expresión matemática para convertir grados centígrados (C) a su 9 = + 32 equivalente Fahrenheit (F), 5 Su codificación en C es: F= (9.0/5.0)*C +32; Se escribe 9.0 y 5.0 para que la división devuelva un número flotante, de lo contrario la división será entera. En este caso las variables F y C, deben ser declaradas como float. Evaluando, paso a paso, la expresión en el estado de la variable C = 30 tenemos: Expresión actual Estados de las variables C F F= (9.0/5.0)*C +32; 30 ¿? F= (9.0/5.0)*30 +32; Igual al anterior F= 1.8*30 +32; Igual al anterior F= 54 +32; Igual al anterior C F F= 86; 30 86 Observa que el único operador que cambia el estado de una variable es el de asignación “=”.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 66
  • 67. Fundamentos de programaciónPrograma Desarrollado Ejemplo 3.4: Ahora evaluemos la expresión: (x % 2 == 0) Considerando que el estado de la variable x=24 Expresión actual Estados de las variables x % 2 == 0 X 24 0 == 0 Igual al anterior 1 Igual al anterior En este caso la evaluación de la expresión no afecta el estado de la variable, esto es porque no contiene ningún operador de asignación, sin embargo podemos decir que el resultado de su evaluación es verdadero. Actividad de Autoevaluación. Unidad 3. Para esta actividad deberás ingresar al aula a resolver un cuestionario de opción múltiple que te ayudará a identificar qué tanto dominio tienes sobre los temas que hasta ahora has estudiado. 3.5. Bibliotecas y funciones El lenguaje C en realidad es un lenguaje reducido, en comparación con otros lenguajes de programación, por ejemplo, no tiene instrucciones de estrada y salida, y tampoco cuenta con operadores o funciones para calcular la raíz cuadrada de un número o su potencia, entre otras. Sin embargo, para compensar esto el lenguaje C ofrece un vasto conjunto de bibliotecas de funciones, que para fines prácticos se pueden considerar como parte de C. Cabe mencionar que también es posible definir nuevas bibliotecas, sin embargo, el lenguaje C tiene definidas diversas funciones de uso frecuente, que para fines de este curso son más que suficiente, por lo que este tema no se estudiará en esta ocasión. 8 Las funciones que más se utilizan están agrupadas en bibliotecas estándar, declaradas como archivos de cabecera, de tal manera que para utilizarlas se debe incluir en el archivo utilizando la directiva #include seguida del nombre del archivo encerrado entre “<>” 8Si deseas más información se te recomienda consultar (Joyanes & Zohanero, 2005).Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 67
  • 68. Fundamentos de programaciónPrograma Desarrollado Las bibliotecas estándar que usaremos en este curso son: • stdio.h en esta biblioteca se encuentran definidas las funciones estándar de entrada y salida – que representan la tercera parte de la biblioteca–, por ejemplo, declara la función printf que sirve para imprimir datos en pantalla y scanf que se utiliza para leer de datos ingresados mediante el teclado. • stdlib.h incluye funciones para conversión numérica, asignación de memoria y tareas similares, llamadas funciones de utilería. En esta biblioteca se declara la función system mediante la cual se envían mensajes al sistema operativo para que ejecute una tarea. • math.h declara funciones matemáticas, como la función sqrt que calcula la raíz cuadrada de un número. • ctype.h declara funciones para prueba de clasificación de caracteres, por ejemplo, si es un dígito o un carácter. Observa que todas las bibliotecas estándar tienen extensión “.h” 9 3.5.1. Funciones matemáticas La siguiente tabla muestra algunas de las funciones predefinidas en lenguaje C declaradas en la biblioteca math.h. Función Descripción Argumento Resultado Ejemplo sqrt(x) Raízcuadrada flotante flotante sqrt(900) = 90 exp(x) Function exponencial flotante flotante exp(2.0)= 2.718282 fabds(x) Valor absoluto entero o flotante entero o flotante fabs(-5) = 5 log(x) Logaritmoneperiano de x entero o flotate flotante log(0.5) = -0.693 Log10(x) logaritmo decimal de x entero o flotante flotante Log10(0.5) = -0.301 floor(x) Redondeohaciaabajo flotante entero floor(6.5)=6 ceil(x) Redondeohaciaarriba flotante entero ceil(6.5)=7 sen(x) seno de x entero o real flotante sen(0.5) = 0 pow(x,y) Devuelve la potencia de x elevada a la y entero o flotante flotante pow(5,2) = 25 cos(x) coseno de x flotante flotante cos(0.5) = 1 sin(x) seno de x flotante Flotante sin(0.0) = 0 tan(x) Tangente de x flotante Flotante tan(0.0) = 0 Tabla 3.7: Funciones matemáticas Con esta información es posible codificar algoritmos que requieran este tipo de operaciones. Por ejemplo, la fórmula para calcular el área de una circunferencia, que se aparece en el programa 3.2. area = PI * radio * radio; 9 En (Kernighan & Ritchie, 1991) puedes consultar las funciones que están definidas en cada una de las bibliotecas estándar.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 68
  • 69. Fundamentos de programaciónPrograma Desarrollado Se puede codificar de la siguiente manera: area = PI * pow(radio,2); 3.5.2. Funciones de entrada y salida En los programas que hemos visto aparece la función de salida estándar printf, que se encarga de imprimir un mensaje en la pantalla. La sintaxis general es: printf(<cadena_de_control>, <lista_de_identificadores>); Donde <cadena_de_control> representa el mensaje de texto que se desea desplegar en el monitor y siempre tiene que ir en comillas, opcionalmente puede incluir secuencias de escape o especificadores de control. Y <lista_de_identificadores> es una lista con los identificadores de las variables o las expresiones que serán desplegadas, separadas por comas. Las secuencias de escape se mostraron en la tabla 3.5. Los especificadores de conversión se utilizan para imprimir valores dentro de la cadena de control especificados por una variable, una constante o una expresión. En la siguiente tabla se muestran los que más se usan. Especificador Acción %d Insertar un entero (int) %i Insertar un entero tipo (int) %ld Insertar un entero tipo (long) Insertar un número flotante %f tipo (float) Insertar un número de tipo %lf (double) %c Insertar un caracter (char) %s Insertar una cadena(char [ ]) Tabla 3.8: Especificadores de conversión Ejemplo 3.5: Suponiendo que el estado de las variables es radio=3 y area=28.27, printf(“El area del circulo con radio %d es %f n”,radio,area); La salida de la instrucción anterior sería: El area del circulo con radio 3 es 28.27Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 69
  • 70. Fundamentos de programaciónPrograma Desarrollado Observa que se imprime el texto tal cual pero en vez de imprimir el especificador de conversión %d se imprime el valor de la primera variable que es radio y en el lugar del especificador %f se imprime el valor del siguiente argumento que es la variable area. Ahora, si tenemos la instrucción: printf(“El perimetro es %.2f n”, PI*2*radio); La salida sería: El perimetro es 18.85 En este caso en el lugar del convertidor %.2f se imprime el resultado de evaluar la expresión PI*2*radio que es el segundo argumento, el número .2 que aparece en el convertidor indica que sólo deben imprimirse dos decimales. En lenguaje C la lectura de datos por medio del teclado se realiza con la función scanf, en la cual se deben de especificar de ante mano los tipos de datos que se desea recibir, además de los identificadores de las variables donde se desean almacenar. La sintaxis de esta función es: scanf(<cadena_de_control>,<lista_de_direcciones_de_variables>); Donde <cadena_de_control> es una cadena con los códigos que controlarán la forma como se recibirán los datos desde teclado y la <lista_de_direcciones_de_variables> es una lista con las localidades de memoria de las variables donde se almacenarán los datos que el usuario del programa introduzca a través del teclado. Dos observaciones importantes: en la especificación de la cadena de control se utilizan los mismos especificadores de conversión que para la función printf encerrados entre comillas y en la lista de direcciones los identificadores de las variables, anteponiéndoles a cada uno un símbolo de amperson “&”, en el mismo orden que los especificadores de tipos que les corresponden. Ejemplo 3.6: Suponiendo que se desea leer la base y la altura de un rectángulo y guardarlas en las variables de tipo int llamadas basen y altura, de tal manera que el usuario ingrese los valores separados por una coma, digamos “5,2” entonces la instrucción sería: scanf(“%d,%d”, &base, &altura);Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 70
  • 71. Fundamentos de programaciónPrograma Desarrollado Nota: Es frecuente que las personas olviden escribir el & antes del identificador de una variable, al utilizar la función scanf, cuestión que no es supervisada por el compilador y genera un error en el momento que se ejecuta el programa. Actividad 2. Funciones de entrada y salida Esta actividad consiste en diseñar un programa en C para resolver un problema dado, para conocer el problema y los detalles de la actividad, ingresa al aula virtual. 3.6. Codificación de algoritmos Para cerrar esta unidad desarrollemos un programa en C que resuelva el siguiente problema: Descripción del problema: Se requiere un programa que se encargue de la venta de boletos en un cine. El sistema debe calcular el monto que se debe pagar por una cantidad determinada de boletos tomando en cuenta que el costo de cada boleto es de 45 pesos. También se encargará de cobrar, es decir, dado el pago debe calcular el cambio indicando el tipo y número de billetes o monedas que devolverá de cada denominación. Para evitarse problemas de cambio, los ejecutivos de CineESAD han decidido no aceptar monedas de denominación menor a 1 peso y tampoco billetes de denominación mayor a 500 pesos. También se debe suponer que siempre hay suficientes billetes y monedas de cualquier denominación para devolver el cambio. Análisis: Los datos de entrada son el número de boletos (nboletos) y el monto del pago (pago), la salida del programa es el monto que se debe pagar por los boletos (total) y el monto del cambio (cambio), indicando el tipo y número de cada uno de los billetes o monedas que se devolverán. Notemos que el precio de los boletos siempre es el mismo, así que se puede declarar como una constante, llamémosla PRECIO. Así que para calcular el monto que el cliente debe pagar tenemos la siguiente fórmula: total = nboletos * PRECIO Y el monto del cambio se calcula con la siguiente fórmula: cambio = pago – total Para calcular cuántos billetes o monedas se tienen que devolver, se utilizarán los operadores de módulo y división. Por ejemplo, si el cambio es 360 se puede calcular el número de billetes de 100 dividiendo 360 entre 100, lo cual resulta ser 3 que corresponde al número de billetes, el resto del cambio es igual a 360 módulo 100, en este caso es 60.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 71
  • 72. Fundamentos de programaciónPrograma Desarrollado Por último, los billetes sólo pueden ser de $500, $200, $100, $50 y $20 y las monedas sólo son de $10, $5, $2 y $1. Por el momento supondremos que el usuario siempre ingresa datos correctos. Diseño del algoritmo: En la siguiente tabla se muestra el algoritmo que resuelve el problema. Constantes: PRECIO = 45 Variables: nboletos: entero, representa el número de boletos que quiere el cliente. total: entero, es la cantidad de dinero que el cliente debe pagar. pago: entero, monto del pago del cliente. cambio: entero, monto del cambio. Inicio Imprimir “ Proporciona el número de boletos” Leer nboletos total = nBoletos * PRECIO Imprimir “Proporciona tu pago” Leer pago cambio = pago – total Imprimir “Tu cambio es”, cambio Imprimir “El número de billetes de 200 pesos es”, cambio/200 cambio = cambio módulo 200 Imprimir “El número de billetes de 100 pesos es”, cambio/100 cambio = cambio módulo 100 Imprimir “El número de billetes de 50 pesos es”, cambio/50 cambio = cambio módulo 50 Imprimir “El número de monedas de 10 pesos es”, cambio/10 cambio = cambio módulo 10 Imprimir “El número de monedas de 5 pesos es”, cambio/5 cambio = cambio módulo 5 Imprimir “El número de monedas de 2 pesos es”, cambio/2 cambio = cambio módulo 2 Imprimir “El número de monedas de 1 peso es”, cambio Fin Algoritmo 3.1: ventaBoletos (pseudocódigo)Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 72
  • 73. Fundamentos de programaciónPrograma Desarrollado Nota: Observa que no es necesario utilizar variables para el número de billetes o monedas de las diferentes denominaciones, pues sólo se utiliza una vez el resultado del cálculo así que se puede imprimir directamente el resultado del mismo. Para verificar que el algoritmo funciona, en la siguiente tabla se realiza una prueba de escritorio considerando que los datos de entrada son 5 boletos y el monto del pago son 500 pesos. En la primera columna aparece la instrucción que se ejecuta, en la siguiente el dato que suponemos se ingresa, después están las operaciones que se realizan en la ALU, en la cuarta columna se muestra los valores de las variables después de que se ha realizado la instrucción y en la última columna se indica el mensaje que se imprimirá en la pantalla, cuando sea el caso. Por otro lado, incluimos en la tabla de estado de la memoria la constante PRECIO sombreando el espacio correspondiente para indicar que no puede ser modificado. Dato Estado de la memoria Dato de Instrucción de Operaciones (variables y constantes) salida entrada PRECIO nBoletos total pago cambio Inicio - - - 45 - - - - Imprimir Proporciona “Proporciona el PRECIO nBoletos total pago cambio - - el número número de 45 - - - - de boletos boletos”. Leer nBoletos PRECIO nBoletos total pago cambio 5 - - 45 5 - - - total = total = 5*45 PRECIO nBoletos total pago cambio nBoletos*PRECIO - - =225 45 5 225 - - Imprimir PRECIO nBoletos total pago cambio Proporciona “Proporciona tu - - 45 5 225 - - tu pago pago” Leer nBoletos PRECIO nBoletos total pago cambio 500 - - 45 5 225 500 - cambio = cambio = pago - PRECIO nBoletos total pago cambio - 500-225 = - total 45 5 225 500 275 275 Imprimir “Tu PRECIO nBoletos total pago Cambio Tu cambio cambio es”, - - 45 5 225 500 275 es 275 cambio. Imprimir “El El número PRECIO nBoletos total pago Cambio número de - 275/200 = 1 de billetes 45 5 225 500 275 billetes de $200 de $200 esEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 73
  • 74. Fundamentos de programaciónPrograma Desarrollado es”, cambio/200 1 cambio = cambio = cambio PRECIO nBoletos total pago Cambio - 275 mod 200 - módulo 200 45 5 225 500 75 =75 Imprimir “El El número número de PRECIO nBoletos total pago Cambio de billetes - 75/100 = 0 billetes de $100 45 5 225 500 75 de $100 es es”, cambio/100 0 cambio = cambio = cambio PRECIO nBoletos total pago Cambio - 275 mod 100 - módulo 100 45 5 225 500 75 =75 Imprimir “El El número número de PRECIO nBoletos total pago Cambio - 75/50= 1 de billetes billetes de $50 45 5 225 500 75 de $50 es 1 es”, cambio/50 cambio = 75 cambio = cambio PRECIO nBoletos total pago Cambio - mod 50 - módulo 50 45 5 225 500 25 =25 Imprimir “El El número número de PRECIO nBoletos total pago Cambio - 25/50= 0 de billetes billetes de $20 45 5 225 500 25 de $50 es 0 es”, cambio/20 cambio = cambio = cambio PRECIO nBoletos total pago Cambio - 25 mod 20 - módulo 20 45 5 225 500 5 =5 Imprimir “El El número número de PRECIO nBoletos total pago Cambio de - 5/10= 0 monedas de $10 45 5 225 500 25 monedas es”, cambio/10 de $10 es 0 cambio = 5 cambio = cambio PRECIO nBoletos total pago Cambio - mod 10 - módulo 10 45 5 225 500 5 =5 Imprimir “El El número número de PRECIO nBoletos total pago Cambio de - 5/5= 1 monedas de $5 45 5 225 500 5 monedas es”, cambio/5 de $5 es 1 cambio = 5 cambio = cambio PRECIO nBoletos total pago Cambio - mod 5 - módulo 5 45 5 225 500 0 =0 Imprimir “El El número número de PRECIO nBoletos total pago Cambio de - 0/2= 0 monedas de $2 45 5 225 500 0 monedas es”, cambio/2 de $2 es 0 cambio = 0 PRECIO nBoletos total pago Cambio cambio = cambio - mod 2 45 5 225 500 0 - módulo 2 =0Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 74
  • 75. Fundamentos de programaciónPrograma Desarrollado Imprimir “El El número número de PRECIO nBoletos total pago Cambio de - - monedas de $1 45 5 225 500 0 monedas es”, cambio de $1 es 0 PRECIO nBoletos total pago Cambio Fin - - - 45 5 225 500 0 Implementación: Por último, sólo queda codificar el algoritmo en lenguaje C. /* Descripción: Simulador de la caja de cobro de un cine.*/ /* Directivas al procesador */ #include<stdio.h>/* Funciones de entrada y salida */ #include<stdlib.h>/* Funciones del sistema */ /* Función Principal */ main( ) { /*Declaración de variables y constantes */ constint precio = 45; intnBoletos, total, pago, cambio; /*Mensaje de bienvenida*/ printf("********** Venta de boletos CineESAD************nn"); /*Datos de entrada*/ printf("Proporcione el numero de boletos que desea comprar:t"); scanf("%d",&nBoletos); /*Calculamos el total de la venta*/ total = nBoletos*precio; printf("El total es *** %d pesos *** nn",total); /*Leemos el pago y calculamos el cambio*/ printf("Indique el monto de su pago: "); scanf("%d",&pago); /*Calculamos el cambio y lo devolvemos*/ cambio = pago - total; printf("nn El monto de su cambio es %dn",cambio); printf("nt%d billetes de $200", cambio/200); cambio = cambio%200; printf("nt%d billetes de $100", cambio/100);Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 75
  • 76. Fundamentos de programaciónPrograma Desarrollado cambio = cambio%100; printf("nt%d billetes de $50", cambio/50); cambio = cambio%50; printf("nt%d billetes de $20", cambio/20); cambio = cambio%20; printf("nt%d monedas de $10", cambio/10); cambio = cambio%10; printf("nt%d monedas de $5", cambio/5); cambio = cambio%5; printf("nt%d monedas de $2", cambio/2); cambio = cambio%2; printf("nt%d monedas de $1", cambio); printf("nnCineESAD le agradece su preferenciann"); system("pause");/*hará una pausa antes de terminar la ejecución*/ }/*fin main*/ Programa 3.3: ventaBoletos.c El resultado de la ejecución del programa utilizando los mismos datos de entrada de la prueba de escritorio es: Figura 3.3: Ejecución del programa ventaBoletos.c Actividad 1. Introducción al lenguaje C –Ejercicio C Escribe, compila y ejecuta el programa ventaBoletos.c que acabamos estudiar e ingresa al foro para exponer tus comentarios al respecto. Consulta el aula para más detalles.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 76
  • 77. Fundamentos de programaciónPrograma Desarrollado Actividad 3. Análisis, algoritmo y codificación de un programa en C Realiza el análisis, diseño e implementación de un programa que resuelva el problema que tu Facilitador(a) proporcionará. Utiliza lo aprendido hasta el momento para hacer el algoritmo. Consideraciones específicas de la unidad Para continuar ejercitándote en el desarrollo de las habilidades en programación se te recomienda realizar más ejercicios, puedes consultar los libros (Joyanes & Zohanero, 2005) y (López, 2005). Referencias: • Böhm, C., & Jacopini, G. (1966). Flow diagrams, Turing machines, and languages only with two formation rules". Communications of the ACM, 9 (5), 366-371. • Cairó, O. (2005). Metodología de la programación: Algoritmos, diagramas de flujo y programas. México, D.F.: Alfaomega. • Guerrero, F. (s.f.). mailxmail.com. Recuperado el 15 de 8 de 2010, de http://www.mailxmail.com/curso-introduccion-lenguaje-c • Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. aspaño: Mc Graw Hill. • Kernighan, B., & Ritchie, D. (1991). El lenguaje de programción C. México: Prentice-Hall Hispanoamericana. • López, L. (2005). Programación estructurada en lenguaje C. México: Alfaomega. • Reyes, A., & Cruz, D. (2009). Notas de clase: Introducción a la programación. México, D.F.: UACM. • Villela, H. T. (20 de agosto de 2010). Manual de C. Obtenido de http://www.fismat.umich.mx/mn1/manual/.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 77
  • 78. Fundamentos de programaciónPrograma Desarrollado Unidad 4: Estructuras de control Propósitos En esta unidad: • Construirás expresiones booleanas para modelar situaciones reales. • Diseñarás algoritmos para resolver problemas que impliquen la toma de decisiones, utilizando estructuras selectivas. • Diseñarás algoritmos para resolver problemas que realicen una misma tarea varias veces usando estructuras repetitivas. • Codificarás en lenguaje C algoritmos estructurados. Competencia específica Utilizar estructuras de control selectivas y repetitivas para resolver problemas simples a través del desarrollo de programas en lenguaje C. Introducción En la segunda unidad, mediante el mundo de la ardilla, aprendiste que cualquier algoritmo puede ser escrito utilizando únicamente tres tipos de instrucciones, conocidas como estructuras de control: secuenciales (cuando se ejecutan una tras otra), selectivas (cuando se ejecutan dependiendo de una condición) y repetitivas (que se ejecutan varias veces en función de una condición); su objetivo es controlar el flujo de ejecución de un programa, es decir, el orden en que se ejecutan las instrucciones. Considerando que en la unidad anterior diseñaste algoritmos secuenciales y los codificaste en lenguaje C, para obtener el programa deseado que diera solución al problema en cuestión, podemos decir que solamente te falta saber cómo funcionan y cómo se codifican en lenguaje C las otras dos estructuras para poder diseñar algoritmos estructurados. Así que esto es justamente el tema de esta unidad, aquí estudiarás con más detalle los tipos y funcionamiento de las estructuras selectivas y repetitivas, introducidas en la unidad 2. Para su mejor comprensión, esta unidad está dividida en dos partes: en la primera revisarás algunos problemas donde la solución implica tener que elegir el camino que se debe seguir para llegar al resultado deseado, los cuales se solucionan utilizando estructuras selectivas, por lo cual se analizarás a mayor profundidad el significado (semántica) de cada estructura y verás la forma de codificarla (sintaxis) en lenguaje C. La segunda parte está dedicada a las estructuras repetitivas, para las cuales se sigue la misma estrategia, verás cómo se pueden solucionar problemas utilizando este tipo de estructuras y también analizarás su semántica y aprenderás su sintaxis en lenguaje C. De esta manera, al finalizar la unidad podrás construir programas que incluyan cualquier tipo de estructura de control.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 78
  • 79. Fundamentos de programaciónPrograma Desarrollado 4.1. Estructuras selectivas Para diseñar programas capaces de tomar decisiones se requiere de las estructuras de control selectivas, también llamadas condicionales. Éstas llevan a cabo su función (controlar el flujo del programa) mediante una condición que se representa utilizando expresiones booleanas, de tal manera que cuando la condición se cumple (es verdadera) se ejecuta un conjunto de instrucciones definidas para este caso y, dependiendo del tipo de estructura, es posible que se ejecute otro conjunto de instrucciones distinto para el caso contrario (cuando la condición es falsa); e incluso, es posible definir diferentes conjuntos de instrucciones para valores distintos que pudiera tomar una variable. Es así que dependiendo de su estructura se han definido tres tipos: simples, dobles y múltiples. Para el estudio de cada estructura selectiva, a continuación, se dedican tres sub-secciones, una para cada una, en las cuales entenderás cómo funcionan y la forman en que se codifican en lenguaje C. 4.1.1. Estructura selectiva simple (if) La estructura de decisión simple, como su nombre lo indica, permite decidir entre ejecutar o no un bloque de acciones; en pseudocódigo se propuso la palabra reservada Si para su representación y en lenguaje C esta estructura se codifica mediante la sentencia de control if, tal como se muestra en la siguiente tabla. Pseudocódigo Diagrama de Flujo Código en C if(<condición>) Si <condición> entonces <instrucciones> <instrucciones> Fin Si Tabla 4.1: Representaciones de la estructura condicional simple La <condición> puede ser cualquier expresión booleana y las <instrucciones>, llamadas cuerpo del Si (if), bien puede ser una sola instrucción o un bloque de instrucciones en cuyo caso van entre llaves {}. La manera en la que se ejecuta una instrucción Si (if) es la siguiente: se evalúa la condición que aparece entre paréntesis y si es verdadera (tiene un valor diferente de cero) entonces se ejecutan las instrucciones del cuerpo del Si (if), en caso de no serlo no se ejecuta y continúa el flujo de ejecución.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 79
  • 80. Fundamentos de programaciónPrograma Desarrollado NOTA: En lenguaje C, cuando el cuerpo de una estructura tiene más de una instrucción éstas deben ir encerradas entre llaves. Para ilustrar las representaciones y el funcionamiento de la estructura selectiva simple se presenta el siguiente problema, con el algoritmo en pseudocódigo, el diagrama de flujo y el programa en lenguaje C. Problema 4.1: Se requiere un programa que lea un valor entre 0 y 360 y determine el tipo de ángulo, considerando que: • Angulo agudo: Mayor a cero y menor de 90 grados • Angulo reto: Es igual a 90 grados • Angulo obtuso: Es mayor que 90 pero menor a 180 grados • Angulo llano: Es igual a 180 grados • Angulo cóncavo: Es mayor a 180 pero menor a 360 grados El análisis del problema se resume en la siguiente tabla. Análisis del problema Salida: Método: Mensaje 1: “Agudo” Realizar comparaciones Datos de entada: Mensaje 2: “Recto” utilizando la estructura de ángulo Mensaje 3: “Obtuso” selección simple para Mensaje 4: “Llano” determinar el tipo de ángulo, Mensaje 5: “Cóncavo” se requiere una por cada tipo Tabla 4.2: Análisis del problema 4.1 Lo primero que se requiere es leer el valor del ángulo, posteriormente, verificar de qué tipo es para imprimir el mensaje indicado. A continuación se muestra el algoritmo, tanto en pseudocódigo como en diagrama de flujo: Inicio Imprimir "Ingrese la medida del angulo (grados): " Leer angulo Si angulo≤0 OR angulo≤360 entonces Imprimir “No tiene clasificación" Fin_SiEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 80
  • 81. Fundamentos de programaciónPrograma Desarrollado Si angulo>0 AND angulo<90 entonces Imprimir "El ángulo es agudo" Fin_Si Si angulo=90 entonces Imprimir "El ángulo es recto" Fin_Si Si angulo>90 AND angulo<180 entonces Imprimir “El ángulo es obtuso" Fin_Si Si angulo =180 entonces Imprimir "El ángulo es llano" Fin_Si Si angulo>180 AND angulo<360 entonces Imprimir “El ángulo es concavo" Fin_Si Fin Algoritmo 4.1.a: Tipo de ángulo - pseudocódigo Observa que, para hacer más legible el algoritmo en pseudocódigo, se han dejado sangrías para indicar qué instrucciones forman el cuerpo de cada una de las estructuras Si y se han encerrado con un rectángulo, esto se adoptará para cualquier bloque de instrucciones que corresponda al cuerpo de una estructura.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 81
  • 82. Fundamentos de programaciónPrograma Desarrollado Algoritmo 4.1.b: Tipo de ángulo – diagrama de flujo Para reafirmar el funcionamiento de la estructura condicional simple y verificar que el algoritmo propuesto sea correcto, en la siguiente tabla se muestra su ejecución paso a paso, tomando comodatos de entrada 120 grados.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 82
  • 83. Fundamentos de programaciónPrograma Desarrollado Tabla 4.3: Prueba de escritorio del algoritmo 4.1 Al ejecutar paso a paso el algoritmo la única condición que satisface el estado de la memoria es la que sombreamos (angulo>90 AND angulo<180), por lo tanto, la única instrucción que se toma en cuenta es la del cuerpo del Si correspondiente. El último paso es la codificación. Observa que el cuerpo de cada una de las estructuras consta de una instrucción por lo tanto no es necesario encerrarla entre llaves {}. /* Programa: tipoAngulo.c Descripción: Determina el tipo de angulo (agudo, recto, obtuso, llanoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 83
  • 84. Fundamentos de programaciónPrograma Desarrollado o cóncavo) */ #include<stdio.h> #include<stdlib.h> /* Función Principal*/ main () { /*Inicio de la función Principal*/ /*Declaración de variables */ intangulo; /*Mensaje de bienvenida*/ printf ("nEste programa determina de que tipo es el angulo dado."); /*Instrucciones */ printf ("nnIngrese la medida del angulo (grados): "); scanf ("%d",&angulo); if (angulo<=0 || angulo>=360) printf ("n No tiene clasificación"); if (angulo>0 &&angulo<90) printf ("n El angulo es agudo"); if (angulo==90) printf ("n El angulo es recto"); if (angulo>90 &&angulo<180) printf ("nElangulo es obtuso"); if (angulo ==180) printf ("n El angulo es llano"); if (angulo>180 &&angulo<360) printf ("nElangulo es concavo"); printf ("nnt"); system ("pause"); } /*Fin de la función Principal*/ Programa 4.1: tipoAngulo.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 84
  • 85. Fundamentos de programaciónPrograma Desarrollado A continuación se muestra la pantalla correspondiente a la ejecución del programa anterior introduciendo el mismo ángulo que se utilizó en la prueba de escritorio. Figura 4.1: Ejecución del programa tipoAngulo.c Actividad 1. Estructuras de control –Ejercicio A Al igual que en la Unidad anterior, en esta ocasión, contarás con un foro para publicar y comentar tus actividades, las cuales te servirán de práctica para mejorar en el desarrollo de programas en C. Recuerda que estas actividades no necesitas enviarlas al (a la) facilitador(a), pero sí debes subirlas al Foro y comentar los aportes de tus compañeros(as). Para iniciar el trabajo en el foro realiza una prueba de escritorio del algoritmo que resuelve el problema 4.1 presentado en esta sección (algoritmo 4.1.a y algoritmo 4.1.b) considerando que el valor del ángulo es 98 grados. Posteriormente escribe, compila y ejecuta el programa tipoAngulo.c (programa 4.1) en la computadora con el mismo valor del ángulo. Finalmente, ingresa un comentario respecto a los resultados obtenidos. 4.1.2. Estructura selectiva doble (if-else) Las estructuras selectivas dobles nos permiten elegir alguna de dos posibles acciones a realizar dependiendo de la condición. En pseudocódigo se propone usar las palabras reservadas Si-Sino y en C se codifican mediante la sentencia if-else, tal como se muestra en la siguiente tabla. Pseudocódigo Diagrama de Flujo Lenguaje C Si (<condición>) if(<condición>) entonces <instruccionesV> <instruccionesV> else sino <instruccionesF> <instruccionesF> Fin Si-Sino Tabla 4.4: Representaciones de la estructura condicional dobleEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 85
  • 86. Fundamentos de programaciónPrograma Desarrollado Al igual que en la estructura selectiva simple, la <condición> representa una expresión booleana y, las <instruccionesV> y <instruccionesF> puede ser una o varias, a las primeras se les llama cuerpo del Si (if) y las segundas son el cuerpo del Sino (else). Esta estructura de control ejecuta sólo uno de los dos cuerpos de instrucciones: cuando la condición es verdadera se ejecutan las <instrucciuonesV> y en caso contrario se ejecutan las <instruccionesF>. En el desarrollo del siguiente problema se ejemplifican las representaciones y el funcionamiento de ésta estructura. Problema 4.2: Se requiere un programa que simule el cálculo y muestre las raíces reales para una ecuación de segundo grado de la forma: 2 + + = 0. Para resolver este problema se utilizará la fórmula general: − ± √ 2 − 4 = 2 Por lo que los datos que requerimos son los coeficientes de la ecuación (a, b y c) y el resultado deseado serán las raíces. También se debe considerar que un polinomio tenga raíces reales se debe cumplir la condición: 2 ≥ 4 De lo contrario el resultado de la raíz cuadrada sería un número imaginario. Para esto se propone una estructura selectiva doble para verificar que existan raíces reales. El algoritmo en pseudocódigo es el siguiente: Inicio Imprimir “Ingresa los coeficientes a, b y c:” det← 2 − 4 Leer a, b, c Si (det ≥ 0 ) entonces x1← x2 ← Imprimir “Las raíces son: ”, x1 , x2Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 86
  • 87. Fundamentos de programaciónPrograma Desarrollado Si no Imprimir “No existen raíces reales” Fin_Si-Sino Fin Algoritmo 4.2.a: Ecuación de segundo grado - pseudocódigo determinante ( 2 − 4) se emplea en más de un lugar del algoritmo, por lo tanto, se recomienda Observa que en el algoritmo se utiliza la variable auxiliar det, la razón es porque el cálculo del guardar este resultado para no volverlo a calcular. Ahora, la representación del mismo algoritmo en diagrama de flujo se muestra a continuación. Algoritmo 4.2.b: Ecuación de segundo grado – diagrama de flujo Para validar el algoritmo, veamos su ejecución paso a paso con el polinomio 2 + 5 + 4 = 0.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 87
  • 88. Fundamentos de programaciónPrograma Desarrollado Tabla 4.5: Prueba de escritorio del algoritmo 4.2 Para la codificación en lenguaje C se debe notar que el cuerpo del Si (if) tiene un bloque de tres instrucciones, por lo que deberán ir encerradas entre llaves {}, en cambio el cuerpo del Sino (else) sólo tiene una instrucción por lo que no son necesarias. /* Programa: ecuacion.c Descripción: Solución de ecuaciones de segundo grado utilizando */ /* Bibliotecas */ #include<stdio.h>/* Biblioteca de entrada y salida estándar */ #include<stdlib.h>/* Biblioteca para las funciones del sistema */ #include<math.h>/* Biblioteca para utilizar funciones matemáticas: pow para calcular la potencia sqrt para calcular la raíz cuadrada*/ /* Función Principal*/ main ( ) { /*Declaración de variables */ double a, b, c, x1, x2, det; /* Mensaje de bienvenida */ printf("El siguiente programa calcula las raices de un polinomio de segundo gradon"); printf("ntt ax^2 + bx + c = 0");Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 88
  • 89. Fundamentos de programaciónPrograma Desarrollado /* Datos de entrada */ printf ("nIntroduzca los coeficientes de a,b y c:"); scanf ("%lf,%lf,%lf",&a,&b,&c); det = pow (b,2)-4*a*c; /* Verificamos que la ecuación tenga raices reales */ if (det>= 0) { x1=(-b + sqrt(det))/2*a; x2=(-b - sqrt(det))/2*a; printf ("n La raices son: %.2lf, %.2lf",x1, x2); } else printf ("nNo existen raices reales."); printf ("n"); system ("pause"); } Programa 4.2: ecuacion.c La ejecución del programa con los mismos datos de entrada de la prueba de escritorio es la siguiente. Figura 4.2: Ejecución del programa ecuacion.c Actividad 1. Estructuras de control –Ejercicio B 2 2 + 5 + 3 = 0. Enseguida escribe y compila el programa ecuacion.c (programa 4.2) en la Realiza una prueba de escritorio del algoritmo que resuelve el problema 4.2 considerando la ecuación computadora y ejecútalo con la misma ecuación para verificar los resultados. Ingresa un comentario respecto a los resultados obtenidos en el Foro Estructuras de control y discute si es posible resolver este problema utilizando estructuras selectivas simples.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 89
  • 90. Fundamentos de programaciónPrograma Desarrollado 4.1.3. Estructura selectiva múltiple (switch-case) Las estructuras selectivas múltiples permiten escoger uno de varios caminos posibles. Para la estructura condicional múltiple se proponen las palabras clave Seleccionar-caso en pseudocódigo, misma que se implementa en lenguaje C utilizando las palabras reservadas switch-case. Esta secuencia se utiliza cuando existen múltiples posibilidades para la evaluación de una expresión matemática (generalmente una variable), pues de acuerdo al valor que tome la expresión será el conjunto de instrucciones que se ejecute. Pseudocódigo Lenguaje switch (<expresión>) Casos para<expresión> { caso<valor1>: case<valor1>: <instruccionesCaso1> <instrucciones1>; caso<valor2>: break; <instruccionesCaso2> case<valor2>: … <instrucciones2>; otros casos: break; <instruccionesOtros> default: Fin_Casos <instruccionesOtras> } Diagrama de Flujo Tabla 4.6: Representaciones de la estructura condicional múltiple En este caso la <expresión> no es booleana sino aritmética y de tipo entero, así cada caso corresponde a un valor que puede resultar de su evaluación. De esta forma, el flujo de control que sigue la ejecución de una instrucción Seleccionar-casos (switch-case) es el siguiente: se evalúa la <expresión> y si el valor corresponde al valor de un caso, es decir a un <valori>, se ejecuta el bloque de <instruccionesi> hasta encontrar el final de la instrucción, que en el caso de C está representado por la palabra reservada break, terminando ahí la ejecución de la instrucción. Cuando el valor no corresponde a ningún caso se ejecuta el bloque de instrucciones correspondiente a otros casos (default). ElEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 90
  • 91. Fundamentos de programaciónPrograma Desarrollado conjunto de todos los casos, incluyendo el default, conforman el cuerpo de la estructura Seleccionar- casos (switch-case). Problema 4.3: Se requiere un programa que dada una calificación con número despliegue un mensaje, de acuerdo con la siguiente información: 0-6: Reprobado 7: Suficiente, Aprobado 8: Bien, Aprobado 9: Notable, Aprobado 10: Sobresaliente, Aprobado En este caso es conveniente utilizar una estructura selectiva múltiple, en donde la expresión que se evalúe sea la calificación del estudiante y se defina un caso por cada una de las calificaciones posibles. Es claro, que la entrada únicamente es la calificación y la salida es el mensaje correspondiente. De lo anterior el algoritmo en pseudocódigo y diagrama de flujo quedaría de la siguiente forma. Inicio Imprimir “ Inserte una calificación: " Leer nota Seleccionar (nota) caso 0: caso 1: caso2: caso 3: caso 4: caso 5: caso 6: Imprimir “Reprobado" caso 7: Imprimir "Suficiente, Aprobado" caso 8: Imprimir "Bien, Aprobado" caso 9: Imprimir “Notable, Aprobado” caso 10: Imprimir “Sobresaliente, Aprobado” otros casos: Imprimir "Esa nota es incorrecta" Fin_Casos Fin Algoritmo 4.3.a: Conversión de calificación numérica a letra - pseudocódigoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 91
  • 92. Fundamentos de programaciónPrograma Desarrollado Algoritmo 4.3.b: Conversión de calificación numérica a letra – diagrama de flujo Observa que tanto en el diagrama de flujo como en el algoritmo, hay siete casos (0 ≤ ≤ 6) en los que la instrucción a ejecutar es la misma, por lo que se agrupan, más no se puede poner una condición que los contenga, como se haría en las estructuras vistas en las subsecciones anteriores, así que en el pseudocódigo se especifica cada valor antecedido por la palabra caso pero sólo se escribe una vez la instrucción y, de manera similar, se listan todos los valores. Para aclarar el funcionamiento de esta estructura y verificar si el algoritmo funciona adecuadamente, en la siguiente tabla se muestra una prueba de escritorio cuando la nota es igual a 8.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 92
  • 93. Fundamentos de programaciónPrograma Desarrollado Tabla 4.7: Prueba de escritorio del algoritmo 4.3 Es importante señalar que, a diferencia de las estructuras anteriores, el cuerpo de una estructura selectiva múltiple siempre debe ir encerrado entre llaves {} cuando se codifica en C, más no así las instrucciones que se definen para cada caso, ya que estás se acotan por las palabra reservadas case y break, por tal motivo no debes olvidar escribir el break al final de cada caso de lo contrario también se ejecutarán las instrucciones de los casos que aparezcan después. /* Programa: calificacion.c * Descripción: Dada una calificación con número despliega un mensaje * 0,1,2,3,4,5,6 - Reprobado * 7 - Suficiente, Aprobado * 8 - Bien, Aprobado * 9 - Notable, Aprobado * 10 - Sobresaliente, Aprobado*/ #include<stdio.h> #include<stdlib.h> /*Función principal*/ main() { /*Declaración de variables*/ int nota;Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 93
  • 94. Fundamentos de programaciónPrograma Desarrollado /*Mensaje de bienvenida */ printf("nEl siguiente programa lee una calificacion con número, ndetermina que tipo de calificacion esn"); /*Datos de entrada*/ printf("nInserte una calificacion numérica: "); scanf("%d",&nota); /*Comparación*/ switch(nota) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: printf("nnt"Reprobado""); break; case 7: printf("nnt"Suficiente, Aprobado""); break; case 8: printf("nnt"Bien, Aprobado""); break; case 9: printf("nnt"Notable, Aprobado""); break; case 10: printf("nnt"Sobresaliente, Aprobado""); break; default: printf("nnt"Esa nota es incorrecta""); } printf ("nntt"); system ("pause"); } Programa 4.3: calificacion.c En la siguiente figura se muestra la ejecución de este programa con el valor de entrada igual a 8. Figura 4.3: Ejecución del programa calificacion.c A lo largo de esta sección has estudiado los tres tipos de estructuras selectivas y por medio de los ejemplos presentados te has dado cuenta de la importancia y utilidad de estas estructuras, sin ellasEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 94
  • 95. Fundamentos de programaciónPrograma Desarrollado sería imposible construir programas que implicaran la toma de decisiones. Sin embargo, todavía existen problemas que requieren de otro tipo de estructuras que permitan repetir una tarea un número determinado de veces, la siguiente sección está dedicada a este tema. Actividad 1. Estructuras de control –Ejercicio C Realiza una prueba de escritorio del algoritmo que resuelve el problema 4.3 presentado en esta sección (algoritmo 4.3.a y algoritmo 4.3.b) considerando que el valor de entrada es igual a 10. Después escribe y compila el programa calificacion.c (programa 4.3) en la computadora y ejecútalo con el mismo valor para comparar el resultado. Finalmente, reflexiona si es posible resolver el problema planteado utilizando estructuras selectivas simples o dobles e ingresa tu comentario en el Foro Estructuras de control Actividad 2: Estructuras selectivas Realiza el análisis, diseño e implementación de un algoritmo que resuelva el problema que se te presenta mediante el uso de las estructuras selectivas, para conocer el problema y los detalles de la actividad, ingresa al aula virtual. 4.2. Estructuras repetitivas En la mayor parte del diseño o implementación de las soluciones que se plantea a problemas específicos nos encontramos con instrucciones que deben ejecutarse un número determinado de veces, si hacemos un análisis más profundo de estas situaciones, en la mayorías de las ocasiones nos encontramos que las instrucciones son las mismas, pero que los datos varían, esto se hace posible utilizando las estructuras repetitivas, generalmente llamadas ciclos. Existen varias estructuras de repetición implementadas por los diferentes lenguajes de programación, todas con la misma idea: repetir un conjunto de instrucciones, llamadas cuerpo del ciclo, dependiendo de condición. En la mayoría de los ciclos el cuerpo se repiten siempre y cuando la condición se cumpla, sin embargo, también existe una estructura repetitiva que se repite en tanto que no se cumple la condición. En esta sección sólo nos enfocaremos en las primeras que son las que están definidas en el lenguaje C y en la mayoría de los lenguajes estructurados y orientados a objetos actuales. Cabe mencionar que a cada una de las veces que se repite el ciclo se le conoce como iteración. Cuando se utilizan ciclos dentro de un programa, te puedes enfrentar a dos posibles situaciones:  Que conozcas desde el diseño cuántas veces deben repetirse las instrucciones (repetición definida),  Que el número de veces que se deban repetir las instrucciones dependa de un valor que se conoce hasta el momento de la ejecución del ciclo (repetición indefinida).Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 95
  • 96. Fundamentos de programaciónPrograma Desarrollado En el primer caso se necesitará una variable que funja como un contador, en la cual se registre el número de iteraciones que se vayan ejecutando. En cambio, en las repeticiones indefinidas generalmente se controlan mediante interruptores o banderas, o bien, con valores centinela. Con los anterior puedes darte cuenta que para las estructuras de control repetitivas es muy importante el uso de variables auxiliares y que por la frecuencia con la que se utilizan dentro de un algoritmo y por la función que realizan dentro del mismo toman un nombre especial: contadores, acumuladores e interruptores. Un contador es una variable comúnmente de tipo entero destinada a almacenar un valor que se irá incrementando o decrementando en una cantidad constante. Se suelen utilizar mucho en procesos repetitivos definidos, para contabilizar el número de veces que se repite un conjunto de acciones o eventos, es decir en los cuerpos de las instrucciones repetitivas. Sobre una variable contadora se realizan dos operaciones básicas: inicialización e incremento o decremento, según sea el caso. Todo contador se debe inicializar con un valor inicial (0, 1...) contador = Valor_Inicial Cada vez que aparezca el evento a contar se ha de incrementar o decrementar en una cantidad fija (I, D respectivamente) el valor del contador. contador = contador+ I; contador = contador- D; Los contadores más utilizados tienen incrementos o decrementos de uno en uno, es por ello que la simplificación de dichas expresiones es: Expresión Expresión Simplificada en lenguaje C contador=contador +1; contador++ contador=contador -1; contador-- En contraste, un interruptor o bandera es una variable que puede tomar dos posibles valores a lo largo de la ejecución del programa, éstos son: 1 (encendido/abierto) y 0 (apagado/cerrado), de ahí su nombre. Y se utilizan principalmente para registrar la ocurrencia o no de un suceso. Por último, un acumulador es una variable cuyo objetivo es acumular cantidades sucesivas obtenidas al realizar la misma operación. El uso más habitual de un acumulador es obtener sumas y productos. Al igual que con los contadores, para poder utilizar un acumulador hay que realizar sobre ellos dos operaciones básicas: inicialización e incremento.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 96
  • 97. Fundamentos de programaciónPrograma Desarrollado En el caso de obtener sumas el acumulador se inicializa en cero y en el caso de los productos en uno, para no afectar el resultado. SumaTotal=0; ProductoFinal=1; Una vez obtenido y almacenado en una variable la cantidad a acumular la añadimos a la variable acumulador: Variable Acumulador Cantidad a Acumular SumaTotal = SumaTotal + cantidad; ProductoFinal = ProductoFinal * cantidad; En resumen, los contadores permiten llevar la cuenta del número de iteraciones que se realizan en un ciclo (definido o indefinido), y en el caso específico de ciclos definidos son el medio por el cual se controla el fin del ciclo. Por otro lado los acumuladores nos permiten guardar resultados parciales de operaciones que se realizan como parte del cuerpo de un ciclo (puede ser definido o indefinido). En este punto, es importante señalar que en lenguaje C hay tres diferentes estructuras repetitivas: while (Mientras-hacer), for (Desde-mientras) y do-while (Hacer-mientras), con todas ellas es posible modelar ciclos definidos o indefinidos, pues las tres son equivalente, es decir, cualquiera de ellas se puede expresar en términos de las otras. En los siguientes subtemas estudiarás a profundidad cada una de ellas y verás su equivalencia. 4.2.1. Estructura Mientras (while) La estructura repetitiva Mientras, codificada en lenguaje C con la palabra reservada while, controla las repeticiones a partir de una condición que se evalúa al inicio del ciclo, de esta manera en cada iteración primero se evaluará la condición y mientras resulte verdadera se repetirá el ciclo. En la siguiente tabla se muestran las representaciones del ciclo Mientras (while).Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 97
  • 98. Fundamentos de programaciónPrograma Desarrollado Pseudocódigo Diagrama de Flujo Lenguaje C Mientras <condición>hacer while (<condición>) F Condición <instrucciones> <instrucciones>; V Fin mientras instrucciones Tabla 4.8: Representaciones de la estructura repetitiva Mientras (while) La manera en la que se ejecuta una instrucción Mientras (while) es la siguiente: las <instrucciones> del cuerpo del ciclo se ejecutan mientras la <condición> es verdadera, cuando esto no se cumple se termina el ciclo; de esta forma, si la primera vez que se evalúa la condición esta es falsa, el cuerpo del ciclo no se ejecuta ni una sola vez. Para ejemplificar cómo se construye un ciclo indefinido utilizando un valor centinela, se propone el siguiente problema. Problema 4.4: Se requiere un programa que calcule el promedio de temperaturas que registra una ciudad, las temperaturas se introducirán en grados Farenheit °F y no se conoce de antemano el número de temperaturas que el usuario introducirá. Para resolver el problema planteado se podría pedir el número de temperaturas que se desean registrar para calcular el promedio, pero esto equivale a una estructura de repetición definida, si decidiéramos dejar abierto este dato hasta el momento de la ejecución del programa, tendríamos que construir una condición que haga que el ciclo se repita mientras que el usuario desea ingresar temperaturas. Pero ¿cómo se puede resolver esto? En casos como este se propone utilizar un valor centinela que indique el fin de la captura de datos. Claramente el valor centinela debe ser seleccionado de tal forma que no se confunda con algún valor de entrada aceptable, por ejemplo podríamos considerar que dado que existe un límite mínimo de temperaturas en grados Farenheit, a saber -460°F, el valor centinela sería cualquier número inferior a éste, es claro que no existe una temperatura más baja, sin embargo el límite máximo es difícil de definir ya que en forma experimental se obtienen en los laboratorios temperaturas de miles de grados, mientras que en una explosión atómica se alcanzan temperaturas de millones de grados. Se supone que la temperatura en el Sol alcanza los mil millones de grados (Pérez, 1992, pág. 325).Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 98
  • 99. Fundamentos de programaciónPrograma Desarrollado Para calcular el promedio, debemos realizar la suma de todas las temperaturas (1 + 2 + … , + ) y dividirlas entre el número total de temperaturas que se hayan leído, digamos . Lo ∑ ← anterior se expresa con la siguiente fórmula. en la variable ) y acumulando la suma en la variable , estas acciones se repetirán hasta Así que en este caso se usará un ciclo que vaya leyendo una a una las temperaturas (almacenándolas ≥ −460; por lo que antes de iniciar el ciclo se debe pedir la primera temperatura, para que se que el usuario introduzca un número menor a -460. De esta manera, la condición de término es: compare con la condición y si es mayor a -460 se acumule en la suma. Además, se utilizará un contador para registrar el número de temperaturas que se lean. Finalmente, cuando se termina el ciclo se divide el resultado de la suma de las temperaturas entre el valor del contador. Lo anterior se expresa en el siguiente pseudocódigo. Inicio c←0, sumaF←0 Imprimir "Ingrese la primer temperatura registrada en grados Fahrenheit:" Leer tempF Mientras (tempF≥-460) c←c+1 sumaF=sumaF+tempF Imprimir "Ingrese la siguiente temperatura en grados Fahrenheit (un número mayor a -460) para calcular el promedio " Leer tempF Fin Mientras promF←sumaF/c Imprimir “El promedio de las temperaturas es” promF Fin Algoritmo 4.4.a: Promedio temperaturas - pseudocódigoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 99
  • 100. Fundamentos de programaciónPrograma Desarrollado La representación del algoritmo en diagrama de flujo que se muestra en la siguiente figura: Algoritmo 4.4.b: Promedio temperaturas – diagramas de flujo En la siguiente tabla se muestra una prueba de escritorio para las temperaturas 75, 78, 79 y para concluir el ciclo -2000.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 100
  • 101. Fundamentos de programaciónPrograma DesarrolladoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 101
  • 102. Fundamentos de programaciónPrograma Desarrollado Tabla 4.9: Prueba de escritorio del algoritmo 4.4 En la tabla 4.9 se puede observar como el mismo conjunto de instrucciones se repite tres veces (3 iteraciones), en cada una se valida la condición y el ciclo termina sólo cuando ésta no se satisface por el estado de las variables implicadas en la expresión booleana. Una vez que se ha ilustrado el funcionamiento del ciclo Mientras y verificado que si funciona, el siguiente paso es la codificación, para la cual se determinó utilizar una variable para representar el valor centinela que controla el ciclo. /* Programa: promTemp.c Descripción: Calcula el promedio de las temperaturas que el usuario ingresa. */ #include<stdio.h> #include<stdlib.h> #define centinela -460 /* Función principal */ main () { /*Declaración de acumuladores y contadores*/ float tempF,promF, sumaF=0; int c=0; /* Lectura de la primera temperatura */ printf ("Programa que calcula el promedio de temperaturas en grados Fahrenheitnnn"); printf ("n Ingrese la primer temperatura registrada:");Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 102
  • 103. Fundamentos de programaciónPrograma Desarrollado scanf ("%f",&tempF); /* Codificación del ciclo */ while (tempF>= centinela) { /* Se registra la temperatura que se leyó */ c = c + 1; /* Se acumulala temperatura en la suma */ sumaF=sumaF+tempF; /* Se lee la siguiente temperatura */ printf ("nnIngrese la siguiente temperatura (si desea terminar ingrese un número menor a %d): ", centinela); scanf ("%f",&tempF); } /* Promedio de Temperaturas Fahrenheit */ promF=sumaF/c; printf ("nPromedio de temperaturas Celsius=%.2fn", promF); system ("pause"); } Programa 4.4: promTemp.c Por último, en la siguiente figura se muestra la ejecución del programa con los mismos datos que se utilizaron en la prueba de escritorio. Figura 4.4: Ejecución del programa promTemp.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 103
  • 104. Fundamentos de programaciónPrograma Desarrollado Actividad 1. Estructuras de control –Ejercicio D Realiza una prueba de escritorio del algoritmo que resuelve el problema 4.4 presentado en esta sección (algoritmo 4.4.a y algoritmo 4.4.b) considerando que los valores de entrada son 80, 100, 250, -1000. Después escribe y compila el programa promTemp.c (programa 4.4) en la computadora y ejecútalo con los mismos valores para comparar el resultado. Posteriormente reflexiona si es posible resolver este problema utilizando únicamente estructuras selectivas e ingresa tus comentarios en el Foro Estructuras de control. 4.2.2. Estructura Desde-mientras (for) El ciclo Desde-mientras, en inglés y lenguaje C for, evaluará una condición y mientras ésta sea verdadera se ejecutará el conjunto de instrucciones definidas en el cuerpo de la estructura, generalmente las repeticiones se controlan por un contador, ya que como parte de su sintaxis tiene la opción de inicializar una variable (el contador) e incrementarlo o decrementarlo. Este tipo de estructura es conveniente utilizarla cuando se conoce de antemano el número de veces que se debe repetir el ciclo (ciclos definidos). Sus representaciones se muestran en la siguiente tabla. Pseudocódigo Diagrama de Flujo Desde <inicialización>Mientras<condición>, <incr/decr> <Instrucciones> Fin desde Lenguaje C for (<inicialización>;<condición>; <inc/dec>) <instrucciones> Tabla 4.8: Representaciones de la estructura repetitiva Desde-mientras (for)Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 104
  • 105. Fundamentos de programaciónPrograma Desarrollado En este caso, primero se realiza la <inicialización> que corresponde a la asignación de un valor inicial de una variable (el contador), posteriormente se evalúa la <condición> si es verdadera se ejecutan las <instrucciones> del cuerpo del ciclo y, posteriormente, se incrementa o decrementa el contador, según sea el caso, para después volver a repetir el ciclo, excepto por la <inicialización> que sólo se ejecuta una vez. Es importante señalar que si te centras en la representación en diagrama de flujo de este ciclo podrás darte cuenta que se parece al diagrama del ciclo while, salvo por la inicialización y el incremento (o decremento); de hecho si partes del diagrama de flujo para la codificación puedes utilizar un while. De igual manera, un ciclo while se puede representar con un ciclo for cuya <inicialización> e <incremento/decremento> son vacíos, sólo se define la condición. Con lo anterior se muestra la equivalencia de las dos estructuras. Para ejemplificar las representaciones, codificación y funcionamiento de esta estructura se presenta el siguiente problema desarrollado. Problema 4.5: Se requiere un programa que calcule el total de la nómina de los trabajadores de una empresa. El problema es similar al que se presentó en la sección anterior, se debe leer el pago de cada trabajador y realizar la suma de cada uno de éstos, para lo cual se puede utilizar un acumulador. La diferencia es que en este caso no se utilizará un valor centinela para terminar la lectura de los pagos, pues se preguntará al usuario al inicio del programa cuántos trabajadores hay, así el número de iteraciones quedará determinado antes de iniciar el ciclo. De lo anterior tenemos que si el número de empleados es n entonces el ciclo debe repetirse n-veces, para lo cual se utilizará un contador c que debe tomar los valores 1,2,…, n, así que el ciclo debe repetirse siempre que c ≤ n. En cuanto a la suma de los pagos, se utilizará un acumulador, al cual llamaremos nom, que se inicializará en cero dado que se trata de una suma. Observa la solución del problema.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 105
  • 106. Fundamentos de programaciónPrograma Desarrollado Inicio Imprimir "Ingrese el total de empleados: " Leer n Desde c=1 , nom=0, Mientras (c<=n), c=c+1 Imprimir “Ingresa el salario del trabajador”, c Leer sal nom=nom+sal Fin desde Imprimir “La nómina a pagar es en total $”, nom Fin Algoritmo 4.5.a: Nómina - pseudocódigo Algoritmo 4.5.b: Nómina – diagrama de flujo En la siguiente tabla se muestra la ejecución paso a paso del ciclo suponiendo que se quiere calcular la nómina de tres empleados y ya se ha leído el dato y registrado en la variable n, la cual no cambia su valor a lo largo de la ejecución del ciclo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 106
  • 107. Fundamentos de programaciónPrograma Desarrollado Tabla 4.9:Prueba de escritorio del algoritmo 4.4 Por lo tanto, la salida del algoritmo es: “La nómina a pagar es $45”. La codificación sería la siguiente. /* Programa: nomina.c Descripción: calcula la nómina a pagar de n trabajadores */ /*directivas de preprocesador*/ #include<stdio.h> #include<stdlib.h>Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 107
  • 108. Fundamentos de programaciónPrograma Desarrollado /*Función Principal*/ main () { /* Declaración de las variables */ int n,c; float nom,sal; /* Lectura del número de empleados */ printf ("Calculo de la Nominann "); printf ("Ingrese el total de empleados: "); scanf ("%d",&n); /*Ciclo definido de 1 hasta el número de empleados ingresados*/ for (nom=0,c=1;c<=n;c=c+1) { printf ("nIngresa el salario del trabajador %d: ", c); scanf ("%f",&sal); /*Acumulador de salários*/ nom=nom+sal; } printf(“n La nomina a pagar es $&.2f”, nom); } Programa 4.5: nomina.c En la siguiente figura se muestra la ejecución del programa con los mismos datos de entrada que se utilizaron en la prueba de escritorio. Figura 4.6: Ejecución del programa nomina.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 108
  • 109. Fundamentos de programaciónPrograma Desarrollado Actividad 1. Estructuras de control –Ejercicio E Realiza una prueba de escritorio del algoritmo que resuelve el problema 4.5 presentado en esta sección (algoritmo 4.5.a y algoritmo 4.5.b) para calcular la nómina de 4 trabajadores con salarios igual a: $2000.00, $5000.00, $3000.00 y $1000.00. Posteriormente, escribe y compila el programa nomina.c (programa 4.4) en la computadora y ejecútalo con los mismos valores para comparar el resultado. Analiza cómo podrías resolver este problema utilizando la estructura Mientras (while) e ingresa tus comentarios al respecto en el Foro Estructuras de control. 4.2.3 Estructura Hacer-mientras (do-while) A diferencia de las estructuras repetitivas anteriores, en las cuales las condiciones se evalúan al principio del ciclo, por lo que las instrucciones que se repiten se ejecuten de 0 hasta N veces, en la estructura Hacer-mientras (do-while) la evaluación se lleva acabo al final, esto implica que el conjunto de instrucciones que se repite se ejecuta al menos una vez. Pseudocódigo Diagrama de Flujo Lenguaje C Hacer do <instrucciones> <instrucciones>; while(<condición>); Mientras <condición>Fin Tabla 4.9: Representaciones de la estructura repetitiva Hacer-mientras (do-while) Observa que en el código en C, la única estructura de control, de todas las que hemos visto, que tiene punto y coma después de la expresión o condición es el do-while. Por el funcionamiento de la estructura, el caso típico del uso del do-while son los menús. Para ejemplificar lo anterior se propone el siguiente problema. Problema 4.6: Se requiere un programa que imprima un menú con las siguientes opciones, el cual se repita en tanto no se elige la opción d (Salir). a. Calcular la fuerza b. Calcular la aceleración c. Calcular la masa d. SalirEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 109
  • 110. Fundamentos de programaciónPrograma Desarrollado Además, dependiendo de la opción que elija el usuario se deberá realizar la tarea indicada utilizando la segunda ley de Newton que dicta: “La aceleración que un cuerpo adquiere es directamente proporcional a la resultante de las fuerzas que actúan en él, y tiene la misma dirección en el sentido que en dicha = ∗ ó resultante” En este caso, para resolver la parte del menú se utilizará un switch-case, en el que cada opción del menú corresponda a un caso, así las instrucciones que lo forman deben ser: la lectura de los datos correspondientes y la operación apropiada (que se define despejando la variable en cuestión de la fórmula dada). Para que el menú se repita se plantea un ciclo while que se ejecute mientras la opción sea distinta de 4 (Salir). De esta forma el algoritmo se presenta a continuación en sus dos representaciones. Inicio Hacer Imprimir "Realiza Cálculos trabajando la 2a. Ley de Newton" Imprimir " ------------------------------------------------" Imprimir " a. Fuerza." Imprimir " b. Aceleración." Imprimir " c. Masa." Imprimir " d. Salir." Imprimir " Elegir una Opción: " Leeropc Selecciona (opc) Caso 1: Imprimir "Ingresa La masa:” Leer m Imprimir “Ingresa la aceleración:” Leer a f = m*a Imprimir “Fuerza = ”, f Caso 2: Imprimir "Ingresa la fuerza:” Leer f Imprimir “Ingresa la masa:” Leer m a = f/m Imprimir “Aceleración = ”, a Caso 3:Imprimir "Ingresa la fuerza:” Leer f Imprimir “Ingresa la aceleración:” Leer a m = f/a Imprimir “Masa = ”, mEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 110
  • 111. Fundamentos de programaciónPrograma Desarrollado Caso 4: Imprimir "Adios" Otro: Imprimir " Opción inválida" Fin_Selecciona Mientras (opc!=4) Fin Fin Algoritmo 4.6.a: Segunda ley de Newton - pseudocódigo A continuación se presenta el diagrama de flujo, salvo que únicamente se ha dejado indicado en donde van las instrucciones de los tres primeros casos, ya definidas en el pseudocódigo. Algoritmo 4.6.b: Segunda ley de Newton – diagrama de flujo En el diagrama de flujo se puede observar claramente que el ciclo se ejecutará mientras el usuario no elija la opción d, que corresponde a salir. Por lo que no se deja como ejercicio al lector la validación del algoritmo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 111
  • 112. Fundamentos de programaciónPrograma Desarrollado La codificación del algoritmo se muestra enseguida. /* Programa: newton.c Descripción: Muestra un menú para calcular la aceleración, fuerza o masa, conforme a la segunda ley de Newton */ /*directivas de preprocesador*/ #include <stdio.h> #include <stdlib.h> #include <conio.h> /*Función Principal*/ main () { /*Declaración de variables*/ char opc; float f,m,a; /*Ciclo para repetir el menú mientras que la opción no sea salir*/ do {/*Impresión del menú*/ system ("cls");/*Instrucción para borrar la pantalla*/ printf ("n Realiza Calculos trabajando la 2a. Ley de Newton"); printf ("n ------------------------------------------------"); printf ("n a. Fuerza. n b. Aceleracion n c. Masa n d. Salir"); printf ("n Elige una opcion: "); /*Instrucción que lee una variable de tipo carácter*/ opc=getche(); /*Estructura de Selección Múltiple*/ switch (opc) { case a: printf ("nnIngresa la masa: "); scanf("%f",&m); printf ("nIngresa la aceleracion: "); scanf("%f",&a); f=m*a; printf("nLa fuerza es %.2fnnt",f); system ("pause"); break; case b: printf ("nnIngresa la fuerza: "); scanf("%f",&f); printf ("nIngresa la masa: "); scanf("%f",&m);Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 112
  • 113. Fundamentos de programaciónPrograma Desarrollado a=f/m; printf("nLaaceleracion es %.2fnnt",f); system ("pause"); break; case c: printf ("nnIngresa la fuerza: "); scanf("%f",&f); printf ("nIngresa la aceleración: "); scanf("%f",&m); m=f/a; printf("nLa masa es %.2fnnt",f); system ("pause"); break; case d: printf ("nnAdiosn"); system ("pause"); break; default: printf ("nn Opcion Invalida"); }/*Fin dela Selección Múltiple*/ }while (opc!=d); }/*Fin*/ Programa 4.5: newton.c En la siguiente figura se muestra la ejecución de una iteración del ciclo, en la cual la opción elegida es la primera. Figura 4.6: Ejecución del programa newton.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 113
  • 114. Fundamentos de programaciónPrograma Desarrollado Observa que dentro del cuerpo del ciclo se definió una estructura selectiva, es decir, que las instrucciones del cuerpo de cualquier estructura compuesta, sea repetitiva o selectiva, puede contener a otras. Uno de los casos más utilizados es el anidamientos de los if´s, de lo cual hablaremos en la siguiente sección. Pero antes de dar por terminada esta sección se propone la siguiente actividad. Actividad 1. Estructuras de control –Ejercicio F Realiza una prueba de escritorio del algoritmo que resuelve el problema 4.6 presentado en esta sección (algoritmo 4.4.a y algoritmo 4.4.b) considerando que se muestran en la ejecución del programa en la figura 4.6, y considerando que la siguiente opción del usuario es salir. Posteriormente escribe y compila el programa newton.c (programa 4.6) en la computadora y ejecútalo con los mismos valores para comparar el resultado. Finalmente, reflexiona si las estructuras de control repetitivas presentadas en esta unidad son equivalente, es decir, cualquier de ellas se puede representar con las otras e ingresa tus conclusiones en el Foro Estructuras de control. 4.3. Estructuras anidadas Las estructuras de control selectivas y repetitivas se consideran compuestas ya que se forman a partir de otras instrucciones que son las que se ejecutaran de acuerdo a una condición dada. Es importante remarcar que las instrucciones que forman el cuerpo de una estructura pueden ser también estructuras compuestas, como se demostró en la solución del último problema visto (ver algoritmo 4.6 y programa 4.6), en el cual un switch está dentro de un while. Así que es posible anidar cualquier tipo de estructura, sin embargo, lo más común es anidar instrucciones if, pues se utilizan cuando se tienen varios casos, por ejemplo, si revisamos nuevamente el problema 4.1, donde se quiere determinar el tipo de ángulo, es mejor solución utilizar if-anidados para resolverlo porque así no se evalúan condiciones que, una vez que se ha definido el tipo de ángulo, son innecesarias. Para ilustrar lo anterior, a continuación se muestra el pseudocódigo y su codificación para la solución del mismo problema. Inicio Imprimir "Ingrese la medida del angulo (grados): " Leer angulo Si angulo≤0 OR angulo≤360 entonces Imprimir “No tiene clasificación" Sino Si angulo<90 entonces Imprimir "El ángulo es agudo" Sino Si angulo=90 entonces Imprimir "El angulo es recto" Sino Si angulo<180 entoncesEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 114
  • 115. Fundamentos de programaciónPrograma Desarrollado Imprimir “El angulo es obtuso" Sino Si angulo =180 entonces Imprimir "El angulo es llano" Sino Imprimir “El angulo es concavo" Fin_Si-Sino Fin_Si-Sino Fin_Si-Sino Fin_Si-Sino Fin_Si-Sino Fin Algoritmo 4.7: Tipo de ángulo (versión 2)- pseudocódigo (Fuente: elaboración propia) Si realizas la prueba de escritorio con el ángulo igual a 90 grados, podrás darte cuenta que a diferencia de la primera versión del algoritmo donde se evalúan todas las condiciones, aquí sólo se evalúan las tres primeras, en los dos primeros Si es falsa y por lo tanto se ejecutan las instrucciones del Sino correspondiente, pero en el tercer Si anidado la condición es verdadera y se imprime el tipo de ángulo, posteriormente se acaba el anidamiento. El programa en C es el siguiente: main () { /*Declaración de variables */ intangulo; /*Mensaje de bienvenida*/ printf ("nEste programa determina de que tipo es el angulo dado."); /*Instrucciones */ printf ("nnIngrese la medida del angulo (grados): "); scanf ("%d",&angulo); if (angulo<=0 || angulo>=360) printf ("n No tiene clasificación"); else if (angulo<90) printf ("n El angulo es agudo"); else if (angulo==90) printf ("n El angulo es recto");Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 115
  • 116. Fundamentos de programaciónPrograma Desarrollado else if (angulo<180) printf ("nElanguloesobtuso"); else if (angulo ==180) printf ("n El angulo es llano"); else printf ("nElangulo es concavo"); printf ("nnt"); system ("pause"); } Programa 4.7: tipoAngulo2.c La ejecución con el ángulo igual a 90 grados se muestra en la siguiente figura. Figura 4.7: Ejecución del programa tipoAngulo2.c Con este ejemplo se da por terminada esta unidad, ahora ya conoces todas las estructuras y has visto cómo funcionan y qué tipo de situaciones se puede modelar con ellas. Aunque cabe destacar que para solucionar cualquier problema basta con que sepas utilizar el ciclo while y la estructura selectiva if- else, pues ya se mencionó que todos los ciclos son equivalentes y con la estructura if-else, puedes modelar un switch-case anidando if´s. Actividad 1. Estructuras de control –Ejercicio G Realiza una prueba de escritorio del algoritmo que resuelve el problema 4.1, en su versión de if´s anidados, presentado en esta sección (algoritmo 4.7), considerando que el valor del ángulo es 90 grados. Posteriormente escribe, compila y ejecuta el programa tipoAngulo2.c (programa 4.7) en la computadora con el mismo valor del ángulo para verificar tu resultado.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 116
  • 117. Fundamentos de programaciónPrograma Desarrollado Actividad 3: Estructuras repetitivas Realiza el análisis, diseño de un algoritmo (en pseudocódigo y diagrama de flujo) y codificación de un programa que resuelva el problema que te proporcionará tu Facilitador(a). Utiliza estructura(s) repetitiva(s). Para conocer los detalles de la actividad, ingresa al aula virtual. Evidencia de aprendizaje.Programa en C. Estructuras de control Con ayuda de tu facilitador deberás acotar el problema que describiste en la evidencia de la unidad 2, de tal manera que la solución sólo implique el uso de estructuras de control. Para conocer los detalles de la actividad, ingresa al aula virtual. Consideraciones específicas de la unidad Para cumplir con los objetivos de esta unidad te recomendamos que realices las actividades señaladas como opcionales de cada subtema, las cuales consisten en pruebas de escritorio y codificación, compilación y ejecución de los programas que se realizaron a lo largo de esta unidad. Referencias: • Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. aspaño: Mc Graw Hill. • Kernighan, B., & Ritchie, D. (1991). El lenguaje de programción C. México: Prentice-Hall Hispanoamericana. • López, L. (2005). Programación estructurada en lenguaje C. México: Alfaomega. • Pérez, H. (1992). Física General (Primera Edición ed.). México: Publicaciones Cultura.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 117
  • 118. Fundamentos de programaciónPrograma Desarrollado Unidad 5: Estructuras de datos Propósitos En esta unidad: • Determinarás las estructuras de datos involucradas en la solución de un problema. • Diseñarás soluciones empleando arreglos y estructuras (registros). • Utilizarás arreglos y estructuras (registros) en programas escritos en lenguaje C. Competencia específica Utilizar estructuras de datos para almacenar y manipular los datos de un programa por medio del desarrollo de programas en lenguaje C. Introducción En muchas ocasiones nos vemos en la necesidad de procesar datos que están relacionados entre sí, a este tipo de datos se le conoce como estructurados, ya que están compuestos de un conjuntos de datos básicos (recuerda la clasificación de datos presentada en la unidad 3 en la tabla 3.2 Tipo de datos). Por ejemplo pensemos en el nombre completo de una persona, que está compuesto nombre, apellido paterno y apellido materno, o bien, en una dirección, formada por nombre de la calle, número y código postal, en este último caso no sólo está formada por varios datos simples sino que además podemos considerarlos de diferentes tipos (Figura 5.1). Figura 5.3: Ejemplos de datos Estructurados Con este tipo de datos será útil poder hacer referencia a ellos bajo un mismo identificador, y así tratarlos como una unidad. Una estructura de datos es un mecanismo de agrupación de datos que facilitan el manejo de datos estructurados y que se caracteriza por la forma en que se acede a sus elementos. Pensemos en otro ejemplo en el cual se tienen datos relacionados, supongamos que nos enfrentamos al siguiente problema:Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 118
  • 119. Fundamentos de programaciónPrograma Desarrollado Problema 5.1: Se requiere un programa para llevar el registro de calificaciones de un grupo de diez estudiantes y generar reportes que incluyan datos como el promedio del grupo, la calificación máxima, el número de estudiantes que tienen una calificación superior al promedio del grupo, entre otros. En este caso, a diferencia de los ejemplos anteriores, es claro que las calificaciones de cada estudiante se puede tratar como un dato simple e independiente de los otros, sin embargo las operaciones que se desean realizar serán las mismas para todo el conjunto de calificaciones, de tal forma que habría que escribir una serie de instrucciones secuenciales para ingresar cada dato y procesarlo. Por ejemplo, para ingresar los datos se requiere leer una por una cada calificación, para obtener el promedio se tendría que hacer la suma de todas y después dividirlas entre 10, hasta aquí no se ha complicado mucho, pero imagina todas las comparaciones que debes hacer para identificar cuál es la calificación mayor. Es claro que este método resulta de lo más ineficiente, y por supuesto si consideramos la posibilidad de modificar el programa para que sea capaz de procesar 60 o más calificaciones, el programa además de extenderse, implica reestructurarlo en su totalidad y que éste sea más complejo que la versión anterior. En cambio si consideramos a todos las calificaciones como un dato estructurado podemos hacer uso de una estructura de dato que nos facilite su manipulación. Existen diferentes tipos de estructuras de datos, cada una caracterizada por la forma de acceso a sus elementos, y el tipo que estos pueden tener, así tenemos arreglos, listas, colas, tablas, pilas, entre otros. No obstante, para esta unidad nos centraremos sólo en las estructuras de datos que implementa el lenguaje C de forma directa: los arreglos y las estructuras. 5.1. Arreglos El uso de arreglos facilita y hace más eficiente la declaración y manipulación de una colección de datos de un mismo tipo que están relacionados entre sí, como es el caso de las calificaciones en el Problema1, ya que todas las calificaciones se pueden considerar como valores enteros. 5.1.1. Definición y tipos de arreglos “Un arreglo se define como una colección finita, homogénea y ordenada de elementos. Finita ya que para todo arreglo debe especificarse el número máximo de elementos que podrá contener; la homogeneidad se refiere a que todos los elementos deben ser del mismo tipo, y ordenada porque es posible determinar cuál es el primer elemento, cual el segundo, y así hasta el enésimo elemento”(Cairo Osvaldo, Guardati Buemo Silvia, 1993). La posición que ocupa un elemento dentro de un arreglo se le denomina formalmente índice y siempre es un número entero. El tamaño o longitud de un arreglo se define como el número de elementos que lo constituyen. La dimensión de un arreglo está relacionada con el número de índices necesarios para especificar a una elemento en particular.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 119
  • 120. Fundamentos de programaciónPrograma Desarrollado Podemos clasificar a los arreglos de acuerdo a su dimensión como unidimensionales o multidimensionales. Los arreglos unidimensionales(también llamados lineales) reciben su nombre debido a que cualquier elemento es referenciado por un único índice, por ejemplo retomando el caso de las calificaciones del problema 5.1, éstas pueden ser almacenadas en un arreglo unidimensional como el que se muestra en la figura 5.2, en donde el nombre del arreglo es lista y los nombres de las variables donde se almacenan las calificaciones son: lista[0], lista[1], lista[2], lista[3], lista[4] …, lista[9]. En este caso el nombre en común es lista y lo único que cambia para cada elemento es el número que le corresponde a cada variable según la posición que ocupa en la lista. Observa que un solo índice es suficiente para diferenciar a un elemento de otro. Figura 5.4 Representación gráfica de un arreglo unidimensional Por otro lado los arreglos multidimensionales son aquellos para los cuales un solo índice no es suficiente para poder referenciar a un elemento individual, los arreglos bidimensionales son el caso más comúnmente utilizado de arreglos multidimensionales y por tanto los únicos que presentaremos. “Un arreglo bidimensional es un conjunto de datos homogéneos, finito y ordenado, donde se hace referencia a cada elemento por medio de dos índices. El primero de los cuales generalmente se utiliza para indicar renglón y el segundo para indicar columna” (Cairo Osvaldo, Guardati Buemo Silvia, 1993) Un arreglo bidimensional también puede verse como una tabla de valores, o bien como un arreglo de arreglos, de ahí la necesidad de dos índices, en la figura 5.3 se muestra un ejemplo gráfico de un arreglo bidimensional, en la cual del lado derecho podemos ver al arreglo como una tabla y del lado izquierdo representado como un arreglo de arreglos, Observa que cada renglón de la tabla es cada unoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 120
  • 121. Fundamentos de programaciónPrograma Desarrollado de los elementos del arreglo de arreglos. Es claro que con un solo índice no podríamos identificar a un único elemento ya que solo podríamos ubicar toda una columna o todo un renglón, en cambio la combinación de renglón-columna si nos identifica a un elemento en particular. Figura 5.5Representación gráfica de un arreglo bidimensional 5.1.2. Declaración e inicialización En lenguaje C los índices de los arreglo siempre empiezan en cero, es decir, al primer elemento del arreglo le corresponde la posición 0, al segundo la posición 1, al tercero la posición 2 y así sucesivamente hasta llegar al elemento TAM-1, donde TAM corresponde al tamaño del arreglo. La declaración de un arreglo consiste en reservar espacio de memoria suficiente para el conjunto de datos homogéneos. La declaración de una variable de tipo arreglo sigue las mismas reglas que para las variables simples; con la diferencia de que ahora será necesario especificar el tamaño del arreglo, esto se hace escribiendo el tamaño del arreglo encerrado entre corchetes [ TAM ], después del identificador. La sintaxis para la declaración de un arreglo unidimensional en lenguaje C es la siguiente: <tipo><nombre>[<tamaño>]; Y para un arreglo bidimensional es: <tipo><nombre>[<tamaño1>] [<tamaño2>];Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 121
  • 122. Fundamentos de programaciónPrograma Desarrollado El tipo de dato para los arreglos puede ser cualquier tipo básico, es decir entero, flotante o carácter (en C int, float, double o char ). De todos ellos los arreglos de tipo carácter (char) tienen un tratamiento especial, ya que un arreglo de este tipo se considerara una cadena. Debido a la importancia que tienen las cadenas en la programación más adelante los trataremos de manera particular. Al igual que las variables simples, un arreglo puede inicializarse al momento de ser declarado, para ello se utiliza el operador asignación “=”, pero como un arreglo almacena a un conjunto de datos, es necesario inicializarlo con un conjunto de valores, los cuales se indican mediante llaves, separando por comas cada elemento del conjunto de valores iniciales, la sintaxis se muestra a continuación: <tipo><nombre>[<tamaño>]={<valor0>,<valor1>,…,<valorTAM-1>}; La asignación de cada valor inicial se hace consecutivamente desde el elemento 0, por tanto no es posible asignar valores a elementos salteados. Veamos como ejemplo la declaración del arreglo unidimensional lista (figura 5.2) planteado para las calificaciones del problema1. Inicializando sus elementos en la declaración queda como: int lista[10] = {9,10,8,5,9,6,7,9,4,8}; En el caso de los arreglos bidimensionales la sintaxis es la siguiente: <tipo><nombre>[<tamaño1>][<tamaño2>]={ {<valor00>,<valor01>,…,<valor0(TAM21)>}, {<valro10>,<valor11>,…,<valor1(TAM21-1)>},…, {<valor(TAM1-1)0>,<valor (TAM2-1)1>,…,<elem(TAM1-1)(TAM2-1)>} }; Veamos ahora como queda la declaración del arreglo bidimensional tabla mostrado en la figura 5.3, inicializando su valores: int tabla[5][3]={{9,10,8},{5,9,6},{7,9,4},{8,9,6},{7,9,4}}; Aunque también es posible declararlo de la siguiente forma: int tabla[5][3]={9,10,8,5,9,6,7,9,4,8,9,6,7,9,4}; Esta es debido a que como ya se dijo antes un arreglo bidimensional se pude ver como un arreglo de arreglos.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 122
  • 123. Fundamentos de programaciónPrograma Desarrollado Por otro lado, en lenguaje C siempre es necesario especificar el tamaño del arreglo al momento de declararlo, sin embargo esto se puede hacer de forma explícita o implícita. • Explícitamente es cuando se especifica el tamaño dentro de los corchetes que siguen al identificador, como en los ejemplos anteriores. • De forma implícita se hace cuando el arreglo es inicializado con un conjunto de valores, y se omite el tamaño dentro de los corchetes, entonces el compilador asume el tamaño del arreglo igual al tamaño del conjunto de valores iniciales, de tal forma que la declaración del arreglo lista puede quedar como: int lista[] = {9,10,8,5,9,6,7,9,4,8}; Observa que en este caso no se escribe el tamaño dentro de los corchetes, pero como hay 10 elementos en el conjunto de valores iniciales, el compilador de C asume un tamaño 10 para el arreglo. Para los arreglos bidimensionales, sólo es posible especificar una dimensión de forma implícita, el tamaño de renglones siempre debe hacerse de forma explícita. La asignación de un conjunto de valores al arreglo, en una sola operación de asignación, únicamente es posible en su declaración, si se intenta realizar en otro momento el compilador marcará un error, ya que en cualquier otra parte del programa sólo se podrán asignar valores simples a cada uno de los elementos por separado. Es importante señalar que cuando se desea inicializar el arreglo al declararlo, es posible inicializar sólo algunos de sus elementos, pero en este caso se tendría que especificar explícitamente el tamaño, además se debe recordar que la asignación de valores iniciales es consecutiva desde el elemento 0. Los elementos para los cuales no se indique un valor inicial, automáticamente se inicializan en cero. Por ejemplo la declaración int lista[10] = {5}; Reservará espacio en memoria para los 10 elementos del arreglo de los cuales al primer elemento se le asignará un 5 y al resto se les asignará un cero. En el caso de los arreglos bidimensionales es posible declara sólo algunos elementos por renglón, siempre y cuando los elementos sean consecutivos, como en el caso de los unidimensionales. Por ejemplo la siguiente declaración para el arreglo tabla: int tabla[5][3]={{9,10},{5},{7,9,4},{8,9,}};Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 123
  • 124. Fundamentos de programaciónPrograma Desarrollado Daría como resultado la siguiente asignación de valores iniciales [0] [1] [2] [0] 9 10 0 [1] 5 0 0 [2] 7 9 4 [3] 8 9 0 [4] 0 0 0 En el caso de que la declaración fuera: int tabla[5][3]={9,10,5,7,9,4,8,9,}; Entonces la asignación de valores iniciales se haría de la siguiente forma [0] [1] [2] [0] 9 10 5 [1] 7 9 4 [2] 8 9 0 [3] 0 0 0 [4] 0 0 0 5.1.3. Acceso a los elementos de un arreglo Para referirse a un elemento del arreglo es necesario indicar el nombre del arreglo seguido del índice o índices correspondientes al elemento que deseamos acceder. Para ello se debe seguir la siguiente sintaxis. Elementos de un arreglo unidimensional: <nombre del arreglo>[<índice>]; Elementos de un arreglo bidimensional: <nombre del arreglo>[<índice de renglón>][<índice de columna>]; Observa que para cada índice se utilizan corchetes separados. Cada elemento del arreglo se puede tratar igual que a cualquier otra variable, es decir, podemos asignarle un valor, incluir en una expresión algebraica o lógica, imprimir en pantalla su valor, asignarle desde el teclado un valor, etc.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 124
  • 125. Fundamentos de programaciónPrograma Desarrollado Veamos algunos ejemplos: Instrucción Descripción tabla[0][2] = 8; Asignar el valor de 8 al tercer elemento del primer renglón de arreglo tabla Imprimir en pantalla el quinto elemento del printf(“%d”,lista[4]); arreglo lista Lee un entero desde teclado y asignarlo en scanf(“%d”,&tabla[0][0]); la primera posición del arreglo tabla. Incrementar en uno el valor del segundo lista[1]++; elemento del arreglo lista 5.1.4. Ciclos y arreglos Los arreglos y los ciclos están estrechamente relacionados, podríamos afirmar que en cualquier programa que se emplee un arreglo éste será manipulado por medio de una estructura repetitiva. Anteriormente mencionamos que un arreglo se utiliza cuando queremos almacenar y manipular datos relacionados entre sí y, generalmente, cuando tenemos un arreglo debemos ejecutar el mismo conjunto de operaciones sobre cada uno de sus elementos. En lenguaje C el índice del elemento se puede especificar mediante una expresión, es decir una variable, una constante o como el resultado de una operación, lo que hace posible ir cambiando el índice de un elemento dentro de un ciclo sin tener que escribir una serie de instrucciones secuenciales para realizar la misma operación sobre cada uno de los elementos del arreglo. La forma general de procesar un arreglo unidimensional por medio de un ciclo se muestra en la figura 5.4, observa cómo la variable contador pos del ciclo, también se utiliza como índice para el elemento del arreglo, de tal forma que en cada iteración se haga referencia a un elemento diferente del arreglo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 125
  • 126. Fundamentos de programaciónPrograma Desarrollado Figura 5.6Procesamiento de arreglos unidimensionales mediante ciclos No es difícil intuir que para el caso de los arreglos bidimensionales será necesario no solo un ciclo sino un par de ciclos anidados, ya que tenemos dos dimensiones, cada uno de los ciclos se encargará de variar a un índice, la estructura general para estos ciclos se muestra en la figura 5.5. Dos ciclos están anidados cuando está uno dentro de otro, de tal forma que por cada iteración del externo, el interno completa todo un ciclo. Considerando esto, observa que en la figura 5.5 se toma como contador a la variable i para el ciclo externo, la cual también se utiliza como índice de renglón. Asimismo, se utiliza a la variable j como contador para el ciclo interno, además de índice de columna, de esta manera se está recorriendo el arreglo por renglón.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 126
  • 127. Fundamentos de programaciónPrograma Desarrollado Figura 5.7Procesamiento de arreglos bidimensionales mediante ciclos anidados Si analizamos el diagrama de flujo podemos observa que para la primera iteración del ciclo externo, la variable i tiene el valor de 0 mientras que j toma los valores desde 0 hasta TAMC-1 (TAMC es el número total de columnas) de tal forma que el renglón se mantiene fijo mientras nos movemos en todas las columnas, en la siguiente iteración cambia el renglón ya que i toma el valor de 1 y recorremosEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 127
  • 128. Fundamentos de programaciónPrograma Desarrollado nuevamente todas las columnas, este proceso se repite hasta el valor final de i que es TAMF-1 (TAMF es el número de renglones). Ejemplo 5.1: Veamos cómo utilizar arreglos en la solución de un problema, resolviendo como ejemplo parte del problema 1, enfocándonos únicamente en la lectura de las 10 calificaciones y el cálculo del promedio. Para almacenar las calificaciones se puede utilizar un arreglo unidimensional de tipo entero, será necesario pedir al usuario que ingrese las 10 calificaciones para poder realizar las operaciones necesarias para el cálculo del promedio, es decir, la suma de las misma y la división entre el total de calificaciones, para finalmente imprimir en pantalla el promedio, adicionalmente se imprimirá también la lista de calificaciones ingresadas. No existe ninguna restricción que sea necesaria considerar. Cada uno de los procesos que se van a realizar sobre las calificaciones, es decir leerlas, sumarlas e imprimirlas en pantalla se pueden implementar mediante ciclos, en vez de tener que escribir 10 veces la misma expresión para cada una de las 10 calificaciones. La lectura y la suma de las calificaciones se pueden implementar dentro del mismo ciclo. De esta manera podemos resumir el análisis del problema de la siguiente forma: Datos de entada: Calificaciones de los 10 estudiantes (calif [ ]) Salida: Promedio de calificaciones (prom) Método: ∑9 [] =0 10 prom = La solución del problema representada en pseudocódigo se muestra en el siguiente algoritmo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 128
  • 129. Fundamentos de programaciónPrograma Desarrollado Inicio suma ← 0 Desde i ← 0 mientras i<10, i ← i+1 Imprimir “Ingresa la calificación” i Leer calif[i] suma← suma+calif[i] Fin Desde prom ← prom/10 Imprimir “Las calificaciones ingresadas fueron:” Desde i ← 0 mientras i<10, i ← i+1 Imprimir “Calificación” i “:” calif[i] Fin Desde Imprimir “Calificación promedio = ” prom Fin Algoritmo 5.2. Promedio de calificaciones La codificación del algoritmo anterior es la siguiente: /*Directivas de preprocesador*/ #include <stdio.h> #include <stdlib.h> /* Definimos como constante simbólica el tamaño del arreglo*/ #define TAM 10 /* Definición de función principal */ main( ) { /*Declaración del arreglo calificaciones*/ int calif[TAM]; double prom = 0; int i; printf("*******************************************n”); printf(“* El siguiente programa calcula el promedio de *n"); printf(“* un grupo de diez estudiantes *n”); printf("********************************************n”); /*Lectura y suma de las calificaciones*/ for(i=0; i < TAM; i++) { printf("Proporciona la calificación %d: ",i+1); scanf(“%d”, &calif[i]); prom = prom + calif[i];Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 129
  • 130. Fundamentos de programaciónPrograma Desarrollado } /*Cálculo e impresión del promedio*/ prom = prom/TAM; /*Impresión de las calificaciones*/ printf("nLas calificaciones ingresadas fueron: n"); for(i=0; i < TAM; i++) printf("nCalificacion %d: %d",i+1, calif[i]); printf("nntPromedio = %.2fnn", prom); system("pause"); } Programa 5.1: promCalificaciones.c En la siguiente figura se muestra una ejecución del programa. Figura 5.8: Ejecución del programa promCalificaciones.c Observa que el tamaño del arreglo se especifica por medio de una constante simbólica, utilizando la directiva #define, esto facilita el cambiar el tamaño del arreglo sin tener que hacer cambios en todo el código.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 130
  • 131. Fundamentos de programaciónPrograma Desarrollado Actividad 1. Foro Estructuras de Datos –Ejercicio A Realiza una prueba de escritorio con los datos que se muestran en la ejecución del programa promCalificaciones.c (figura 5.6) y posteriormente escribe, compila y ejecuta el programa en la computadora. Reflexiona cómo solucionarías el problema si no contaras con los arreglos y qué pasaría si en vez de calcular el promedio de 10 calificaciones tuvieras que hacerlo para 50, qué se debería modificar en cada el programa que se presentó en esta sección y qué tendrías que modificar sino contaras con los arreglos. Ingresa tus conclusiones al Foro Estructuras de Datos A continuación se presenta otro ejemplo para ilustrar el uso de arreglos bidimensionales. Ejemplo 5.2: Se requiere un programa que calcule el determinante de una matriz de 2x2. Considerando la siguiente información. Dada la siguiente matriz: Su determinante se define como: ∆=a00a11-a01a10 Análisis del problema: Para este problema se puede utilizar un arreglo bidimensional de 2 renglones y 2 columnas para almacenar los valores de la matriz, los cuales se pueden solicitar al usuario utilizando la estructura de ciclos anidados presentada en la figura 5.5, nuestro dato de salida será el valor del determinante y adicionalmente también se mostrará en pantalla la matriz ingresada. Datos de entada: Elementos de la matriz (A[ ][ ]) Salida: Valor del determinante (det) = [0][0] ∗ [1][1] − [0][1] ∗ [1][0] Método: La solución del problema se da en el siguiente diagrama de flujo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 131
  • 132. Fundamentos de programaciónPrograma Desarrollado Algoritmo 5.3: Determinante de una matriz 2x2Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 132
  • 133. Fundamentos de programaciónPrograma Desarrollado La codificación del algoritmo se deja como ejercicio al lector, sin embargo, en la siguiente figura se muestra un ejemplo de ejecución del programa. /* Directivas al preprocesador */ #include <stdlib.h> #include <stdio.h> /* Constantes con el tamaño de la matriz */ #define TAM 2 /* Función principal */ main() { int i, j; float det; float A[TAM][TAM]; /*declaración de la matriz*/ /* Mensaje de bienvenida */ printf("***************************************n"); printf("* Determinante de una matriz A de 2x2 *n"); printf("***************************************n"); /* Lectura de la matriz A */ for(i=0; i<TAM; i++) for(j=0; j<TAM; j++){ printf("nProporciona el elemento A[%d][%d]: ", i,j); scanf("%f", &A[i][j]); } det = A[0][0]*A[1][1] - A[0][1]*A[1][0]; printf("nA: nt"); /* Impresión de la matriz A */ for(i=0; i<TAM; i++){ for(j=0; j<TAM; j++) printf("%8.2f", A[i][j]); printf("nt"); } printf("nnttDeterminante = %.2fnn", det); system("pause"); } Programa 5.2: determinantes.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 133
  • 134. Fundamentos de programaciónPrograma Desarrollado En la siguiente figura se muestra una ejecución del programa. Figura 5.9: Ejecución del programa determinante.c Actividad 1. Foro Estructuras de Datos –Ejercicio B Realiza una prueba de escritorio con los datos que se muestran en la ejecución del programa determinante.c (figura 5.7) y posteriormente escribe, compila y ejecuta el programa en la computadora. Comparte tu experiencia en el Foro. 5.1.5 Cadenas Una cadena es una serie de caracteres tratados como una sola unidad. Una cadena puede incluir letras, dígitos y varios caracteres especiales(Deitel H. M., Deitel P. J., 1995). En algunos lenguajes de programación existe un tipo de dato específico para definir a las cadenas, sin embargo, en lenguaje C las cadenas se implementan por medio de arreglos de tipo carácter ya que no existe un tipo específico para ellas, pero existe todo un conjunto de funciones estándar definidas en la biblioteca string.h mediante las cuales es posible realizar las operaciones más comunes, por ejemplo: copiarlas, concatenarlas, compararlas, entre otras. Además es posible imprimirlas y leerlas de forma similar que un dato simple. En lenguaje C toda constaten de tipo cadena se indica entre comillas dobles, por ejemplo: “Calle 2 #135”Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 134
  • 135. Fundamentos de programaciónPrograma Desarrollado Una cadena en C termina siempre con el carácter nulo ‘0’ (cuyo valor ascii es cero) que representa el fin de cadena. Al declarar arreglos de tipo char que sean una cadena se pueden inicializar directamente con una constante cadena de la siguiente forma: char cad[50]=”saludo”; Al inicializar una variable cadena de esta manera, se agrega automáticamente el símbolo de carácter nulo para indicar el fin de cadena, es decir, en la posición 6 del arreglo cad se encuentra almacenado el fin de cadena ‘0’. De forma general, es importante señalar que en un arreglo de tamaño N es posible almacenar correctamente una cadena de máximo N-1 caracteres. De tal forma que en el arreglo cad se puede almacenar una cadena de máximo 49 caracteres. Las cadenas en C pueden ser asignadas a un arreglo de tipo char utilizando la función scanf mediante el especificador de formato %s, por ejemplo la línea de código: scanf(“%s”,cad); De esta manera se lee desde el teclado una cadena y se guarda en el arreglo cad, sólo que en este caso no se incluye el operador & antes del nombre del arreglo, pues el identificador del arreglo almacena la dirección del primer elemento del mismo. La función gets() también nos permite leer del teclado una cadena y asignarla a un arreglo de tipo char, por ejemplo la instrucción: gets(cad); Lee una cadena desde el teclado y la almacena en el arreglo cad. Una diferencia importante entre usar scanf y gets es que con la primera la lectura de la cadena se da por terminada cuando el usuario presiona [Enter] o Espacio, mientras que la segunda termina la lectura de la cadena únicamente cuando el usuario presiona [Enter], tal como se muestra en los siguientes ejemplos: Cadena ingresada Instrucción Contenido del arreglo cad[] “Calle 2 #135” scanf(“%s”,c cad[]: ad); C a l l e / / … / 0 0 0 “Calle 2 #135” gets(cad); cad[]: C a l l e 2 # 1 3 5 / … / 0 0Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 135
  • 136. Fundamentos de programaciónPrograma Desarrollado Similarmente, para imprimir en pantalla una cadena se puede utilizar la función printf con el especificador de formato %s, o bien, la función puts, nuevamente ambas funciones tienen un comportamiento similar con la única diferencia de que puts incluye siempre un salto de línea al final, esto se ilustra a continuación. Código c Ejecución Impresión de cadena con printf #include <stdio.h> #include <stdlib.h> main(){ char mensaje[30]=”Mar profundo ”; printf(“%s”,mensaje); system(“pause”); } Impresión de cadena con puts #include <stdio.h> #include <stdlib.h> main(){ char mensaje[30]=”Mar profundo ”; puts(mensaje); system(“pause”); } Las funciones que nos permiten el manejo de cadenas se encuentran en la biblioteca estándar string.h, para ilustrar algunas se muestra el siguiente programa en C. Ejemplo 5.3: El programa siguiente verifica si una clave (password) de 8 caracteres alfanuméricos ingresado por el usuario es correcta. /*Directivas de preprocesador*/ #include <stdio.h> #include <stdlib.h> #include <string.h> /* se incluye la biblioteca de cadenas */ main( ) { /* Declaración de variables */ char pwscorrecto[9]=”jk278la0”; /* Clave correcta */Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 136
  • 137. Fundamentos de programaciónPrograma Desarrollado char pwsingresado[9]; /* para leer la clave que ingrese el usuario */ char nombre[10]; /* Para leer el nombre del usuario */ char mensaje[50]=”Bienvenido ”; /* Lectura de datos */ printf(“Nombre: "); gets(nombre); /* Lectura de una cadena con espacios */ printf(“pasword: "); scanf(“%s”,pwsingresado); /* Lectura de una cadena sin espacios*/ if (!strcmp(pwscorrecto,pwsingresado)){ /* comparación de claves, si la función strmp regresa 0 son i iguales */ printf(“pasword correcto n”); strcat(mensaje,nombre); /* pega al final de mensaje el nombre del usuario*/ puts(mensaje); /* impresión de la cadena con salto de línea*/ } else { strcpy(mensaje, “Acceso denegado”); /* copia la cadena acceso denegado al mensaje */ puts(mensaje); /* imprime la cadena*/ } system("pause"); } Programa 5.3: password.c En la siguiente figura se muestran dos ejecuciones del programa a) Clave inválida b) Clave válida Figura 5.10: Ejecución del programa password.c (Fuente: elaboración propia utilizando DevC++) Con esto se concluye la sección de arreglos, recuerda que un arreglo es un conjunto de dato del mismo tipo. En la siguiente sección verás cómo puedes agrupar datos de diferente tipo.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 137
  • 138. Fundamentos de programaciónPrograma Desarrollado 5.2. Estructuras Las estructuras en C al igual que los arreglos nos permiten tratar a un conjunto de datos bajo un mismo identificador pero a diferencia de los arreglos las estructuras son conjuntos de datos contiguos en memoriano homogéneos de tal forma que una estructura puede estar formada por datos de diferentes tipos. Una de las aplicaciones para las estructuras es para la manipulación de registros que se recuperan o se almacenan en una base de datos. 5.2. Definición, declaración e inicialización “Una estructura es una colección de una o más variables, de tipos posiblemente diferentes, agrupadas bajo un nombre para manejo conveniente (en algunos lenguajes también se conocen como registros). Las estructuras permiten tratar a un grupo de variables relacionadas como una unidad, en vez de que se traten en forma separada (Kernighan & Ritchie, 1991, pág. 141)”. La definición de una estructura en C inicia con la palabra reservada struct seguida del identificador para el tipo de estructura y de un bloque de definiciones de variable que constituyen el conjunto de elementos que forman parte de ella, la sintaxis para definir la estructura es la siguiente: struct<identificadorEstructura>{ <tipo1><identificadorE1>; <tipo2><identificadorE2>; … <tipoN><identificadorEN>; } Observa que se utiliza la palabra reservada struct para iniciar la definición y que las declaraciones para los elementos de la estructura se encierran entre llaves. Una estructura puede contener a N elementos de diferentes tipos, de cualquiera de los tipos básicos, o incluso un arreglo, veamos un ejemplo: struct paciente { int nss; /* número de seguro social */ char apellido[50]; char nombre[20]; int edad; float estatura; char sexo; }Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 138
  • 139. Fundamentos de programaciónPrograma Desarrollado En este ejemplo se está definiendo la estructura paciente que tiene seis elementos: dos enteros (nss y edad), dos cadenas (apellido y nombre), un flotante (estatura) y un carácter (sexo). Sin embargo la definición anterior no reserva espacio en memoria para la estructura, más bien define un tipo de dato, por lo tanto para poder utilizar la estructura, es necesario declarar una variable de este tipo, es aquí cuando se reserva espacio en memoria. La sintaxis para hacer esta declaración es la siguiente: struct<identificadorEstructura><identificador_var>; Por ejemplo la declaración: struct paciente paciente1, paciente2; Declara a las variables paciente1 y paciente2, las cuales son del tipo paciente y por tanto para cada una de ellas se reserva espacio en memoria suficiente para cada uno de sus seis elementos. Otra forma válida de hacer la declaración es haciéndola seguida a la definición de la estructura, para el ejemplo anterior puede escribirse como sigue: struct paciente { int nss; char apellido[50]; char nombre[20]; int edad; float estatura; char sexo; } paciente1, paciente2; En este caso el identificador para el tipo de estructura puede omitirse, pero entonces la única forma de declarar variables para ese tipo de estructura es en su definición, y no en una declaración por separado, de tal forma que nuestro ejemplo puede quedar como sigue: struct { int nss; char apellido[50]; char nombre[20]; int edad; float estatura; char sexo; } paciente1, paciente2;Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 139
  • 140. Fundamentos de programaciónPrograma Desarrollado Por otro lado, al igual que los arreglos, también se pueden inicializar los elementos de una estructura en el momento de la declaración de una variable del tipo de la estructura en cuestión, éstos deben estar encerrados entre llaves y separados por comas. La sintaxis general es la siguiente: struct<identificadorEstructura><identificador_var> = { <valorE1>,<valor2>, …,<valorN> }; Por ejemplo : struct paciente paciente1 = {1240, “PicaPiedra”, “Pedro”, 45, 1.80, ‘M’}; Sólo en el momento de la declaración es posible asignar todos los valores de una estructura (al igual que con los arreglos), así que si después se quiere modificar tendrán que hacerse las modificaciones de forma separada en cada uno de sus elementos, como se muestra en el siguiente subtema. Actividad 2. Arreglos y estructuras. Retoma el programa que has trabajado para las evidencias de aprendizaje anteriores y realiza una versión preliminar del mismo pero ahora incorporando lo que has aprendido en esta unidad. Tu facilitador(a) te orientará si tienes dudas. Con esta actividad podrás prepararte para la entrega de tu evidencia de aprendizaje de la unidad. 5.2.2. Acceso a sus elementos Para referenciar un elemento de la estructura se utiliza el operador punto “.” con la siguiente sintaxis: <idenficador_var>.<idenficadorEi> Este operador seguido del identificador del elemento, referencia el elemento indicado, de tal forma que la sentencia para asignar al paciente1 un nss de 23442145 será: paciente1.nss = 23442145; Ahora, si se quiere asignar a la misma variable el nombre “Pablo”, la instrucción sería: paciente1.nombre = “Pablo”; Del mismo modo se realiza la impresión o lectura del elemento de la estructura, sin perder de vista su tipo. Para ilustrar esto se propone el siguiente ejemplo. Ejemplo 5.4: En el siguiente programa se declara una estructura de tipo perro, que tiene los siguientes elementos: Elemento TipoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 140
  • 141. Fundamentos de programaciónPrograma Desarrollado Raza char[] Edad int Peso float Posteriormente se declaran dos variables de éste tipo, una se inicializa en la declaración y a la otra se le asignan valores desde el teclado, ambos se muestran al final en pantalla. #include <stdio.h> #include <stdlib.h> #include <conio.h> main(){ /* Declaración de la estructura perro*/ struct perro{ char raza[20]; int edad; float peso; } fido, pluto = {"labrador", 7, 20} ; /* inicialización de la variable pluto*/ printf("***********************************"); printf("n* Comparando perros *"); printf("n***********************************"); printf("nnIngresa la raza de fido:"); scanf("%s",&fido.raza); /* lectura de un elemento */ printf("Ingresa la edad de fido en a%cos:", 164); scanf("%d",&fido.edad); /* lectura de un elemento */ printf("Ingresa el peso de fido en kilos de fido:"); scanf("%f",&fido.peso); /* lectura de un elemento */ /* impresión de los elementos de las estructuras */ printf("nFido es de raza %s, tiene %d a%cos y pesa %.2f kilosn",fido.raza,fido.edad,164,fido.peso); printf("nPluto es de raza %s, tiene %d a%cos y pesa %.2f kilosn",pluto.raza,pluto.edad,164,pluto.peso); /* comparación de los nombres que son cadenas */ if(!strcmp(pluto.raza,fido.raza)) printf("nPluto Y Fido son de la misma raza n"); elseEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 141
  • 142. Fundamentos de programaciónPrograma Desarrollado printf("nFido y Pluto son de razas distintasn"); /* comparación de elementos de tipo numérico */ if(pluto.peso > fido.peso) printf("Pluto es m%cs pesado que Fidon",160); else if(pluto.peso < fido.peso) printf("Fido es m%cs pesado que Pluton",160); else printf("Fido y Pluto pesan lo mismon"); if(pluto.edad > fido.edad) printf("Pluto es mas viejo que Fidon"); else if(pluto.edad < fido.edad) printf("Fido es mas pesado que Pluton"); else printf("Fido y Pluto tienen la misma edad n"); getch(); } Programa 5.4: perros.c Nota: Observa que en este caso, para poder imprimir la letra ñ se utilizó su código Ascii (164) para lo cual en la cadena de control del printf se escribió %c en donde se desea imprimir la ñ. Este mismo truco se hizo para acentuar la letra a. En la siguiente figura se muestra una ejecución del programa anterior. Figura 5.11: Ejecución del programa perros.c Actividad 1. Foro Estructuras de Datos –Ejercicio CEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 142
  • 143. Fundamentos de programaciónPrograma Desarrollado Escribe, compila y ejecuta en la computadora el programa perros.c. Posteriormente, analiza cuáles son las principales diferencia entre las estructuras y los arreglos e ingresa tus comentarios en el Foro Estructuras de Datos. Para concluir con este capítulo veamos el siguiente ejemplo donde se utilizan estructuras y arreglos: Ejemplo 5.5:Se requiere un programa que permita registrar los datos de los perros que ingresan a refugio para perros, y poder desplegar los datos de alguno de los perros, a cada perro se le asigna una clave numérica consecutiva. Los datos que se registran del perro son: • la fecha de ingreso (cadena) • nombre (cadena) • raza (cadena) • color (cadena) • edad (entero) • peso (flotante) El refugio tiene capacidad máxima para 100 perros. Para la solución del problema se puede plantear un menú que permita registrar a un perro, o bien, desplegar los datos del perro solicitados. En este caso tenemos como datos de entrada la opción del menú que elija el usuario. En el caso de que sea un registro tendremos también se tienen como datos de entrada los datos del perro. Para la opción de despliegue se tendrá que dar como datos de entrada la clave del perro y la salida serán los datos correspondientes a la clave. Para desplegar y repetir el menú se requiere un ciclo y una estructura condicional que maneje las opciones del menú. Para almacenar los datos del perro, se puede utilizar una estructura similar al ejemplo anterior. Mediante un arreglo de estas estructuras estaremos en capacidad para manipular los datos de varios perros, el tamaño de este arreglo tendrá que ser igual a la capacidad del refugio (100 perros), de tal forma que el índice del arreglo que toca a cada perro corresponderá con su clave. Una restricción que hay que tomar en cuenta es que se debe verificar que no se sobre pase la capacidad de los 100 peros, tanto al ingresar datos como al recuperarlos, para ello se llevará un contador (c) que actualice el número de perros ingresados. Inicio c←0 Hacer Imprimir “Refugio para perros -Ladrido Feliz- ” Imprimir “1) Registrar un perro ” Imprimir “2) Buscar un perro ”Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 143
  • 144. Fundamentos de programaciónPrograma Desarrollado Imprimir “3) Salir ” Imprimir “Elige una opción: ” Leer op Casos para op Caso 1: Si c≥100 entonces Imprimir “El refugio está lleno” Si no Imprimir “Ingresa los datos del perro:” Imprimir “Clave:” c Imprimir “fecha de ingreso[dd/mm/aa]: ” Leer perros[c].fecha Imprimir “color: ” Leer perros[c].color Imprimir “nombre: ” Leer perros[c].nombre Imprimir “raza: ” Leer perros[c].raza Imprimir “edad: ” Leer perros[c].edad Imprimir “peso: ” Leer perros[c].peso c ← c+1 Fin si-si no Caso2: Imprimir “Clave: ” Leer clave Mientras clave≥100 v clave <0 hacer Imprimir “La calve no es válida, ingresa nuevamente la clave:” Leer clave Fin mientras Imprimir “nombre:”, perros[clave].nombre Imprimir “fecha de ingreso:”, perros[clave].fecha Imprimir “color: ”, perros[clave].color Imprimir “raza: ”, perros[clave].raza Imprimir “edad: ”, perros[clave].edad Imprimir “peso: ”, perros[clave].peso Caso 3: Otro caso: Imprimir ”Opción no válida” Fin casos Mientras op≠3 Fin Hacer-mientras Fin Algoritmo 5.3. Registro perrosEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 144
  • 145. Fundamentos de programaciónPrograma Desarrollado La prueba de escritorio se deja como ejercicio al lector. En cuanto a la codificación del algoritmo se muestra a continuación. #include <stdio.h> #include <stdlib.h> #include <conio.h> main(){ /* Declaración del arreglo de tipo estructura perro */ struct perro{ char fecha[10]; char raza[30]; char color[50]; char nombre[30]; int edad; float peso; } perros[100]; int c=0, op, clave; do{ /* Inicio del ciclo que imprime el menú*/ printf( "n----------------------------------------n"); printf( "nRefugio para perros -Ladrido Feliz- n" ); printf( "n----------------------------------------n"); printf( "1) Registrar un perro n" ); printf( "2) Buscar un perro n" ); printf( "3) Salir n" ); printf( "Elige una opci%cn:",162 ); scanf("%d",&op); switch (op){ case 1: /*Opción Registrar perro */ printf( "n------------------------------n"); if(c>=100) /* Verifica si hay espacio */ printf("El refugio esta llenon"); else{ /*Si hay espacio pide los datos del perro y Y los guarda en el registro c del arreglo */ printf( "Ingresa los datos del perro:"); printf( "Clave:%.3dn", c); printf( "fecha de ingreso[dd/mm/aa]: ");Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 145
  • 146. Fundamentos de programaciónPrograma Desarrollado scanf( "%s", perros[c].fecha); printf( "nombre: "); fflush(stdin); gets( perros[c].nombre); printf( "color: "); gets( perros[c].color); printf( "raza: "); gets( perros[c].raza); printf( "edad: "); scanf("%d" ,&perros[c].edad); printf( "peso: "); scanf("%f" ,&perros[c].peso); c++; } break; case 2: /* Opción buscar perro */ printf( "n-------------------------------n"); printf( "Clave: "); scanf("%d",&clave); /* verifica que la clave sea válida */ while(clave>=100 || clave <0){ printf("La calve no es válida, ingresa nuevamente la clave:"); scanf("%d",&clave); } /* Imprime los datos del perro correspondiente a la clave */ printf("nombre:%sn",perros[clave].nombre); printf( "fecha de ingreso: %sn", perros[clave].fecha); printf( "color: %sn", perros[clave].color); printf( "raza: %sn", perros[clave].raza); printf( "edad: %d a%cosn", perros[clave]edad,164); printf( "peso: %.2f kilosn", perros[clave].peso); break; case 3: /* Caso salir, no hace nada */ break; default: /* Caso opción inválida */ printf( "Opcion no validan"); } }while (op!=3); /* El ciclo do-while se repite mientras la opción no sea salir (3) */ }Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 146
  • 147. Fundamentos de programaciónPrograma Desarrollado Programa 5.5: registroPerros.c Evidencia de aprendizaje. Programa en C. Avance de solución del problema implementando las estructuras de datos Con ayuda de tu facilitador deberás acotar el problema que describiste en la evidencia de la unidad 1, de tal manera que la solución involucre a las estructuras de datos vistas en esta unidad. Para conocer los detalles de la actividad, ingresa al aula virtual. Consideraciones específicas de la unidad Para alcanzar los objetivos de esta unidad te recomendamos que escribas y compiles los programas que se desarrollaron a lo largo de la misma y realices una prueba de escritorio de cada uno de ellos, tal como se sugiere en las actividades opcionales. Referencias: • Cairo Osvaldo, Guardati Buemo Silvia. (1993). Estructura de Datos. México: McGraw-Hill. • Deitel H. M., Deitel P. J. (1995). Cómo programar en C/C++. México: Prentice Hall. • Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. aspaño: Mc Graw Hill. • Kernighan, B., & Ritchie, D. (1991). El lenguaje de programción C. México: Prentice-Hall Hispanoamericana. • López, L. (2005). Programación estructurada en lenguaje C. México: Alfaomega.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 147
  • 148. Fundamentos de programaciónPrograma Desarrollado Unidad 6: Funciones Propósitos En esta unidad: • Identificarás los sub-problemas en que puede dividirse un problema. • Diseñarás algoritmos modulares para solucionar un problema • Construirás funciones en lenguaje C que realicen tareas específicas Competencia específica Implementar funciones para resolver problemas a través del desarrollo de programas modulares escritos en lenguaje C. Introducción Hasta esta etapa del curso, has aprendido a utilizar las estructuras de control para diseñar soluciones de problemas simples. También has conocido diferentes formas de representar los datos involucrados en un problema, desde simples hasta estructurados (como arreglos, cadenas y estructuras). Sin embargo, todas las soluciones propuestas constan únicamente de un módulo (función), llamado principal (en C, main); lo cual no es conveniente cuando se trata de problemas complejos que requieran de una serie de tareas para lograr su solución, pues ésta sería muy grande y, por lo tanto, difícil de corregir o modificar. En estos casos lo recomendable es crear módulos independientes que realicen cada una de las tareas específicas y que en conjunto implementen la solución del problema. A esta metodología se le llama diseño modular, y está inspirado en la estrategia “divide y vencerás”. En esta unidad se explicarán las funciones, que son el medio por el cual se implementan los módulos en lenguaje C. Se presentará la sintaxis para crear una función y la forma en la que se utilizan. Además, se resolverá un problema utilizando el diseño modular para ejemplificar el tema. 6.1. Diseño descendente La descomposición de un programa en módulos más pequeños se conoce como el método de divide y vencerás (divide and conquer) o diseño descendente (top-down). Consiste en dividir un problema en unidades más pequeñas sucesivas hasta que sean directamente ejecutadas por el procesador, en otras palabras, la solución del problema se divide una y otra vez hasta que esté expresada en términos deEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 148
  • 149. Fundamentos de programaciónPrograma Desarrollado estructuras de control, cada uno de los niveles o pasos sucesivos se conoce como refinamiento (stepwise). La metodología del diseño descendente consiste en efectuar una relación entre las etapas de estructuración de manera que se relacionen entre sí a través de entradas y salidas de datos. Es decir, se descompone el problema en etapas de estructuración jerárquicas, de forma que se pueda considerar cada estructura desde dos puntos de vista: ¿qué hace? y ¿cómo lo hace? Con lo anterior podemos decir que: un módulo se caracteriza por realizar una tarea específica, posee sus propios datos de entrada – llamados parámetros de entrada – y su resultado – llamado salida o valor de retorno –. El diseño de cada módulo debe ser independiente de los otros; si es necesario que exista comunicación entre ellos, ésta únicamente podrá realizarse a través de los parámetros de entrada y del valor de retorno. En este sentido, puede ser visto, por otros módulos, como una caja negra que hacia el exterior sólo muestra qué hace y qué necesita, pero no cómo lo hace. La creación de un modulo conlleva dos partes: la definición del módulo y la llamada o invocación (ejecución). La primera consta de tres partes: • Definir los parámetros de entrada; • Definir el valor de retorno; • Escribir todas las instrucciones que le permitirán llevar a cabo la tarea, es decir, un algoritmo. La llamada o invocación a un módulo es el proceso de ejecutar el conjunto de instrucciones definidas en el módulo dado un conjunto de entradas específico. La forma general de invocar un módulo es escribiendo su nombre y entre paréntesis los valores de cada uno de los parámetros de entrada, respetando el orden que con el que se definió. No existe un método para saber en cuánto módulos se debe dividir un problema, sin embargo es importante tener en cuenta los siguientes principios del diseño modular: • Las partes altamente relacionadas deben pertenecer a un mismo módulo. • Las partes no relacionadas deben residir en módulos diferentes. Para ejemplificar esta forma de resolver problemas y cómo implementarla, se presenta la siguiente situación: Problema 6.1: Realiza el análisis y diseño de un programa que lea las temperaturas promedio mensuales registradas en una ciudad a lo largo de un año y calcule el promedio anual. Además, debe convertir las temperaturas mensuales dadas en grados Celsius a grados Fahrenheit al igual que el promedio. Empecemos por hacer un bosquejo de los pasos que se tienen que realizar para llegar al resultado deseado. 1. Leer las doce temperaturas promedio mensualesEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 149
  • 150. Fundamentos de programaciónPrograma Desarrollado 2. Calcular el promedio anual de las temperaturas 3. Convertir las temperaturas promedio mensuales de Celsius a Fahrenheit 4. Convertir el promedio anual de temperaturas a Fahrenheit 5. Imprimir las temperaturas mensuales en grados Fahrenheit y el promedio anual de las temperaturas, en Celsius y Fahrenheit. Para registrar las temperaturas mensuales proponemos utilizar un arreglo de tamaño 12. Y de acuerdo con lo anterior, proponemos tres módulos: El primero encargado de leer las temperaturas mensuales dadas en grados Celsius, este módulo necesita el nombre del arreglo donde va a almacenar los datos. Otro módulo encargado de calcular el promedio de las temperaturas, que recibe como parámetros de entrada el arreglo con las temperaturas mensuales y devuelve el promedio en grados Celsius. El último módulo sólo convierte grados Celsius a grados Fahrenheit. Esta información se resume en el diagrama modular que se muestra a continuación. Figura 6.12: Diagrama modular del problema 6.1 Es mediante un diagrama modular como se representan de manera gráfica los módulos que integran la solución del problema. Y una vez que se han definido, el siguiente paso es diseñar el algoritmo de cada uno de ellos. En primer lugar se muestra el pseudocódigo de los módulos secundarios.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 150
  • 151. Fundamentos de programaciónPrograma DesarrolladoMódulo leerTemps(temp[ ])Inicio Desde mes ← 1 mientras mes ≤ 12, mes ← mes + 1 Imprimir “Proporciona la temperatura del mes”, mes Leer temps[mes-1] Fin_DesdeFin Algoritmo 6.4: Algoritmo del módulo leerTemps(temp[]) Observa que el ciclo del módulo leeTemps se inicia con mes igual a 1 y termina cuando mes es 13, se propone así porque se pide la temperatura de los mes 1, 2, 3,.. 12, así que la variable mes guardara el número de mes correspondiente a cada lectura, sin embargo para almacenar la temperatura en la posición del arreglo indicada se resta uno (temps[mes-1]), así se guarda desde la posición 0 y hasta la posición 11.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 151
  • 152. Fundamentos de programaciónPrograma DesarrolladoMódulo promTemps(temp[])Inicio suma ← 0 Desde mes ← 0 mientras mes ≤ 11, mes ← mes + 1 suma ← suma + temps[mes] Fin_Desde Regresa (suma/12)Fin Algoritmo 6.2: Algoritmo del módulo promTemps(temp[]) En contraste con el ciclo del módulo leerTemp, en este módulo el contador del ciclo se inicia en 0 y termina en 11 (aunque el valor que tiene al finalizar el ciclo es 12) pues se utiliza para ir sumando cada uno de los elementos del arreglo, así que la variable mes indicará cada una de las posiciones del arreglo.Módulo aFahrenheit(tempC) tempF = 9�5 tempC + 32Inicio Regresa tempFFin Algoritmo 6.2: Algoritmos de módulos secundarios del problema 6.1 (pseudocódigo)Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 152
  • 153. Fundamentos de programaciónPrograma Desarrollado A partir de los módulos secundarios presentados se puede plantear el módulo principal.Módulo PrincipalInicio /* Lectura de las temperaturas, invocando al módulo leerTemps */ Imprimir “Ingresa los promedios de temperaturas mensuales” leerTemps(temps[]) /* Cálculo del promedio utilizando el módulo promTemps */ promC ← promTemps(temps[]) /* Conversión del promedio a grados Fahrenheit, invocando al módulo aFahrenheit */ promF ← aFahrenheit(promC) /* Conversión de las temperaturas mensuales a grados Fahrenheit */ Desde mes ← 0 mientras mes ≤ 11, mes ← mes + 1 tempsF[mes] ← aFahrenheit(temps[mes]) Fin_Desde /* Impresión de temperaturas mensuales en Fahrenheit */ Desde mes ← 1 mientras mes ≤ 12, mes ← mes + 1 Imprimir “Temperatura en Fahrenheit del mes”, mes, “ es: ”, tempF[mes-1] Fin_Desde /* Impresión del promedio en grados Celsius y grados Fahrenheit */ Imprimir “ El promedio en grados Celsius es: “, promC Imprimir “El promedio en grados Fahrenheit es: “, promFFin Algoritmo 6.4: Algoritmo del módulo principal del problema 6.1 (pseudocódigo) Por esta ocasión se deja como ejercicio al lector que realice las representaciones en diagrama de flujo del módulo principal, considerando que el símbolo que se utiliza para llamar a módulos que no devuelven ningún valor, como es el caso se leerTemps se muestra a continuación: leerTemps(temp[]) Esto no es caso, del resto de los módulos secundarios que sí devuelven un valor, así que se utiliza el símbolo de proceso (rectángulo). Con el ejemplo anterior resaltan indudablemente varias ventajas que proporciona un diseño modular: 1. Es posible reutilizar código, ésta indudablemente es una de las más importantes ya que no es necesario escribir el mismo código cada vez que deseamos realizar una tarea semejante. PorEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 153
  • 154. Fundamentos de programaciónPrograma Desarrollado ejemplo, el módulo aFahrenheit se utiliza 13 veces (12 en el ciclo y una para convertir el promedio) y sólo basto definirlo una vez. 2. Fácil detección y corrección de errores, dado que el problema fue divido en pequeños módulos cada uno responsable de una tarea, si en algún momento existiera un error en la solución global, basta identificar cuál de las tareas es la que no se está resolviendo adecuadamente y corregir únicamente aquellos módulos involucrados. 3. Fácil modificación o extensión, si se requiere modificar una tarea del problema o agregar una nueva, no será necesario rediseñar todo el algoritmo, basta con hacer las modificaciones en los módulos pertinente. 4. Un problema se vuelva más sencillo de solucionar si pensamos de manera modular. Una vez que se ha ilustrado como realizar una solución modular, lo siguiente es explicar cómo se codifica cada uno de los módulos, tema que se abordará en las siguientes secciones. } Actividad 1. Foro Funciones En esta actividad reflexionarás sobre las ventajas del diseño descendente y las funciones en Lenguaje C a partir de la solución modular del problema que planteaste en las unidades anteriores. Conforme avances en el diseño modular del mismo ingresa tus comentarios al respecto en el Foro Funciones. 6.2. Definición, declaración e invocación de funciones en C En el caso particular de C, un módulo se implementa como una función, recuerda que en la unidad 3 se explico que un programa en C está integrado de varias funciones, donde una función se define como una porción de código (un conjunto de instrucciones agrupadas por separado) enfocado a realizar una tarea en específico, resaltando la función principal main. Al igual que la función principal, cada una de las funciones existe de manera independiente, tiene sus propias variables, instrucciones y un nombre que las distingue de las otras. Además de los parámetros de entrada (también llamados argumentos) que recibe y el tipo de dato que regresa. La forma general para definir una función es: <tipo de dato retorno><identificador de la función>( <parámetros de entrada>) { <instrucciones de la función> return<expresión>; }Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 154
  • 155. Fundamentos de programaciónPrograma Desarrollado El <tipo de dato retorno> indica el tipo de dato que la función devuelve (puede ser cualquiera de los tipos básicos), para lo cual se utiliza la palabra reservada return. Cuando la función no va a devolver ningún dato se especifica mediante el tipo void y no debe incluir la palabra reservada return. El <identificador de la función> es el nombre que le vamos a dar a la función y mediante el cual vamos a hacer referencia a ella. Se deben seguir las mismas reglas que los identificadores de las variables y se recomienda que sea nemónicos. Enseguida del nombre y entre paréntesis va la lista de parámetros, que consiste de una lista de declaraciones de variables locales que van a contener los datos de entrada para la función, se debe especificar explícitamente el tipo y nombre para cada uno, separados por comas, aún cuando sean del mismo tipo: tipo1 param1, tipo2 param2,…, tipoN paramN. Por último, las instrucciones del cuerpo de la función van entre llaves. La primera línea de la definición de una función se conoce como encabezado de la función (en inglés header). Para ilustrar esto, a continuación se muestra la codificación del módulo aFahrenheit definido en la sección anterior. float aFahrenheit(float tempC) { return ((9.0/5.0)*tempC+32); } Programa 6.1: Codificación del módulo aFahrenheit La llamada o invocación a una función se realiza cuando se requiere que se ejecuten las instrucciones del cuerpo con valores de entrada determinados. Para invocar a una función se tiene que escribir el nombre seguido de los valores que deben coincidir con el orden, número y tipo de los parámetros de entrada dados en la definición de la función y deben estar encerrados entre paréntesis. La sintaxis general para invocar una función ya sea predefinida o definida por el programador, es la siguiente: <identificador de la función>( <lista de valores>); Los parámetros de entrada de una función son valores, por lo que pueden estar determinados por: valores constantes (8,’a’, 5.2, “cadena constante”) o una variable (lo que realmente se pasa a la funciónEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 155
  • 156. Fundamentos de programaciónPrograma Desarrollado es el valor almacenado) o una expresión (el parámetro de entrada real es el resultado de la evaluación). Por ejemplo, la llamada a la función que definimos se remarcar en la siguiente instrucción: promF = aFahrenheit(promC); Al igual que las variables una función debe de ser declarada antes de utilizarse, es decir, antes de invocarla. La declaración de una función se realiza escribiendo el prototipo de la función. El prototipo de una función coincide con el encabezado de la misma terminando con punto y como (;) El prototipo de una función sólo indica al compilador que existe y cómo es, más no lo que hace por lo tanto se debe definir después. Por ejemplo, el prototipo de la función antes definida sería: float aFahrenheit(float tempC); Cabe señalar que en el prototipo de las funciones se puede omitir los identificadores de los parámetros, más no los tipos. Para ilustrar todo lo anterior, a continuación se muestra la codificación del algoritmo modular diseñado en la sección anterior. /* Programa: promedioTemp.c * Descripción: Calcula el promedio de las temperaturas promedio * mensuales registrada a lo largo de un año*/ /* Biblioteca */ #include<stdio.h> #include<stdlib.h> /* Variables globales */ int meses = 12; /* Prototipos de las funciones */ /* Función que lee las temperaturas promedio mensuales registradas en un año*/ void leerTemps( float temps[]); /* Función que calcula el promedio de las temperaturas promedio mensuales registradas en un año*/ float promTemps( float temps[]); /* Función que convierte de grados Celsius a grados Fahrenheit */Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 156
  • 157. Fundamentos de programaciónPrograma Desarrollado float aFahrenheit(float tempC); /* Función principal */ main() { /* Declaración de variables locales a main */ float temps[12], tempsF[12], promF, promC; int mes; /* Lectura de las temperaturas, invocando a leerTemps*/ printf(“Ingresa los promedios de temperaturas mensualesn”); leerTemps(temps); /* Cálculo del promedio utilizando la función promTemps */ promC = promTemps(temps); /* Conversión del promedio a grados Fahrenheit, invocando al módulo aFahrenheit */ promF = aFahrenheit(promC); /* Conversión de las temperaturas promedio mensuales a grados Fahrenheit, invocando al módulo aFahrenheit */ for(mes = 0; mes<=11; mes++) tempsF[mes] = aFahrenheit(temps[mes]); /* Impresión de temperaturas promedio mensuales en grados Fahrenheti*/ for(mes = 1; mes<=12; mes++) printf(“n La temperatura en grados Fahrenheit del mes %d es %.2f: ”, mes, tempsF[mes-1]); /* Impresión del promedio */ printf(“nn El promedio anual en grados Celsius es: %.2f ”, promC); printf(“n El promedio anual en grados Fahrenheit es: %.2f ”, promF); system(“pause”); } /* fin main */Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 157
  • 158. Fundamentos de programaciónPrograma Desarrollado /* Definición de funciones */ void leerTemps (float temps[]) { /* Definición de variables locales a leerTemps */ int mes; for(mes = 1; mes<=12; mes++) { printf(“n Ingresa la temperatura promedio del mes %d: ”, mes); scanf(“%f”, &temps[mes-1]); } } /* fin leerTemps */ float promTemps (float temps[]) { /* Definición de variables locales a promTemps */ int mes; float suma=0; for(mes = 0; mes<=11; mes++) suma = suma + temps[mes]; return (suma/12); } /* fin leerTemps */ float aFahrenheit(float tempC) { return ((9.0/5.0)*tempC+32); } /* fin aFahrenheit */ Programa 6.1: promedioTemp.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 158
  • 159. Fundamentos de programaciónPrograma Desarrollado Figura 6.2: Ejecución del programa promedioTemp.c Actividad 2. Funciones En esta actividad presentarás una versión preliminar del programa que has trabajado como parte de las evidencias de aprendizaje anteriores, el cual, ahora debe incorporar módulos para hacer más eficiente su funcionamiento. En el aula virtual encontrarás más detalles. 6.3. Alcance de las variables El alcance de las variables es la parte del programa dentro de la cual se pueden utilizar. Cuando son declaradas fuera del cuerpo de cualquier función se denominan variables globales y pueden ser utilizadas en cualquier punto del programa a partir del lugar donde fueron declaradas, en cambio cuando son declaradas dentro del cuerpo de alguna función se denominan variables locales a ésta, esEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 159
  • 160. Fundamentos de programaciónPrograma Desarrollado decir sólo dentro de esa función pueden ser utilizadas. Las variables locales que tienen en el mismo nombre pero fueron declaradas en diferentes funciones, no tienen relación, son espacios de memoria totalmente independientes uno de otro. Podemos decir que, son como dos personas diferentes que tienen el mismo nombre. Por otro lado las variables que se ponen como argumentos en la declaración de una función se consideran locales a estas. Para ejemplificar lo anterior, se muestra el siguiente programa, en el cual se distinguen con diferentes colores el alcance de las variables. #include<stdio.h> #include<stdlib.h> Variable global int TAM = 5; Variable local a inicializaA void inicializaA(int A[]) { Variable local Referencia a una int i; variable global for (i=0; i<TAM; i++) A [i] = 0; } main() { Declaración de int i; variables locales a main int A[] = {1,1,1,1,1}; printf(“Arreglo antes de la llamada a inicializaA: A = [”); for (i=0; i<TAM; i++) { if(i< TAM -1) printf(“%d ,”,A[i]); else printf(“%d ]nnt”,A[i]); } inicializaA(A); printf(“Arreglo despues de la llamada a inicializaA: A = [”); for (i=0; i<TAM; i++) { if(i< TAM -1) printf(“%d ,”,A[i]); else printf(“%d ]nnt”,A[i]); } system(“pause”); } Programa 6.2: porReferencia.cEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 160
  • 161. Fundamentos de programaciónPrograma Desarrollado Al utilizar variables globales todas las funciones pueden manipularlas, sus valores permanecen mientras el programa está en ejecución. Sin embargo su uso puede promover errores de tipo lógico, ya que al modificar el valor de una variable dentro de una función puede afectar el resultado de otra. Por ejemplo, supongamos que la función inicializaA() modifica el valor de la variable TAM que almacena el número de elementos del arreglo A, este cambio repercutirá en los ciclos de la función main, los cuales imprimen el arreglo A. En este caso se producirá un error en la ejecución, pues si el valor es menor a cinco no se imprimirán todos los valores y se es mayor entonces habrá elementos indefinidos. Detectar y corregir este tipo de errores puede ser una tarea nada fácil, por lo que no se recomienda el uso de variables globales, lo cual no ocurre si son constantes. Las variables locales por otra parte favorecen mucho la reutilización de código y la modularidad, ya que cada función declara y manipula sus propias variables sin depender de lo que ocurra en otras funciones, esto no significa que al utilizar solamente variables locales no sea posible compartir datos entre las diferentes funcione, esto se hace mediante sus datos de entrada y retorno, una posible desventaja es que el valor de las variables locales se pierde cada vez que la función termina. 6.4. Paso de parámetros EL paso de parámetros se refiere a la forma en la que se transfieren como parámetro una variable a una función, esencialmente, si se le otorgan o no permisos para modificar los valores originales. Cuando no se le otorga permisos para que la modifique se dice que es paso de parámetros por valor, pues en este caso sólo se transfiere el valor de la variable, el cual se almacena en una variable local de la función que se está llamando. En cambio, cuando la función puede modificar el valor de la variable se dice que es un paso de parámetro por referencia, pues en este caso no se pasa sólo el valor sino la dirección de memoria que le corresponde a la variable. En los siguiente subtemas se explica más a detalle los dos tipos de paso de parámetro. 6.4.1. Por valor Cuando se realiza una llamada a una función por valor y en ésta aparece una variable como uno de los argumentos, en realidad no se está pasando la variable sino una copia del valor que ésta contiene, lo cual implica que si dentro de la función se modifica el argumento esto no se ve reflejado en el programa desde el cual se hizo la llamada, pues son localidades de memoria diferentes (recuerda que en cada llamada a una función se crean nuevas variables y se destruyen una vez finaliza la ejecución). #include<stdio.h> #include<stdlib.h> void inicializa(int a) { a = 0;Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 161
  • 162. Fundamentos de programaciónPrograma Desarrollado printf("nEl valor de la variable local "a" es %dnn",a); } main() { int a=10; /* Llamada a la función incializa */ printf("nEl valor de "a" antes de la llamada es %inn", a); inicializa(a); printf("nEl valor de "a" despues de la llamada es %inn", a); system("pause"); } Programa 6.3: porValor.c La ejecución del programa es: Figura 6.3: Ejecución del programa pasoValor.c En la ejecución puedes ver que la variable local a main no se modifica, esto es porque se pasa una copia del valor que almacena cuando se realiza la llamada a la función inicializa(a). Este valor se guarda en un espacio de memoria, también llamado a, que es una variable local a la función y que existe mientras ésta se ejecuta. Observa que el cambio si se realiza en la variable local de la función inicializa. 6.4.2. Por referencia La llamada a una función por referencia sí modifica el valor de la variable, pues lo que realmente se está pasando es la dirección de memoria asignada a la variable para que la función pueda modificar el valor. En C los arreglos siempre se pasan por referencia, ya que el nombre del arreglo en realidad almacena la dirección de memoria donde se encuentra almacenado el primer elemento del arreglo. De esta manera cuando se realiza una llamada a una función y se escribe el identificador de un arreglo comoEducación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 162
  • 163. Fundamentos de programaciónPrograma Desarrollado parámetro, se está pasando la dirección. Para ejemplificar lo anterior se muestra la ejecución del programa pasoReferencia.c que se presentó en un subtema anterior. Figura 6.4: Ejecución del programa pasoRefencia.c En la ejecución del programa se observa que después de la llamada a la función cambia el estado del arreglo A. Finalmente, cabe mencionar que para realizar la llamada por referencia de una variable de tipo básico en lenguaje C es necesario pasar la dirección de la variable para lo cual se utiliza el operador & seguido del nombre de la variable (&nombre), como se hace en la función scanf, este operador regresa la dirección de memoria que le corresponde a la variable indicada. Por otra parte, para almacenar la dirección de memoria de una variable se utiliza una variable de tipo apuntador. Una variable apuntador se encarga de almacenar una dirección de memoria, la declaración de una variable apuntador es similar a la de cualquier otra variable, con la diferencia que se debe escribir un asterisco entre el tipo de la variable y el identificador. El tema de los apuntadores es muy interesante, sin embargo, no es uno de los objetivos de este curso. Para que apliques lo aprendido en esta unidad y a lo largo del curso se propone la siguiente evidencia de aprendizaje. Evidencia de aprendizaje: Programa en C. Entrega final del programa modular que soluciona el problema planteado Esta es la última evidencia, deberás realizar el diseño modular del problema original que describiste en la evidencia de la unidad dos, así como la codificación de tu solución. Para conocer los detalles ingresa al aula virtual. Consideraciones específicas de la unidad Te sugerimos que escribas, compiles y ejecutes los programas que se desarrollaron a lo largo de esta unidad para que comprendas mejor los contenidos y te apropies de ellos.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 163
  • 164. Fundamentos de programaciónPrograma Desarrollado Referencias • Deitel H, M., & Deitel P, J. Cómo programar en C/C++. México: Prentice Hall. • Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos y estructuras de datos. aspaño: Mc Graw Hill. • Kernighan, B., & Ritchie, D. (1991). El lenguaje de programción C. México: Prentice-Hall Hispanoamericana. • López, L. (2005). Programación estructurada en lenguaje C. México: Alfaomega. • Pérez, H. (1992). Física General (Primera Edición ed.). México: Publicaciones Cultura.Educación Superior Abierta y a Distancia • Ciencias Exactas, Ingeniería y Tecnología 164