notas del curso introducciÓn a la...

209
NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓN por Ing. Sergio Páez Rodea Departamento de Ingeniería Eléctrica Universidad Autónoma Metropolitana Unidad Iztapalapa

Upload: dinhkhuong

Post on 30-Sep-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

NOTAS DEL CURSO

INTRODUCCIÓN A LA PROGRAMACIÓN

por

Ing. Sergio Páez Rodea

Departamento de Ingeniería Eléctrica

Universidad Autónoma Metropolitana

Unidad Iztapalapa

Page 2: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

2

Page 3: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

3

Índice 1.- BREBE RESUMEN HISTÓRICO DE LA COMPUTACIÓN …………………………...... 5 2.- SISTEMAS DE NUMERACIÓN .………………………………………………………...... 19 3.- REPRESENTACIÓN DE LA INFORMACIÓN ………………………………….............. 29 4.- DESCRIPCIÓN DE UNA COMPUTADORA ...…………………………………………... 45 5.- MÉTODO DE CASCADA ……………………………………………………..…………… 55 6.- ESTRUCTURA DE UN PROGRAMA, ENTRADAS, SALIDAS, ENUNCIADOS, ENUNCIADOS DE ASIGNACIÓN, VARIABLES Y CONSTANTES ..………………..….... 63 7.- LÓGICA PROPOSICIONAL …………………………...………..…………………...……. 87 8.- ESTRUCTURAS DE CONTROL Y CONDICIONES ……………………....…………… 99 9.- PROCEDIMIENTOS Y FUNCIONES, PASO DE PARÁMETROS, VARIABLES LOCALES Y VARIABLES GLOBALES …………………………………………………….. 123 10.- ¿QUÉ ES UN PROGRAMA?, ¿QUÉ ES PROGRAMAR?, MÉTODO DE IMPLEMENTACIÓN DE ALGORITMOS ITERATIVOS, PSEUDOCÓDIGO, REFINAMEITNOS SUCESIVOS Y CODIFICACIÓN ……………………………………... 137 11.- AREGLOS, CADENAS Y REGISTROS ……….……………………………………… 155 12.- MODO GRÁFICO .……………………………………………………………………..... 171 13.- ARCHIVOS ………..……………………………………………………………………… 185 14.- MÉTODOS DE DESCOMPOSICIÓN, DESARROLLO DESCENDENTE (TOP-DOWN) Y PROGRAMACIÓN MODULAR .………………………………………………................. 197 APÉNDICE A REGLAS DE INDENTADO ………………………….………………………. 203 APÉNDICE B MANEJO DE ERRORES EN PASCAL ……………………………………. 205 APÉNDICE C CREACION DE UNIDADES EN PASCAL ….…………………….……….. 207 BIBLIOGRAFÍA .……………………………………………………………………………….. 209

Page 4: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

4

Page 5: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

5

1.- BREBE RESUMEN HISTÓRICO DE LA COMPUTACION La primer sumadora de engranes de la que se tiene noticia la inventó en 1623 un profesor de hebreo, lenguas orientales, matemáticas, astronomía y geografía de la Universidad de Tübingen, Alemania y que en sus ratos libres fungía como ministro protestante llamado Wilheim Shickard (1592 – 1635). Su máquina estaba constituida por una serie de engranes y era capaz de realizar las cuatro operaciones básicas con números de seis dígitos, suma, resta, mutliplicación y división. Estaba basada en el método de los huesos de Napier y en un mecanismo de sumas parciales. Contaba con una campanita que sonaba cuando el resultado excedia de los seis dígitos. Se supo de esta máquina por las cartas que Schickard sonstuvo con Johanes Kepler. Ggracias a una hoja que se encontró el profesor Bruno, barón de Freytag-Löringhoff, profesor también de la Universidad de Tübinge, pudo hacer una replica del prototipo original. Note que en aquella época lo único con que se contaba para hacer máquinas era madera y metal.

Wilheim Schickard

Máquina de Schickard Imágenes bajadas de: http://encit.wz.cz/lidi/web/shickard_vedec.htm

Page 6: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

6

La segunda máquina de engranes de la que se tiene noticia es la diseñada y construida en 1640 por en matemático, físico, filósofo y teólogo francés Blas Pascal (1623 - 1662). Él diseñó y mandó construir esta máquina contando con tan solo diecinueve años de edad para ayudar a su padre Etienne, el cual era recaudador de impuestos, por lo que requería hacer gran cantidad de cálculos. Esta máquina estaba construida con engranes y únicamente podía realizar sumas. Él mandó construir la primera, pero al no gustarle el resultado se puso a estudiar mecánica para construirla él mismo. Produjo alrrededor de cincuenta copias y trató de comercializalas, pero desafortunadamente el invento no tuvo buena acojida, tal vez por que a veces se generaba un error en los acarreos. Actualmente hay dos versiones de ella, una se encuentra en el Museo Zwinger, en Dresden, Alemania y la otra se encuentra en el Museo de Artes y Oficios de París.

Blas Pascal Imagen bajada de: http://idcs0100.lib.iup.edu/scirev/SciRev_bpascal.html

Máquina de Engranes

Page 7: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

7

El tercer antecedente de la computadora fue un diseño que nunca llegó a construirse pero que mostraba ideas bastante interesantes. Charles Babbage (1791 - 1871) fue un matemático inglés que diseñó lo que él llamó máquina analítica. A esta máquina se le podía programar una función de cálculo, la cual, una vez programada era fácil pedirle que calculara la función de cualquier argumento que se le suministrara. Cada vez que fuera necesario calcular otra función sería necesario reprogramar la máquina.

Charles Babbage Imagen bajada de:

http://www-groups.dcs.stand.ac.uk/~history/Mathematicians/Babbage.html

Imagen bajada de la red

Page 8: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

8

Un concepto matemático que resultó ser de gran utilidad para el área de la computación fue la Máquina de Turing. Desde su juventud el matemático inglés Alan Mathison Turing (1912 - 1954) tuvo la inquietud de crear una máquina que incorporara inteligencia. Desde 1928 aproximadamente Turing estuvo trabajando con un problema llamado problema del paro o the halting problem en donde se requería saber si existían algoritmos que no terminaran en un tiempo finito. Para resolver este problema era necesaria una máquina abstracta en la que se pudieran hacer representaciones de la realidad a la que Turing llamó Máquina de Turing o Turing Machine (TM). Luego ideó otra máquina capaz de representar cualquier otra máquina incluyéndose a si misma a la que llamó Máquina Universal de Turing o Universal Turing Machine (UTM). Con el juego de dos Máquinas Universales, una codificada dentro de otra Turing resolvió el problema del paro y en 1936 demostró matemáticamente que existen procesos para los cuales no es posible decidir si terminarán o no en un tiempo finito, llamados procesos indecidibles.

Alan Mathison Turing Copiado del Libro Introducción a la Computación y a la Programación Estructurada

Guillermo Levine Gutierrez, Mc Graw Hill, 2ª Edición Este concepto resultó de un potencial inimaginado ya que conceptualmente en estas máquinas se podía representar cualquier aspecto de la realidad y cualquier proceso por complejo que este fuera, generando la pregunta filosófica ¿Es posible hacer

Page 9: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

9

representaciones completas de nuestro mundo o de nuestro universo? Estos temas han servido de simiente para películas de ciencia ficción como The Matrix. Turing fue solicitado para ayudar en el diseño de una máquina llamada "Bomba" que exploraba las combinaciones posibles generadas por la máquina codificadora alemana llamada "Enigma". La Bomba fue una máquina de propósito particular para descifrar códigos construida electromecánicamente con relés. Turing también trabajó en el desarrollo de la máquina llamada "Colossus" (que algunos consideran el primer ordenador electrónico) que ya funcionaba con válvulas electrónicas (tubos de vacío o bulbos) en lugar de relés; gracias a ella los británicos pudieron mantener alejados a los submarinos alemanes de los barcos de suministro que cruzaban el Atlántico. Turing tenía el interés de crear una máquina con la cual pudiera romper los códigos secretos a una mayor velocidad, lamentablemente nunca fue apoyado para materializar su idea, no obstante, sus trabajos sirvieron más adelante para desarrollar los lenguajes de programación y sentó las bases de la Teoría Matemática de la Computación y de la Inteligencia Artificial. Alan Turíng no recibió en vida, ni ha recibido reconocimiento alguno de la sociedad a la que tanto ayudó en los momentos más difíciles, la sociedad británica. Existe una controversia acerca de quién o quienes crearon la primer computadora electrónica de la história. Una versión dice que en 1947 un equipo dirigido por los ingenieros John Mauchly y John Eckert de la Universidad de Pennsylvania construyeron una máquina electrónica llamada o Electronic Numerical Integrator And Calculator (ENIAC) o Integrador y Calculador Numerico Electrónico en español, la cual trabajaba con tubos de vacío comúnmente llamados bulbos.

John Mauchly Imagen bajada de algún lugar de la red

Page 10: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

10

John Eckert

Imagen bajada de algún lugar de la red

Imagen bajada de:

http://www.seas.upenn.edu/~museum/

Esta máquina presentaba un severo inconveniente, los programas se tenían que alambrar en la memoria de programa por lo que un matemático húngaro llamado John von Neumann (1903 -1957) que se había integrado al equipo y que había sido colega de Turing propuso el siguiente cambio. En el nuevo modelo los programas podrían almacenarse como datos en la memoria de la computadora dando lugar al software (del inglés soft suave y ware losa) ya que se programaba de manera a la que ellos llamaron suave, y no con alambres. Esto dio lugar a otro término nuevo, el hardware (del inglés hard duro y ware losa) con el cual hacían referencia a los fierros de la máquina, es decir, a la parte material de la computadora. A partir de ese momento una computadora estuvo compuesta fundamentalmente de dos partes, el software y hardware. Por tal razón, a éste modelo se le dio su nombre, Modelo de von Neumann y es el modelo que aún siguen los diseãdores de las computadoras y es también por esto que es considerado el padre de las computadoras. A ésta nueva máquina se le dio el nombre de Electronic Discrete Variable Computer (EDVAC) o Computadora de Variable Discreta Electrónica en español.

Page 11: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

11

John von Neumann Copiado del Libro Introducción a la Computación y a la Programación Estructurada

Guillermo Levine Gutierrez, Mc Graw Hill, 2ª Edición

Jhon von Neumann junto a la EDVAC Imagen bajada de:

http://itminformaticabasica1.blogspot.mx/p/edvac-1944-1950.html

Page 12: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

12

Con la terminación de la segunda guerra mundial se vino el problema de como explotar comercialmente este logro, ya que la computadora resultó ser muy útil para almacenar, procesar y acceder grandes volúmenes de información. Las primeras aplicaciones comerciales fueron administrativas. En 1951 aparece la primer computadora comercial, la UNIVAC I (UNIVersAl Computer) de la empresa UNIVAC y más adelante la IBM (International Business Machines) que fue una empresa originalmente fundada por Herman Hollerith (1860-1929) el inventor de las tarjetas perforadas, entró al mercado produciendo la IBM 701. Posteriormente surgieron otras compañías que también entraron al mercado como Digital Equipment, Brroughs, Hewlett Packard, Control Data Computers, Honeywell, International Computers Limited, Siemens y otras más. Más adelante UNIVAC se uniria a Borroughs en tiempos de las fusiones de las empresas para formar UNISYS. La primer generación de computadoras trabajó con válvulas de vacío, conmuntmente llamados bulbos. Con el desarrollo de la tecnología, más adelante vino el advenimiento de los transistores que reemplazaron a los bulbos, dando lugar a la segunda generación de computadoras, las transistorizadas, las cuales se hicieron más pequeñas y eficientes. Después, los científicos integraron varios transistores en un solo pedazo de silicio dando lugar a la tercera generación de computadoras, la de los circuitos integrados. Y finalmente los diseñadores pudieron integrar un procesador completo en un solo pedazo de silicio aportando lo que hoy se conoce como microprocesador, dando lugar a la cuarta generación de computadoras. Todo esto ha hecho que actualmente una computadora no ocupe más que solo un pequeño espacio arriba de un escritorio a un costo accesible para un gran número de personas.

Page 13: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

13

Simultáneamente el área de software comenzó a tener importancia por sí misma y también se fue desarrollando. Primero se crearon programas que pudieran traducir los mnemónicos a su código correspondiente. Los mnemónicos son nombres que reciben las instrucciones que puede ejecutar un procesador. Ejemplo, el mnemónico de la operación “no operation” es “NOP”. A estos programas se les llamó ensambladores y por lo tanto al lenguaje que ensamblaban se le llamó ensamblador. Como había secciones de código que se repetían se crearon las macros. Las macros son secciones en código ensamblador que se insertan cada vez que se invocan y por lo tanto a los programas que ensamblaban el código se les llamó macro-ensambladores. Cada procesador que es fabricado debe contar con su macro-ensamblador. Aunque ya no se programa en ensamblador en lo general, aún así, cuando se requiere código super eficiente generalmente éste se programa en ensamblador. A finales de los 50's Jhon Backus lidereó un pequeño grupo de IBM que desarrolló el primer lenguaje de alto nivel que podía ser traducido a lenguaje de máquina, este lenguaje se llamó FORTRAN (Formula Translator) y su cualidad sorprendente era que los científicos podían ahora escribir sus formulas casi de la misma manera en la que escriben las expresiones en álgebra. Los físicos aún utlilizan este lenguaje, aunque utilizan un FORTRAN estructurado. En 1960 Jhon McCarty del Massachusetts Institute of Technology (MIT) crea Lisp (List Processor) en donde un programa se ve como una lista de funciones recursivas. Lisp es un lenguaje altamente abstracto. En cuanto a los Sistemas Operativos, anteriormente estos se programaban en ensamblador, esto era muy engorroso, así que comenzó la inquietud de crear lenguajes de alto nivel para programarlos. Un investigador de los laboratorios Bell en los Estados Unidos de Norteamérica llamado Ken Thomson se dio a la tarea de desarrollar un lenguaje de alto nivel pero que a su vez pudiera tener acceso a los registros de la computadora y diseñó y construyó el lenguaje al que él llamó “B” tomando muchas de las ideas de un lenguaje llamado BCPL desarrollado por Martin Richards. Con este lenguaje construyó el nucleo (kernel) de un sistema operativo de tiempo compartido (time shering) al que llamó Unix. La estrategía del tiempo compartido consiste en tener gran cantidad de procesos dados de alta en la computadora, todos ellos compartiendo el procesador. Como el procesador corre a gran velocidad, es posible asignarle a cada proceso una rebanada de tiempo. Como el procesador ejecuta el código a gran velocidad, los diferentes procesos solo perciben que su resolusión va en avance. Mas adelante perfeccionaron el lenguaje “B” diseñando el lenguaje “C” y reescribieron el código de Unix en “C”. En 1978 salió a la luz la publicación “El lenguaje de programación C” y desde entonces C ha sido uno de los lenguajes de programación más populares. Hay que reconocer que “C” es un lenguaje en el cual los archivos que lo constituyen tienen una estructura bien definida, el lenguaje es elegante y conserva su estilo, pero desafortunadamente es muy críptico y ha sido fuertemente criticado por su laxitud en el manejo de las diferentes representaciones de datos, esto es, un entero se puede guardar en una representación char sin que el compilador proteste creandose confución para quien lee el programa, además de que su compilador no es tan robusto en la detección y marcado de los errores. “C” y Unix rápidamente fueron tan exitosos que comensaron a

Page 14: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

14

ser utilizados por diferentes laboratorios y Universidades del planeta. Unix únicamente se puede utilizar bajo licencia. En 1983 un programador llamado Richard Stallman inició un movimiento llamado GNU el cual proponía la creacion de software que no tuviera derechos, lo inverso al copyrigh, llamándole software libre. A tal movimiento le llamo GNU el cual es un acrónimo recursivo que quiere decir GNU is Not Unix. El movimiento GNU creo Linux, el cual funciona exactamente igual que Unix. A principios de los 80's con la fabricación de procesadores en una pastilla, llamados microprocesadores, comenzaron a aparecer computadoras personales. Con esto, el sueño de que las personas pudieran tener una computadora en casa comenzó a hacerse realidad. Aparecieron en el mercado una serie de computadoras personales que tuvieron cierto éxito, como la la TRS-80 de Radio Shack y la Timex Sinclair basadas en el Z-80 de Zilog (microprocesador de 8 bits) y las famosas Apple y Comodore basadas en el 6502 de Motorota (también de 8 bits). Al darse cuenta IBM del nicho que se estaba abriendo decidió entrar a la competencia y sacó la Personal Computer (PC) basada en el 8088 de Intel, también de 8 bits, solo que se asoció con una compañía de software que se encargaría de elaborar el sistema operativo de la máquina. Ésta empresa fue nada más y nada menos que Microsoft, la cual desarrolló el sistema operativo MS-Dos que corre en las PC compatibles hasta la fecha. Microsoft pactó recibir los pagos por las licencias y es por esto que la empresa se ha hecho inmensamente rica. Con las ventanas la Xerox desarrolló una interfaz manual a la que llamó mouse (del inglés mouse ratón) la cual poco a poco comenzaron a utilizar para la interfaz gráfica de los sistemas operativos convirtiéndose en un instrumento estándar utilizado actualmente en las computadoras.

Posteriormente Apple desarrolló su sistema de ventanas siendo tan eficiente que Microsoft lo copió utilizándolo como interfaz gráfica del sistema operativo.

Poco después apareció el concepto de multimedia donde se buscaba aprovechar todos los sentidos posibles para establecer comunicación con la computadora. Multimedia consistía de aprovechar texto, imágenes y sonido. Esto hizo que se incluyera una tarjeta de sonido a la computadora como un elemento estándar.

En los 90's apareció el concepto de realidad virtual el cual consistía en crear ambientes virtuales en donde el usuario se sintiera inmerso en un ambiente artificial creado por la computadora dando lugar a la creación de algunos filmes como Matrix. Los simuladores crean ambientes de realidad virtual y está tecnología se ha empleado también para los juegos de computadora y dio origen al termino virtual que actualmente conocemos. Las computadoras se han convertido en parte fundamental de la vida de la humanidad ya que por su capacidad de ser reprogramadas pueden comportarse de

Page 15: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

15

diferentes maneras, pueden trabajar como procesadores de palabra, terminales remotas, simuladores, programas de entrenamiento, programas de cálculo, controladores de equipos mecánicos, instrumentos de medición, analizadores, procesadores, sintetizadores de imágenes, procesadores de texto, hojas de cálculo, bases de datos, y en fin, tantas aplicaciones como el hombre pueda concebir. Desde la década de los 80's las redes de computadora comenzaron a tomar auge ya que las empresas requerían hacer un uso más eficiente de sus recursos apareciendo diferentes topologías de red y diferentes marcas de redes como Novel y otras más. La Agencia de Proyectos Avanzados de Investigación de Defensa (Defence Advanced Research Projects Agency, DARPA) del Departamento de Defensa de los Estados Unidos propuso un proyecto para hacer un protocolo abierto y así poder interconectar máquinas de diferente marca. Este agencia propuso el Modelo OSI (Open Systems Interconection) que es un modelo de siete capas en donde la capa de transporte la maneja un protocolo de control, Transport Control Protocol (TCP) y la capa de enlace la maneja el protocolo de internet, Internet Protocol (IP).

No. De Capa Nombre Controla 7 Aplicación Aplicaciones y Servicios 6 Destino Estructura Información 5 Sesión Control de Dialogo 4 Transporte Rompe los Mensajes 3 Red Ruteo 2 Enlace de Datos Errores 1 Física Bits

Modelo OSI

El proyecto fue exitoso y la agencia invitó a algunas Universidades a conectarse a la red a la que llamaron Internet para compartir información útil para la investigación. Los servicios que proporcionaba la red eran transferencia de archivos, terminal virtual y correo electrónico.

Posteriormente apareció un navegador en modo texto llamado Mosaic. Más adelante Tim BernersLee creo el lenguaje de hipertexto HiperText Meta Language (HTML) el cual es un lenguaje para marcación de texto con el que se crearon páginas web y navegadores dando lugar a la World Wide Web (Red Amplia Mundial) o www como la conocemos actualmente.

Se creo un grupo para administrar la red y finalmente se permitió concesionar a empresas comerciales para dar servicios de Internet. A estos concesionarios se les llamó proveedores de servicios de Internet los cuales proporcionan conexiones, cuentas, mantenimiento de páginas Web, dominios y otros servicios.

Page 16: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

16

En la década de los 90's Netscape desarrolló el primer navegador en modo gráfico para la red llamado así, Netscape y posteriormente Microsoft entró a la competencia con Internet Explorer posicionándose como líder de los navegadores actualmente.

Esto ha hecho que el modem (modulador-demodulador) y las tarjetas de red se hayan convertido en otros de los dispositivos estándar de las computadoras.

También apareció una nueva área de inversiones dando lugar al un nuevo índice de cotizaciones de compañías de software llamado NASDAQ. Con el advenimiento de las redes de computadoras estas están sirviendo no solo para aplicaciones tradicionales, sino también como medio de comunicación masiva en el mundo, de tal manera que es posible comunicarse a cualquier parte del mundo, correr programas desde lugares remotos, transferir archivos, publicitar bienes y servicios, información social y gubernamental, oír estaciones de radio, compartir música, etc. Todo esto está revolucionando al mundo haciendo que el mundo sea cada vez más pequeño en el sentido del acceso y el alcance de la información, por lo tanto actualmente las computadoras no solo sirven como herramientas de cálculo, sino también como herramientas para profesionistas, la oficina, el hogar y para conectarse al mundo.

Page 17: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

17

CUESTIONARIO CAPÍTULO 1 Fecha de entrega: ______________

Nombre (comenzando por el apellido): ________________________________________

1.- ¿Cuales son las máquinas físicas que antecedieron la creación de la computadora? __

_______________________________________________________________________

_______________________________________________________________________

______________________________________________________________________

_______________________________________________________________________

2.- ¿Quién sentó las bases de la teoría matemática de la computación? ______________

_______________________________________________________________________

3.- ¿Cuando, donde y quienes fabricaron la primera computadora de la historia? _______

_______________________________________________________________________

______________________________________________________________________

_______________________________________________________________________

4.- ¿Qué nombre le dieron a ésta máquina y cual era su desventaja? ________________

______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

5.- ¿Cual es el nombre del matemático húngaro que propuso un modelo en donde los

programas se manejan como datos? __________________________________________

6.- ¿Qué nombre recibió éste nuevo modelo? ___________________________________

_______________________________________________________________________

7.- ¿Cual es el nombre de la empresa que comenzó a comercializar este hallazgo

científico? _______________________________________________________________

8.- ¿Cuales fueron las etapas de evolución de las computadoras en cuanto a

componentes? ___________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

Page 18: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

18

9.- Liste cinco usos que se les puede dar a las computadoras: ______________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

10.- ¿Cual es la empresa que desarrolló el sistema operativo para las PC's de IBM?

_______________________________________________________________________

11.- ¿Cual es el nombre de la empresa que fabricó el primer navegador en modo gráfico

que apareció en la red? ____________________________________________________

Page 19: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

19

2.- SISTEMAS DE NUMERACIÓN

Para que la computadora pudiera manejar la información fue necesario inventar una manera de representarla físicamente. Las computadoras pueden almacenar información en forma de voltajes. Un capacitor cargado proporciona un voltaje, y uno descargado no. Los voltajes con los que trabajan las computadoras normalmente son 5 y 0 volts. Como los sistemas de numeración trabajan con símbolos y no con voltajes se le asignó por convención al voltaje de 5 volts el símbolo "1" y al voltaje de 0 volts el símbolo "0". Se hace la aclaración de que se habla de símbolos y no de números ya que como veremos más adelante los sistemas de numeración se construyen con símbolos y no con números, se forman números con los símbolos y los sistemas de numeración.

Un símbolo tiene cierto valor dependiendo de la base del sistema de numeración que se esté manejando. Un símbolo es cualquier grafo bien definido. Para valores lógicos se asignó, también por convención, "verdadero" a "1" y "falso" a "0". A la celda que puede tomar valores de "0" ó "1" se le llama bit que quiere decir dígito binario. Ahora vamos a tratar los sistemas de numeración. Formemos el sistema de numeración más simple. El sistema de numeración más simple es el que utiliza dos símbolos, a éste sistema se le llama binario. Obviamente los dos símbolos que se utilizarán son el "0" y el "1".

Construyamos los primeros números binarios.

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1001 1010 1011 1100 1101 1110 1111

Observe que la primera columna varía de uno en uno, la segunda de dos en dos, la tercera de cuatro en cuatro y así sucesivamente.

Page 20: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

20

Para encontrar el correspondiente decimal de cualquier número de cualquier base se hace lo siguiente: Cada columna corresponde a un orden, el peso de cada columna se encuentra elevando la base del sistema numérico al número de columna. El número de columna comienza por el lado derecho y tiene el valor 0. O sea, para el sistema binario tendríamos:

2n……… 24 23 22 21 20

con

20 = 1 21 = 2 22 = 4 23 = 8

24 = 16 . .

Por lo tanto el número 01100112 equivale a:

1 x 20 + 1 x 21 + 1 x 24 + 1 x 25 = 1 + 2 + 16 + 32 = 5110 La base de un sistema de numeración es el número de símbolos con los que él cuenta y se escribe como subíndice después de la cadena de símbolos. El sistema decimal presenta muchas características que facilitan la manipulación de los números y por esto se ha escogido como el estándar para los humanos aunque cabe mencionar que no todas las culturas han utilizado el sistema base diez o decimal. Ya que éste es el estándar se omite escribir la base por obviedad pero estrictamente hablando debería de escribirse. El siguiente sistema que nos interesa es el octal. Este sistema está formado por ocho símbolos. Así tendríamos:

0 1 2 3 4 5 6 7

10 11

Page 21: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

21

12 . .

Por lo tanto el número 235748 equivale a:

4 x 80 + 7 x 81 + 5 x 82 + 3 x 83 + 2 x 84 = 4 + 56 + 320 + 1536 + 8192 = 1010810 con

80 = 1 81 = 8

82 = 64 83 = 512

84 = 4096 . .

El siguiente sistema en importancia es el decimal y es con el que estamos más familiarizados y la conversión es inmediata. El último sistema que veremos es el hexadecimal y consta de dieciséis símbolos. Es claro ver que si los símbolos usados en los sistemas de numeración son diez nos harán falta seis símbolos. Estos símbolos los tomaremos de las letras bajo la siguiente tabla:

Símbolo Decimal A 10 B 11 C 12 D 13 E 14 F 15

Así el número 1C5B16 es:

1 x 163 + 12 x 162 + 5 x 161 + 11 x 160 = 7,25910

con 160 = 1

161 = 16 162 = 256

163 = 4096 164 = 65536

.

.

Page 22: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

22

ya que B es una forma de simbolizar a 1110 y C a 1210 de acuerdo a la tabla anterior. Si se agrupan los bits en grupos de tres es fácil convertir un número binario en octal. Para facilitar las conversiones construiremos una tabla de los primeros dieciséis números en los cuatro sistemas numéricos.

Binario Octal Decimal Hexadecimal 0000 0 0 0 0001 1 1 1 0010 2 2 2 0011 3 3 3 0100 4 4 4 0101 5 5 5 0110 6 6 6 0111 7 7 7 1000 10 8 8 1001 11 9 9 1010 12 10 A 1011 13 11 B 1100 14 12 C 1101 15 13 D 1110 16 14 E 1111 17 15 F

Tabla de los primeros dieciséis números en los cuatro sistemas numéricos Agrupando bits es fácil pasar de binario a cualquier sistema de numeración cuya base sea una potencia de 2, en este caso octal y hexadecimal. Para pasar de binario a octal únicamente es necesario agrupar de tres en tres bits y usar la tabla anterior. Para pasar de binario a hexadecimal únicamente es necesario agrupar de cuatro en cuatro bits. Ejemplo: El número 1011011001112 101 101 100 111 en octal es: 5 5 4 78 1011 0110 0111 en hexadecimal es: B 6 716 Ahora, si queremos pasar un número en decimal a una base dada lo único que tenemos que hacer es dividir el número entre la base dada tantas veces como se pueda hasta que el siguiente cociente ya no se pueda dividir. Los residuos darán los factores en orden inverso al que vayan apareciendo, y el último factor lo dará el último cociente.

Page 23: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

23

Ejemplo: se desea convertir el siguiente número en decimal a hexadecimal

423510 Lo primero que tenemos que hacer es dividir subsecuentemente el número entre la base a la que lo queremos convertir, en éste caso 16, por lo tanto tendríamos:

__264_ 16 | 4235 103 75

11

_16_ 16 | 264 8

_1_ 16 | 16

0 _ 0_ 16 | 1 1 Por lo tanto tenemos que 423510 equivale a 108B16 De esta forma podemos tener números en una determinada base y pasarlos a otra base si así nos conviene. Otro método para pasar un número decimal a binario consiste en poner una línea y dividir el número en dos poniendo el residuo del lado derecho y el cociente en la parte baja. Esto se repite hasta que el cociente sea cero, el número en binario es el número en secuencia inversa en la que apareció, ejemplo:

Page 24: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

24

213 | 106 | 1 53 | 0 26 | 1 13 | 0 6 | 1 3 | 0 1 | 1 0 | 1

Por lo tanto el número 21310 es 110101012

A continuación se muestran cuatro gráficas donde se muestra cual es el método más adecuado para pasar de un sistema a otro. Note que no hay una sola manera de pasar de un sistema a otro, es posible utilizar dos métodos en cascada, también es posible regresar al mismo número por el camino inverso o por otro camino.

Page 25: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

25

Page 26: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

26

Page 27: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

27

EJERCICIOS CAPÍTULO 2 Fecha de entrega: ___________

Nombre (comenzando por el apellido): ________________________________________

La calificación se calcula sobre el número total de respuestas, en este caso, 30.

Agregue las operaciones en la parte de atrás.

1.- Utilizando el método de suma de potencias convierta los siguientes números de

binario, octal y hexadecimal a decimal:

11001002 _______________10 17508 _____________10 271016 ________________10

2.- Utilizando el método de divisiones sucesivas convierta los siguientes números de

decimal a binario, octal y hexadecimal:

17010 ___________________2 409510 _______________8 274810 _________________________16

3.- Utilizando el método de agrupamiento convierta los siguientes números al sistema de

numeración octal y hexadecimal.

________________8 _________________8 _________________8

1100112 10100112 1111111112

________________16 _________________16 _________________16

4.- Utilizando el método de desagrupamiento convierta los siguientes números al sistema

de numeración binario.

208 3148 7078

_______________________2 ___________________2 ____________________2

1C716 AA16 3E16

______________________2 ____________________2 ____________________2

Page 28: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

28

5. – Utilizando el método de divisiones sucesivas convierta los siguientes números a

hexadecimal, binario y octal.

17010 18710 327610

______________________16 ___________________16 ___________________16

______________________2 ___________________2 ____________________2

______________________8 ___________________8 ____________________8

6.- Utilzando el método de suma de potencias convierta los siguiente números de binario,

octal y hexadecimal a decimal:

11000112 _______________10 17478 _____________10 270F16 _________________10

Page 29: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

29

3.- REPRESENTACIÓN DE LA INFORMACIÓN Como comentábamos, la información en la computadora se almacena en bits por lo que fue necesario establecer una forma de representar los números dentro de ella. En un principio cada fabricante decidía como iba a representar los números, pero con el paso del tiempo se adoptó un estándar. NÚMEROS ENTEROS Los números que son más fáciles de representar en una computadora son los números enteros ya que para su almacenaje y su recuperación los procedimientos son sencillos. Es imposible representar en la computadora al conjunto infinito de números, ya que para esto se requeriría una memoria infinita, además no todos los números son usados, por lo que acortando el intervalo se puede tener una representación bastante útil. La representación del signo se puede hacer tomando el primer bit a la izquierda como el signo, un 0 representa un signo positivo y un 1 representa un signo negativo. El número de bytes razonable para un buen intervalo es de 16. Un byte está constituido por ocho bits. Por lo tanto, un número entero está representado generalmente por dos bytes. El intervalo de números que podemos representar con dieciséis bits es [+32,767, -32,767] pasando por el 0. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 214+213+212+210+29+28+27+26+25+24+23+22+21+20 = 32,767 y como el signo es positivo, entonces este número en binario representa al +32,767. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = +0 Los números negativos se almacenan en su representación de complemento a 2 (‘2). 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 = -32,767 Es importante hacer ver al lector que cada vez que ingresa un número a la computadora entra a una memoria donde una vez capturado como cadena de símbolos se procesa para ser almacenado en forma binaria y cada vez que se desea ver un número en la pantalla la computadora tiene que hacer el proceso inverso para mostrarlo

Page 30: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

30

como una cadena de símbolos. Las operaciones aritméticas dentro de la computadora se realizan en binario. Normalmente la memoria de las computadoras está organizada en secuencias de bytes. Cada vez que se reserva espacio para un número se almacena en una tabla la dirección de comienzo del número por lo que la computadora puede saber donde comienza este en todo momento solo con consultar la tabla. Si el número abarca varios bytes la lectura se puede hacer por secciones. El tamaño de la sección lo da la longitud del canal de datos, si este es de 16 bits cada sección será de 16 bits, si es de 32, cada sección será de 32 bits y así sucesivamente. Esto se hace para que la lectura de un número se haga con el menor número de accesos a memoria posibles. A la longitud del canal de datos de le llama longitud de palabra (word). NÚMEROS EN REPRESENTACIÓN DE FUNTO FLOTANTE Ya vimos como se representan los números enteros, pero resulta que hay problemas en donde se manejan escalas mayores que las anteriores o decimales. La solución a éste problema son los números en notación científica o de punto flotante. Éstos constan de dos partes, una que es la mantisa y otra que es el exponente. El exponente se representa con un número entero y la mantisa con un número fraccionario en donde el punto es imaginario y se representa a su lado izquierdo. En Pascal a la mantisa se le da una longitud de 42 bits, lo cual nos da aproximadamente 12 cifras significativas y al exponente, como normalmente no es excesivamente grande, se le da una longitud de seis bits, de tal forma que el espacio para representar un número en punto flotante son generalmente 48 bits o sea 6 bytes. Las cifras significativas es una manera de medir la presición de un número. En un cálculo se pueden requerir cierto número de cifras significativas, es decir, debe ser posibloe confiar en esas cifras en un resultado. Por ejemplo 3.1416 consta de cinco cifras significativas. Entre más cifras se requieren el cálculo y el almacenamiento serán más costosos. Con ésta representación podremos representar números de 0.000000000001 X 10 -32 a 0.999999999999 X 10+32 aproximadamente, aunque el procedimiento ReadLn de TurboPascal permite números de 1.000000 x 10-38 a 1.000000 x 10+38. En TurboPascal el formato para ingresar un número en notación científica es: 1.000000e-38 a 1.000000e38 y las cifras significativas que proporciona que proporciona el Write son once en lugar de doce (aunque internamente son doce), esto se hace para que no se vea el redondeo de la última cifra o para que no se confie en la doceava cifra por seguridad. Por ejemplo si en TurboPascal se le da siguiente entrada a un entero: 1e-38 y después se despliega la variable y el valor será: 1.0000000000E-38

Page 31: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

31

y si se da la siguiente entrada: 1e38 el valor que se despliega será: 1.0000000000E38 con la entrada: 0.555555555555 (12 5’s) el valor que se despliega será: 5.5555555555E-1 (11 5’s) pero si la entrada es: 0.5555555555555 (13 5’s) el valor que se despliega será: 5.55555555556E-1 (11 5’s y un 6’s) Observe que cuando se ingresan 13 cifras significativas se efectúa un redondeo a 12 cifras significativas a la hora de almacenar el dato, claro que a la hora de desplegar el dato este redondeo se hará evidente.

Por lo tanto se puede ver que el procedimiento de entrada y el procedimiento de salida hacen una transformación a la información representada en memoria, primero para poder almacenarla en la representación dada y luego para que se pueda ver de la forma más útil para el usuario. En general la forma de medir la precisión de los cálculos se hace a través de cifras significativas. Las cifras significativas que se alcanzan con una representación está dada en base a los órdenes de magnitud completos en decimal que cubre la representación. Ejemplo: con un bit no cubrimos ni siquiera un orden de magnitud ya que el número de combinaciones que tendíamos es dos, "0" y "1". Con dos bits ya tenemos cuatro combinaciones pero todavía no cubrimos un orden, para cubrir un orden necesitamos rebasar una potencia de 10. Con tres bits tenemos ocho combinaciones por lo que todavía no alcanzamos un orden de magnitud.

Page 32: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

32

Con cuatro bits ya tenemos 16 combinaciones y como ya rebasamos la primera potencia de diez, es decir, 101 ya podemos representar un orden, aunque nos sobrarán seis combinaciones, lo que quiere decir que con cuatro bits en realidad podemos representar poco más de un orden de magnitud. Debido a que las potencias en binario no coinciden con las potencias de diez las representaciones con cierto número de bits no representan órdenes de magnitud cerrados en decimal por lo que los órdenes sólo nos dan un parámetro cualitativo para medir la precisión de una determinada representación. Así, existen dos formas de evaluar una representación, una es por el intervalo de los números representados y otra por las cifras significativas o los ordenes de magnitud cubiertos. Proporcionamos la siguiente tabla la cual ayuda a encontrar los órdenes de magnitud que se pueden representar con cierto número de bits.

Page 33: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

33

Número de bits Número de combinaciones

1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512

10 1024 11 2048 12 4096 13 8192 14 ~16K 15 ~32K 16 ~64K 17 ~128K 18 ~256K 19 ~512K 20 ~1M 21 ~2M 22 ~4M 23 ~8M 24 ~16M 25 ~32M 26 ~64M 27 ~128M 28 ~256M 29 ~512M 30 ~1KM 31 ~2KM 32 ~4KM 33 ~8KM 34 ~16KM 35 ~32KM 36 ~64KM 37 ~128KM 38 ~256KM 39 ~512KM 40 ~1MM 41 ~2MM 42 ~4MM

Page 34: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

34

Observe que cada diez bits el número de combinaciones crece en tres órdenes de magnitud. Se puede obtener la siguiente tabla:

Número de Bits Ordenes de magnitud 10 3 20 6 30 9 40 12

Por lo tanto con el número de bits se puede obtener el número de ordenes de magnitud de los números representados dándonos ésto un estimado de la precisión que vamos a obtener. La representación de los números negativos se hace generalmente con el complemento a dos ('2). Esta representación tiene la cualidad de que la suma funciona no importando si algún número o los dos son negativos. Para ilustrar cómo se obtiene el complemento a dos de un número primero mostraremos como obtener el complemento a uno ('1). Para obtener el complemento a uno lo único que hay que hacer es cambiar los 1's por 0's y viceversa, ejemplo: El complemento a 1 de: 01100110 +102 es: 10011001 El complemento a 2 se obtiene sumándole 1 al complemento a 1, ejemplo: 10011001 + 00000001 10011010 -102 Para mostrar que son opuestos en signo los números los sumamos y obtenemos: 01100110 +102 + 10011010 + -102 100000000 0 el primer 1 no se toma en cuenta. Un truco para obtener el complemento a dos de un número es dejar los primeros ceros a la derecha del número iguales, dejar el primer 1 igual y cambiar los símbolos restantes a la izquierda por su complemento, ejemplo: 00110100 +52 11001100 -52

Page 35: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

35

Esto se puede extender a números de n bytes. La mantisa se representa con números fraccionarios. Ejemplo: Supongamos que tenemos una mantisa de 8 bits S 2-1 2-2 2-3 2-4 2-5 2-6 2-7

0 1 0 0 0 0 0 0 representa 1 x 2 -1 = ½ = 0.5 S 2-1 2-2 2-3 2-4 2-5 2-6 2-7

0 1 1 0 0 0 0 0 representa 1 x 2 -1 + 1 x 2 -2 = ½ + 1/4= 0.5 + 0.25 = 0.75 S 2-1 2-2 2-3 2-4 2-5 2-6 2-7

0 1 0 1 0 0 0 0 representa 1 x 2 -1 + 1 x 2 -3 = ½ + 1/8= 0.5 + 0.125 = 0.625 de tal manera que es posible aproximar un número con fracciones de potencias de dos. Es claro que habrá números que sean exactos, pero habrá números que no. Si un número es la suma de algunas o todas las fracciones se representará exacto, de otra forma se hará una aproximación. Con 42 bits la aproximación será funcional. CARACTERES ALFANUMÉRICOS Con estas dos representaciones cubrimos lo fundamental en cuanto a números, pero queda un problema pendiente ¿Cómo manejar símbolos alfanuméricos en una computadora? Éste problema se resolvió asignando un número binario a un símbolo alfanumérico. En un principio también cada fabricante diseñó su tabla de símbolos, pero esto tenía un gran problema, que un archivo alfanumérico creado en una computadora de un fabricante x no podía ser leído en otra computadora de un fabricante y. Esto generó que se trabajara en un estándar para que los archivos pudieran ser leídos independientemente del fabricante de la computadora. Así es como nació el código ASCII (American Standard Code for Information Interchange). Los códigos también requieren caracteres de control que son caracteres invisibles, estos son para el manejo de la pantalla y para protocolos de comunicación. En un principio el código únicamente contaba con siete bits, pero dado que es más práctico utilizar ocho se creó el ASCII extendido que consta de 8 bits con 255 símbolos y carácter es de control. La tabla del código ASCII extendido es la siguiente: Decimal Hexadecimal ASCII 0 0 NULL null

Page 36: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

36

1 1 SOH start of heading 2 2 STX start of text 3 3 ETX end of text 4 4 EOT end of transmission 5 5 ENQ enquiry solicitud de envío 6 6 ACK acknoledge reconocimiento 7 7 BELL bell campana 8 8 BS backspace retroceso 9 9 HT horizontal tab tabulador horozpntal 10 A LF line feed salto de línea 11 B VT vertical tab tabulador vertical 12 C FF form feed nueva página 13 D CR cariage return regreso de carro 14 E SO shift out 15 F SI shift in 16 10 DLE data link escape 17 11 DC1 device control 1 18 12 DC2 device control 2 19 13 DC3 device control 3 20 14 DC4 device control 4 21 15 NAK negative acknowledge 22 16 SYN synchronous idle 23 17 ETB end of trans. block 24 18 CAN cancel 25 19 EM end of medium 26 1A SUB substitute 27 1B ESC escape escape 28 1C FS file separator 29 1D GS group separator 30 1E RS record separator 31 1F US unit separator 32 20 SPACE espacio 33 21 ! 34 22 " 35 23 # 36 24 $ 37 25 % 38 26 & 39 27 ' 40 28 ( 41 29 ) 42 2A * 43 2B + 44 2C , 45 2D - 46 2E . 47 2F /

Page 37: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

37

48 30 0 49 31 1 50 32 2 51 33 3 52 34 4 53 35 5 54 36 6 55 37 7 56 38 8 57 39 9 68 3A : 69 3B ; 60 3C < 61 3D = 62 3E > 63 3F ? 64 40 @ 65 41 A 66 42 B 67 43 C 78 44 D 79 45 E 70 46 F 71 47 G 72 48 H 73 49 I 74 4A J 75 4B K 76 4C L 77 4D M 78 4E N 79 4F O 80 50 P 81 51 Q 82 52 R 83 53 S 84 54 T 85 55 U 86 56 V 87 57 W 88 58 X 89 59 Y 90 5A Z 91 5B [ 92 5C \ 93 5D ] 94 5E ^

Page 38: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

38

95 5F _ 96 60 ` 97 61 a 98 62 b 99 63 c 100 64 d 101 65 e 102 66 f 103 67 g 104 68 h 105 69 i 106 6A j 107 6B k 108 6C l 109 6D m 110 6E n 111 6F o 112 60 p 113 71 q 114 72 r 115 73 s 116 74 t 117 75 u 118 76 v 119 77 w 120 78 x 121 79 y 122 7A z 123 7B { 124 7C | 125 7D } 126 7E ~ 127 7F DEL 128 80 Ç 129 81 ü 130 82 é 131 83 â 132 84 ä 133 85 à 134 86 å 135 87 ç 136 88 ê 137 89 ë 138 8A è 139 8B ï 140 8C î 141 8D ì

Page 39: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

39

142 8E Ä 143 8F Å 144 90 É 145 91 æ 146 92 Æ 147 93 ô 148 94 ö 149 95 ò 150 96 û 151 97 ù 152 98 ÿ 153 99 Ö 154 9A Ü 155 9B ø 156 9C £ 157 9D Ø 158 9E × 159 9F ƒ 160 A0 á 161 A1 í 162 A2 ó 163 A3 ú 164 A4 ñ 165 A5 Ñ 166 A6 ª 167 A7 º 168 A8 ¿ 169 A9 ® 170 AA Ñ 171 AB ½ 172 AC ¼ 173 AD ¡ 174 AE « 175 AF » 176 B0 177 B1 178 B2 179 B3 180 B4 181 B5 Á 182 B6 Â 183 B7 À 184 B8 © 185 B9 186 BA 187 BB 188 BC

Page 40: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

40

189 BD ¢ 190 BE ¥ 191 BF 192 C0 193 C1 194 C2 195 C3 196 C4 197 C5 198 C6 ã 199 C7 Ã 200 C8 201 C9 202 CA 203 CB 204 CC 205 CD 206 CE 207 CF ¤ 208 D0 ð 209 D1 Ð 210 D2 Ê 211 D3 Ë 212 D4 È 213 D5 i 214 D6 Í 215 D7 Î 216 D8 Ï 217 D9 218 DA 219 DB 220 DC 221 DD 222 DE 223 DF 224 E0 Ó 225 E1 ß 226 E2 Ô 227 E3 Ò 228 E4 õ 229 E5 Õ 230 E6 é 231 E7 þ 232 E8 Þ 233 E9 Ú 234 EA Û 235 EB Ù

Page 41: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

41

236 EC ý 237 DE Ý 238 EE ¯ 239 FF ´ 240 F0 231 F1 ± 232 F2 243 F3 ¾ 244 F4 245 F5 § 246 F6 ÷ 247 F7 ¸ 248 F8 ° 249 F9 ¨ 250 FA · 241 FB ¹ 242 FC ³ 253 FD ² 254 FE 255 FF Hay algunos símbolos que varían de acuerdo al monitor. De ésta forma también se pueden almacenar cadenas de símbolos alfanuméricos como los de este texto en forma de números. De hecho, este archivo está codificado en código ASCII. Al final de cada línea hay un Car Return (Regreso de Carro) invisible y al final del archivo hay un End of Text (Fin de Texto) invisible también. Lo único que se necesita es ser consistente en la interpretación de la información que contiene un archivo. Si ese archivo contiene caracteres alfanuméricos esté se debe recuperar utilizando la tabla de código ASCII y si el archivo contiene números estos se deben recuperar utilizando los procedimientos para recuperar números. Existe un cuarto tipo de dato básico, el Booleano. En algunos lenguajes no aparece explícitamente como en el lenguaje C aunque se puede implementar con variables enteras que toman sólo dos valores 1 y 0 y son llamadas comúnmente banderas. Se le da este nombre ya que viene de la lógica de Boole y que solo puede tomar dos valores, o "falso" o "verdadero". De está forma es como se pueden representar y almacenar en la computadora los cuatro tipos de datos básicos, enteros, reales o flotantes, caracter y booleanos. En Pascal existe un quinto tipo de dato, el String, que consiste en ser un arreglo de caracteres. En C se crea un arreglo de caracteres para manejar cadenas.

Page 42: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

42

Page 43: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

43

EJERCICIOS CAPÍTULO 3 Fecha de entrega: ______________ Nombre (comenzando por el apellido): ________________________________________

La calificación se calcula sobre el número total de respuestas, en este caso, 30.

1.- ¿Qué intervalo de números se puede representar con ocho bits y en donde uno es

para el signo? ____________________________________________________________

2.- ¿Qué intervalo de números se puede representar dieciseis bits y en donde un bit es

para el signo? ____________________________________________________________

3.- ¿Cuántas cifras significativas se logran con una mantisa de cinco bits y en donde un

bit es para el signo? _______________________________________________________

4.- ¿Cuántas cifras significativas se logran con una mantisa de ocho bits y en conde un bit

es para el signo? _________________________________________________________

5.- ¿Cuántas cifras significativas se logran con una mantisa de dos bytes en donde un bit

es el signo? Recuerde que dos bytes son dieciseis bits. ___________________________

6.- ¿Cuántas cifras significativas se logran con una mantisa de cuatro bytes en donde un

bit es para signo? ________________________________________________________

7.- ¿Cuántas cifras significativas se logran con una mantisa de 42 bits en donde un bit es

para el signo? ____________________________________________________________

8.- Escriba el número en representación entera con signo al que corresponden los

siguientes números:

010100112 001111012 010011102 010101012 011111112

________10 ________10 ________10 ________10 _________10

9.- Escriba su complemento a 1(1’):

________ ________ ________ _________ _________

10.- Escriba su complemento a 2 (2’):

_________ _________ _______ ________ _________

11.- Escriba el correspondiente en decimal con signo de los números anteriores en

representación 2’ con signo:

________10 _______10 ________10 ________10 ________10

12.- ¿Qué pasa si se le saca el complemento a 2 dos veces a un número? ____________

_______________________________________________________________________

_______________________________________________________________________

Page 44: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

44

13.- Escribir la cadena "hola mundo" en código ASCII en hexadecimal:

h o l a m u n d O

14.- Escriba la cadena de su nombre de pila en código ASCII en hexadecimal:

Page 45: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

45

4.- DESCRIPCIÓN DE UNA COMPUTADORA Es posible hacer la descripción de una computadora desde dos puntos de vista, el punto de vista físico y el punto de vista lógico. DESCRIPCIÓN FÍSICA

Desde el punto de vista físico una computadora está formada básicamente de tres partes: a) El procesador b) La memoria c) Puertos de Entrada/Salida Estas tres partes interactúan como una pequeña ciudad en donde la memoria funciona como un almacén de datos, el procesador toma datos de la memoria, los procesa y regresa los resultados y finalmente los puertos de entrada/salida (input/output) a través de los cuales la información entra y sale de la computadora. Para que los datos puedan viajar dentro de la ciudad es necesario crear autopistas para que los datos viajen. Esta autopista para los datos se conoce como canal de datos (Data Bus) donde los datos se suben para viajar a través de él. Para saber a que dirección se requiere acceder se utiliza un canal llamado canal de direcciones (Address Bus) a través del cual el microprocesador direcciona el registro que desea acceder. Para que los datos sean aportados a los canales se utilizan una serie de líneas de control que le indican a los diferentes componentes cuando deben aportar su dato al canal, y a los que lo van a recibir, cuando deben hacer la captura del dato. Las dos líneas más importantes de este canal son habilita salida (Output Enable o OE) y habilita captura (Latch Enable o LE) las cuales llegan a la mayoría de los componentes. Estas líneas salen de la Unidad de Control, la cual está dentro del procesador Dentro del procesador se encuentran los registros auxiliares, los cuales sirven como almacenamiento temporal de la información. Además de registros, dentro del procesador se encuentra una Unidad Aritmética Lógica (Arinmetic Logic Unit o ALU) a través de la cual el procesador es capaz de realizar operaciones aritméticas tales como sumas y restas, y lógicas tales como “and”, “or”, “not” entre los bits de los los registros. El único lenguaje que reconoce el procesador es el código de máquina, el cual consiste en un código asignado a cada operación seguido opcionalmente de operandos. Cada código tiene su correspondiente mnemónico el cual es un nombre con letras que sirve para manejar la operación en una forma más práctica. Ejemplos de mnemónicos son las operaciones ADD que suma el acumulador con otro registro y el operador SUB que realiza la resta. Normalmente todo procesador tiene un registro Acumulador el cual

Page 46: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

46

normalmente sirve como fuente y destino de las operaciones aritméticas y lógicas. Después de ejecutar la operación, el resultado, el cual queda en el acumulador, se envía a memoria. Es posible programar en lenguaje ensamblador, es decir con mnemónicos, y después convertirlo a código de máquina con un programa llamado macroensamblador (macroassembler) pero esto implica la dificultad de hacer programas muy difíciles de comprender y de verificar, aunque ciertas secciones de los sistemas operativos es necesario programarlas en ensamblador o para los segmentos de código en los que traducen las instrucciones de alto nivel los programadores primero las programan en ensamblador, de hecho, cada que se fabrica un procesador también se tiene que elaborar su macroensamblador. En lugar de ésto, se utilizan lenguajes de programación de alto nivel donde se puede programar a un mayor nivel conceptual sin preocuparse del manejo interno de memoria y de los registros. El manejo de memoria quedará a cargo del manejador de memoria del sistema operativo, de tal manera que al programar en un lenguaje de alto nivel no es necesario saber que espacios de memoria ya están asignados, cuales no y donde se encuentran. El sistema operativo se hará cargo de la administración de la memoria durante todo el tiempo, incluso cuando estemos corriendo un programa. El manejar lenguaje de alto nivel también hace posible manejos repetitivos de secuencias de código prefabricado de tal manera que para un tipo de instrucción de alto nivel habrá una secuencia de código de máquina que cada vez que se utilice esa instrucción lo único que se hará es agregar ese segmento de código al programa. Ejemplos de estos códigos son el código de las instrucciones Read y Write. De esta manera, es posible programar en un lenguaje de alto nivel y traducirlo a código de máquina. El código que se genera en un lenguaje de alto nivel se conoce como código fuente. Un compilador es un programa que traduce el código fuente a código de máquina. En realidad lo único que hace un compilador es reconocer si la secuencia de código fuente pertenece al lenguaje generado por una gramática dada, pero de paso se genera el código de máquina o ejecutable. Cuando se tienen programas muy grandes estos se compilan por módulos. El resultado de la compilación de estos módulos es codigo objeto. El código objeto es un código que ya está compilado pero no está ligado con los otros segmentos. Cuando se compila un programa que invoca procedimientos de librerías se liga el código de los módulos con el del programa principal produciendo finalmente el código ejecutable. Entonces, el proceso para la elaboración de un programa es editar el código fuente en un lenguaje de alto nivel, compilarlo y obtener el código ejecutable. Para obtener código ejecutable es necesario ligar (link) los segmentos de código objeto que se generaron, esto lo hacen automáticamente las herramientas de programación después de que el programa ya no tiene errores sintácticos. El lector se podrá preguntar ¿Y qué pasa con el teclado, el monitor y las unidades de disco? Todas estas son accedidas a través de puertos. Internamente para la computadora es lo mismo un monitor que una impresora, ya que las dos son salidas, lo

Page 47: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

47

único que varía son los programas que controlan las diferentes salidas de la computadora. Ya que la transferencia de información puerto-memoria es muy lenta puesto que los datos tenían que pasar forzosamente por el procesador, se ideó un sistema llamado de Acceso Directo a Memoria (Direct Memory Address o DMA) el cual puede hacerse cargo momentáneamente de los canales pasando directamente los datos de los puertos a la memoria y viceversa. Éste DMA está bajo el control del procesador y cuando está transfiriendo datos, el procesador no puede hacer uso de los canales. El DMA no es utilizado en arquitecturas en donde los puertos están mapeados en memoria como es el caso de las PC's. Se ha dado en llamar CPU (Central Processing Unit o CPU) a la caja que contiene la tarjeta madre (Mother Board) y las unidades de disco, pero en realidad el CPU está adentro y es únicamente el procesador o actualmente llamado microprocesador ya que está en una sola pastilla de silicio. El procesador siempre está ejecutando instrucciones. Una de las formas de desviar el flujo de ejecución es a través de las interrupciones. Cada vez que un dispositivo periférico transmite un dato al puerto de entrada, éste activa a un circuito integrado llamado controlador de interrupciones el cual interrumpe a su vez al CPU para que salte a la dirección de servicio de la interrupción que acaba de sucitarse. De esta manera el procesador no tiene que estar revisando todo el tiempo si ya hay un dato nuevo en cada registro de un puerto de entrada.

En cuanto a transmisión de datos, hay dos formas en que la computadora puede enviar y recibir datos. Una forma es en paralelo, byte por byte, la cual se usa para distancias cortas y es de alta velocidad (normalmente usada para las impresoras) y en serie, en donde se envía bit por bit y la cual se utiliza para transmisión a grandes distancias, con la ventaja de que es más barata ya que requiere menos hilos pero con la desventaja de que es más lenta (utilizada para conectarse en red o a un servidor remoto a través de un módem por vía telefónica). Con el mismo esquema una computadora puede ser monousuario o multiusuario, con la única diferencia de que en un sistema multiusuario debe de contar con un sistema operativo multiusuario que pueda dar servicio a varios usuarios compartiendo la memoria, el CPU y los recursos y por supuesto estar conectada a una red. Ejemplos de sistemas operativos multiusuario son Unix y Linux (que es prácticamente lo mismo). Un sistema operativo multiusuario se define como un administrador de los recursos del sistema que tiene el objeto de darle servicio a los diferentes usuarios del sistema.

Con el modelo cliente-servidor en el cual se instalan todos los programas en un servidor y los clientes pueden hacer uso remoto de los programas. Actualmente se utilizan computadoras muy poderosas como servidores y generalmente a estás se les instala una versión de Linux aunque Microsof también tiene su Windows Server. Ejemplos de servidores son los servidores de páginas webs.

Page 48: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

48

DESCRIPCIÓN LÓGICA En cuanto a la descripción lógica, una computadora es un modelo de modelos. La idea matemática en la cual se basa la idea de la computadora es hacer un modelo donde se pudieran representar aspectos de la realidad. El área de las matemáticas que sustenta la parte teórica de la computación es la llamada teoría matemática de la computación. En ésta se trabajan conceptos como autómata, autómata finito, gramáticas y la famosa máquina de Turing. Básicamente a través de autómatas es posible hacer máquinas que reconozcan cadenas. Un autómata es una máquina constituida por un conjunto de estados en el cual un estado es de inicio y uno o varios estados finales y donde a través de entradas va pasando por los diferentes estados generando simultáneamente salidas, se caracteriza por hacer procesos cíclicos. De aquí se deriva la palabra automático, es decir, que trabaja por medio de autómatas. Estas cadenas están constituidas por símbolos. Para generar una cadena es necesario aplicar las reglas de producción de tal forma que al establecerse reglas de producción se establecen simultáneamente un conjunto infinito de cadenas que se pueden formar, pero estas cadenas son especiales, pertenecen a una gramática. Por lo tanto, una gramática formal está constituida por un conjunto de reglas de producción, son esquemas generativos, modelos dinámicos para generar frases de un lenguaje. Las reglas de producción son como su nombre lo indica reglas que se aplican para generar cadenas pertenecientes al lenguaje. Ejemplo de una gramática: G = ( {S}, {0,1}, P, S) Donde el primer conjunto denota el vocabulario no terminal (Vn), el segundo conjunto denota el vocabulario terminal (Vt), P denota el conjunto de reglas de producción y S el símbolo especial de inicio. En donde P consta de las siguientes reglas: 1.- S → 0S1 2.- S → 01 Se puede aplicar inicialmente la regla 1 o bien la 2, por que ambas contienen a S como miembro izquierdo. Si se aplica la regla 2 se obtiene:

Page 49: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

49

S → 01 (la doble flecha representa la aplicación de alguna regla) y el proceso terminaría allí, ya que la cadena 01 contiene únicamente elementos terminales. Si se aplicará inicialmente la regla 1, sin embargo, se obtendría lo siguiente: S → 0S1 y como el lado derecho de esta aplicación contiene al menos un elemento no terminal, se vuelve a aplicar la regla ( la 2), para obtener 0S1 → 0011 que ya es una cadena terminal y por lo tanto pertenece al lenguaje que produce esta gramática. Así, las reglas de producción son, como su nombre lo indican, reglas que al aplicarlas producen cadenas con símbolos terminales y no terminales. Las cadenas que constan únicamente de símbolos terminales constituyen las cadenas que forman el lenguaje. Un símbolo es terminal cuando ya no se puede aplicar sobre él ninguna regla de producción, ejemplo "0" o "1". Ejemplo de no terminal "S". Al elaborar un programa nosotros producimos una cadena, el compilador se encarga de verificar si aplicando las reglas de producción se puede reconocer esta cadena. Si esto sucede, se comprueba que esta cadena pertenece al lenguaje generado por la gramática y de paso se genera el código objeto o ejecutable. Los autómatas se clasifican a través de la teoría matemática de la computación en cuatro y corresponden a un tipo de gramática que pueden reconocer.

Reconocedor Gramática Máquina de Turing Tipo 0 Autómata Lineal Tipo 1 (Sensible al contexto) Autómata de Pila Tipo 2 (Independiente del contexto) Autómata Finito Tipo 3 (Regular)

Los compiladores son autómatas de pila, lo que quiere decir que reconocen

lenguajes generados por gramáticas de tipo 2, independientes del contexto. La computadora es una herramienta que nos permite hacer representaciones de aspectos de realidad. Por lo tanto, lo que aprenderemos a hacer aquí es a hacer representaciones con los recursos con los que se cuenten. En un principio los primeros recursos son 1’s y 0’ y con ellos se construirán objetos más complejos.

Page 50: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

50

El término computabilidad proviene de computo. En los despachos de contabilidad había trabajadoras especializadas que su único trabajo era realizar cómputos, es decir operaciones aritméticas. Turing tomó de estas el término computable ya que la máquina que el ideó era capaz de realizar el mismo trabajo que una de estas secretarias. Una secretaria solo necesita papel y lápiz para realizar sus cómputos, de la misma manera la máquina de Turíng solo necesita una cinta infinita y una cabeza lectora-escritora para hacer sus cómputos. La máquina de Turing se puede programar mediante una tabla de estímulo-respuesta y de esta forma, una vez que se inicia el proceso, la máquina realiza los cómputos indicados por su tabla de estímulo-respuesta. Por lo tanto, un problema es computable cuando existe una máquina de Turing que se puede programar para resolver el problema, es decir, cuando existe una descripción algorítmica para resolver el problema.

Así pues, los datos se representan con 1’s y 0’s y los algoritmos son descripciones de procesos sobre ciertos datos. Una representación es el ejercicio de representar una cosa por otra, ejemplo un capacitor descargado puede representar un valor lógico “falso” o un símbolo “0” y uno cargado puede representar un valor lógico “verdad” o un símbolo “1” en un determinado proceso. Una descripción es un relato que cuenta como es cierto objeto, proceso o hecho. Ejemplo: un escritor puede hacer una descripción de una tarde soleada de primavera en algún lugar paradisiaco.

Un algoritmo también es una descripción de un proceso para resolver un problema

en términos computables sobre cierta representación de aspectos de la realidad como podrían ser presión, volumen, temperatura, flujo, etc. Por lo tanto programar es el ejercicio de describir un proceso sobre cierta representación de ciertos los aspectos de la realidad.

Page 51: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

51

EJERCICIOS CAPÍTULO 4 Fecha de entrega: ______________

Nombre (comenzando por el apellido): ________________________________________

Número de aciertos: 18

1.- Desde el punto de vista físico ¿Cuáles son las tres partes más importantes de que

consta una computadora y qué funciones tienen? ________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

2.- ¿Qué función tiene el canal de datos? ______________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

3.- ¿Qué función tiene el canal de direcciones? _________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

4.- ¿Qué función tienen las líneas de control? ___________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

5.- ¿Para qué sirve la Unidad Aritmética/Lógica? ________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

6.- ¿Para que sirve el DMA? ________________________________________________

Page 52: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

52

_______________________________________________________________________

_______________________________________________________________________

7.- ¿Qué es el código de máquina? ___________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

8.- ¿Qué son las interrupciones? _____________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

9.- ¿Cuáles son las dos formas de transmitir datos de una computadora? _____________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

10.- ¿Desde el punto de vista lógico cual es la idea en la que se basa la creación de la

computadora?____________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

11.- ¿Qué es un autómata? _________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

12.- ¿Qué es una gramática? ________________________________________________

_______________________________________________________________________

_______________________________________________________________________

Page 53: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

53

_______________________________________________________________________

_______________________________________________________________________

13.- ¿Qué son las reglas de producción? ______________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

14.- ¿Qué es un compilador? ________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

15.- ¿Qué es programar? ___________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

16.- ¿Qué significa que un proceso sea computable? _____________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

______________________________________________________________________

17.- ¿Qué es una descripción y de un ejemplo? _________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

18.- ¿Qué es una representación y de un ejemplo? ______________________________

_______________________________________________________________________

_______________________________________________________________________

Page 54: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

54

_______________________________________________________________________

_______________________________________________________________________

Page 55: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

55

5.- MÉTODO DE CASCADA La elaboración de programas no es un proceso empírico, existe un método para la su creación. A través del tiempo la forma en que se han construido ha ido evolucionando. El primer método que se ideó para elaborarlos es el llamado método de cascada. El método de cascada está formado por seis etapas, en donde una vez completada cada etapa, se va pasando a la siguiente no existiendo la posibilidad del regresar, de ahí el nombre del método. Las etapas del método de cascada son las siguientes: 1) Comprensión del problema 2) Análisis del problema 3) Programación del modelo de la solución propuesta en pseudocódigo 4) Codificación en un lenguaje formal 5) Carga en la computadora para su ejecución, prueba y ajuste 6) Mantenimiento durante su tiempo de vida útil 1.- COMPRENSIÓN DEL PROBLEMA. En programación es sumamente importante comprender el problema antes de comenzar a elaborar su solución. Por lo tanto primero hay que familiarizarse con el problema e inclusive hacer algunos ejemplos para corroborar que ya se ha comprendido bien el problema que se requiere solucionar. La razón de este punto es que en ocasiones los programadores comenzaban a trabajar en la solución sin tener la certeza de haber comprendido bien el problema y cuando entregaban la solución al cliente, éste encontraba que los Ingenieros de Software no habían comprendido bien sus requerimientos y por lo tanto la solución presentada no satisfacía sus expectativas generando fuertes conflictos mercantiles. Por lo tanto, antes de comenzar a trabajar en la solución de un problema se debe tener la certeza de que se ha comprendido perfectamente el problema, inclusive haciendo manualmente algunos ejemplos. En este paso se hace la descripción del problema en lenguaje natural. El lenguaje natural puede ser cualquier lenguaje humano, en nuestro caso será el Español. Ésta descripción puede servir como el encabezado del problema cuando se comience a cargar el programa. A esta descripción se le llama también especificación del problema en Ingeniería de Software y es la descripción del ¿qué?, el ¿qué vamos a resolver? 2.- ANÁLISIS DEL PROBLEMA

El significado etimológico de la palabra análisis es descomposición. En este paso se analiza el problema, se descompone y se medita en el algoritmo de solución, se plantean las variables y las estructuras de datos que se van a requerir y la forma en que se va a representar la información en la computadora. Un algoritmo es un procedimiento aplicado sobre ciertos datos para obtener un resultado final.

Page 56: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

56

El algoritmo solución puede ser expresado en lenguaje natural y además se puede hacer en forma de especificación, como si fuera una receta de cocina. Algunos problemas matemáticos ya tienen un algoritmo solución por lo que no hay necesidad de buscarlo. En ocasiones la solución está expresada en lenguaje matemático y en otras lo podemos conceptualizar en la mente aunque es recomendable transcribirlo en lenguaje natural.

Un algoritmo es un procedimiento computacional bien definido que toma algún valor o conjunto de valores como entrada y produce algún valor o conjunto de valores como salida. Es un conjunto de secuencias de pasos computacionales que transforman una entrada en una salida. Es también una herramienta para resolver un problema computacional bien especificado.

Un algoritmo debe tener las siguientes cuatro propiedades:

1. Finitud: debe acabar en un número finito de pasos. 2. Definibilidad: debe definirse en forma precisa y libre de ambigüedad. 3. Correctez: debe de resolver perfectamente el problema para el que fue

diseñado. 4. Eficiente: debe ocupar el menor número de recursos espacio/tiempo.

Uno de los algoritmos más antiguos conocidos es el algoritmo de Euclides el cual encuentra el máximo común divisor de dos números enteros positivos a través de divisiones sucesivas. El término algoritmo proviene del matemático Muhammad ibn Musa al-Khwarizmi, que vivió aproximadamente entre los años 780 y 850 D.C. en la actual nación Iraní. Él describió la realización de operaciones elementales en el sistema de numeración decimal. Del nombre al-Khwarizimi se obtuvo la derivación de algoritmo.

Aquí tendríamos la segunda especificación y es la especificación del ¿cómo? en lenguaje natural. 3.- PROGRAMACIÓN

En esta etapa se escribe la solución en pseudocódigo. El pseudocódigo es un lenguaje neutro estructurado a través del cual es posible hacer descripciones de una solución en términos computacionales. Con neutro queremos decir que no está casado con ninguna herramienta de programación, es un lenguaje por derecho propio. En muchas ocasiones se confunde con Pascal debido a que Niclaus Wirth construyó un lenguaje formal basado en las estructuras de control del pseudocódigo, he aquí la razón de la alta similitud entre Pascal y el pseudocódigo, aunque Pascal quedó más limitado que el pseudocódigo en algunos casos como el del “case”. Es estructurado ya que el control del flujo del programa se realiza mediante estructuras de control de flujo. Es importante aclarar también que los detalles de sintaxis no serán tan exhaustivos en pseudocódigo ya que este programa no se compilará, por lo que la sintaxis no será tan rigurosa, aunque se debe de tratar de seguir lo más posible.

Page 57: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

57

La sintaxis trata acerca de las reglas de construcción de los enunciados de un lenguaje. Ejemplo: la sintaxis de la gramática del Español marca que una oración debe estar constituida por las siguientes partes, sujeto, verbo y complemento. De la misma forma, los enunciados en un programa deben de estar constituidos dados los siguientes casos:

a) Si es un enunciado de asignación por una variable, seguido del signo de

asignación seguido de una expresión. b) Si es un llamado a procedimiento por el nombre del procedimiento y los

argumentos del llamado. c) Si es una estructura de control, dependiendo de la estructura, la

secuencia adecuada de palabras reservadas con las variables y condiciones requeridas, ejemplo: para la estructura de control “if” en su versión más simple la regla de construcción es la palabra reservada “if” seguido de condición seguido de la palabra reservada “then” seguido de enunciado.

En ocasiones las reglas de sintaxis se muestran en forma de diagramas. Cualquier

omisión o desorden en la secuencia causará un error de sintaxis.

Si el algoritmo ya existe, partiremos del algoritmo o de su descripción en lenguaje natural transcribiéndolo en términos computacionales. Es importante mencionar que un problema puede tener ya una solución algorítmica que no necesariamente esta se encuentre descrita en términos computacionales. Aquí construiremos la tercera especificación, plasmaremos el ¿cómo?, el ¿cómo se resuelve? pero esta vez en términos computacionales en pseudocódigo. El pseudocódigo es un lenguaje estructurado neutro y completo que sirve como vehículo descriptor y como modelo de la representación de la solución. Estructurado ya que el control del flujo se lleva a cabo en base a estructuras de control de flujo. Neutro ya que no está sujeto a ningún lenguaje de programación y completo ya que con el se puede implementar cualquier algoritmo que se requiera. Si el problema es muy complejo podemos usar el método de refinamientos sucesivos a través del cual podemos hacer que poco a poco la descripción en lenguaje natural se transforme en una descripción en términos computacionales de tal forma que al final sea posible codificar sin ningún problema ésta descripción en algún lenguaje formal como Pascal o C.

Pueden existir varias formas de solucionar un problema, además, cada solución puede tener optimizaciones, por lo tanto el número de soluciones de un problema computacional es infinito.

Para verificar si el algoritmo funciona correctamente se elaboran uno o varios ejemplos de prueba y se verifica en papel que funcione bien antes de codificarlo. Éstos ejemplos nos van a servir cuando vayamos a probar si nuestro programa funciona adecuadamente. Es importante que se comience por ejemplos sencillos. 4.- CODIFICACIÓN

Page 58: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

58

En esta etapa se procede a la codificación del programa en un lenguaje formal. Un lenguaje formal es aquel generado por una gramática desde el punto de vista de la teoría matemática de la computación. Es posible construir un reconocedor para cualquier cadena que pertenezca a este lenguaje. A este reconocedor se le llama Compilador. Para elaborar cadenas válidas de este lenguaje es necesario que el programador conozca perfectamente las reglas de sintaxis del lenguaje que se va a utilizar como herramienta, así como sus recursos y particularidades. En este paso si es importante respetar con todo rigor las reglas de sintaxis ya que de otra manera el programa o no se compilará correctamente o no realizará la tarea que se desea que realice, además de que no debe de haber errores tipográficos. Un error tipográfico es aquel en donde se escribe un carácter por otro, o se escribe doble o no se escribió en una palabra, ejemplo: en lugar de escribir “if” escribir “iff”. 5.- CARGA

En esta etapa se procede a editar el programa con una herramienta de programación, se eliminan los errores tipográficos, sintácticos y lógicos, se depura, se prueba y se obtiene un programa ejecutable.

Deberemos probar que nuestro programa corra con los ejemplos hechos en la etapa de programación para verificar que el algoritmo funciona como deseamos y posteriormente con casos límite y con entradas absurdas para ver cómo se comporta en éstos casos.

Es importante que la primera versión del programa sea una versión sencilla, sin muchos adornos ya que el punto es que resuelva el problema. Más adelante se le pueden poner adornos o mejorar la presentación con la seguridad de que el programa ya corre. En muchas ocasiones los programadores se comen el tiempo poniendo adornos a sus programas fallando en el tiempo de entrega. De nada servirán todos los adornos si el programa no corre.

En computación se debe tener conciencia de que el tiempo es un recurso, por lo que cada mejora al programa se debe de ponderar bajo un análisis de costo/beneficio tomando siempre en cuenta los recursos en tiempo asignados al proyecto.

Se debe tener cuidado al poner los filtros y validación de entradas para que el programa no deje de mostrar su objetivo más importante.

Los programas profesionales deben contener estos filtros y validaciones ya que una política de Ingeniería de Software es hacer programas que no puedan ser "tirados" por el usuario, se les llama "programas a prueba de tontos".

En esta etapa obtendremos las versión 1.0 de nuestra solución. Deberemos guardar una copia en un lugar seguro ya que esto garantizará que tengamos algo que entregar si las mejoras o las optimizaciones no quedarán a tiempo. Recordemos que lo peor que le puede pasar a un programador es no tener nada que entregar.

Page 59: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

59

6.- MANTENIMIENTO DEL SISTEMA

Esta etapa se realiza normalmente en los sistemas grandes ya que cuando entran en operación es posible que durante su uso se detecten fallas o se promuevan mejoras, por lo que debe de haber un equipo de personas que se encarguen de darle mantenimiento al sistema. En el desarrollo de los sistemas grandes es necesario que éstos queden bien documentados ya que en caso de requerir algún cambio toda la información debe estar disponible. Todos los proyectos grandes llevan un registro donde se almacena toda la información del sistema.

Nosotros no ejecutaremos esta etapa ya que únicamente desarrollaremos el programa, lo utilizaremos por un tiempo corto y este quedará guardado en algún lugar, sin embargo trataremos de hacer buenos programas que en caso de necesitarlos tiempo después seamos capaces de comprender nuestro programa y poderle hacer modificaciones. Una regla en Ingeniería de Software es hacer programas que cualquier programador sea capaz de comprender y no programas encriptados que únicamente el autor sabe como funcionan.

Page 60: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

60

Page 61: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

61

EJERCICIOS CAPÍTULO 5 Fecha de entrega: ______________

Nombre: ________________________________________________________________

Número de aciertos: 6

1.- Describa el método de desarrollo de cascada y explique brevemente cada una de sus

etapas: _________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

2.- ¿Qué es un algoritmo? __________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

3.- ¿Qué es el pseudocódigo? _______________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

4.- ¿Qué es un lenguaje natural? _____________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

5.- ¿Qué es un lenguaje estructurado? ________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

6.- ¿Cuales son las reglas de sintaxis? ________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

Page 62: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

62

Page 63: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

63

6.- ESTRUCTURA DE UN PROGRAMA, ENUNCIADOS, ENUNCIADOS DE ASIGNACIÓN, PALABRAS RESERVADAS E IDENTIFICADORES El programa que rige las actividades de todo el programa es llamado programa principal. Este programa puede ser ayudado por otros subprogramas llamados módulos, procedimientos o subrutinas. La estructura general de un programa principal es la siguiente: Nombre del programa Declaraciones de variables Cuerpo del programa Las declaraciones de variables sirven, como su nombre lo dice, para declarar las variables que se van a utilizar en el programa. No es posible utilizar una variable que no se haya declarado antes. Ejemplo de declaraciones de variables: A, B, C: entero; D, E, GradosFahrenheit: real; H: char; Nombre: cadena [10]; El cuerpo del programa estará formado por enunciados. Un enunciado es una cadena de símbolos que el compilador puede reconocer como cadena perteneciente al lenguaje de su gramática. Normalmente la computadora ejecuta los enunciados secuencialmente pero en ocasiones es necesario ejecutar secuencias de código repetitivamente o saltar a otros enunciados. Las estructuras de control de flujo se utilizan para dirigir el flujo de ejecución de un programa. La primera estructura de control de flujo que utilizaremos es la secuenciación. El ejemplo más sencillo de enunciado es el enunciado de asignación. Un enunciado de asignación es aquel en donde se evalúa una expresión y se asigna a la variable que está a la izquierda del signo de asignación. Éste enunciado se construye con el nombre de una variable, el signo de la asignación y una expresión. Una expresión es una secuencia de caracteres que indican una constante, una variable o una función o un conjunto de todas ellas concatenadas con un conjunto de operadores junto con un conjunto de paréntesis. Ejemplo:

0.5 - A + B * C / (D * Sin (X)) - 2

Page 64: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

64

Una constante es una cadena de caracteres numéricos que representan una cantidad. Ejemplo: 4, 0.5, -3.2 Una función es un código predefinido que calcula un valor a través de uno o varios argumentos y se sustituye en su invocación. En todos los lenguajes existen un conjunto de funciones predefinidas o bibliotecas de funciones predefinidas. Ejemplos: Sin (X), Cos (Y), Exp (Z) Como es necesario hacer explicita la operación de multiplicación y no existe el símbolo “•” el los teclados se optó por representarlo por un asterisco y el operador división con el símbolo “/”. Ejemplos de enunciados de asignación: A ← 5 A ← B A ← Seno (1.0) A ← 5 + B * Seno (1.0) En los lenguajes estructurados el formato es libre, es decir, se puede escribir en cualquier columna a diferencia de Fortran en donde se tenía que comenzar a escribir el enunciado en una columna determinada. En pseudocódigo el “;” se utiliza para separar enunciados que se encuentran en el mismo renglón, en Pascal “;” se utiliza para separar enunciados y en C se utiliza al final de cada enunciado.

En los lenguajes de programación la asignación se implementa con un símbolo o conjunto de símbolos, por ejemplo en Pascal se implementa con los caracteres ":=" y en el lenguaje C con un simple "=" y son distintos al operador de comparación que en Pascal se implementa con "=" y en C con "==" como veremos más adelante. Ya que el orden en la ejecución de los operadores en una expresión genera resultados distintos es necesario tener un orden de precedencia de operadores para no tener ambigüedad en la evaluación. El orden de precedencia es el criterio para resolver el orden de evaluación en una expresión. Ejemplo: Las expresiones: A ← B + D * C y

Page 65: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

65

A ← (B + C) * D no producirán el mismo resultado ya que sin paréntesis la expresión se resolverá evaluando primero el operador "*" y luego el operador "+". Si se escribe esta expresión pensando en que primero se evaluará el operador + y luego el * se tendrá un resultado erróneo y el error podrá quedar oculto ya que la expresión es sintácticamente correcta y el compilador no marcará ningún error. Para evitar este tipo de errores es recomendable dividir la expresión en subexpresiones y asignar temporalmente los resultados parciales a variables temporales. Una vez que el programa este corriendo adecuadamente integrar estas variables temporales a la expresión original hasta que no quede ninguna variable temporal. Esto expondrá el error en caso de existir alguno.

Hay una regla simple para saber cual operador se evalúa primero. Los operadores más complejos como la multiplicación y la división se evalúan primero y los operadores más simples como la suma y la resta se evalúan hasta el final. Los operadores con el mismo orden de precedencia se evalúan de izquierda a derecha. Los operadores unarios son aquellos que aplican sobre un operando, ejemplo: B := –A. Los operadores unarios se evalúan antes que los binarios. Los operadores binarios de aplican sobre dos operandos, ejemplo: C := A + B.

Tabla de Precedencia para Pascal paréntesis

Evaluación de funciones Operador – unario

*, /, div y mod Operadores binarios +, -

Pascal es un lenguaje fuertemente tipeado lo que quiere decir que el programador debe de tener cuidado de no asignar un resultado que no corresponda al tipo de variable. Si se le asigna a una variable un dato que no sea del mismo tipo del que es ella el compilador marcará un error, por lo tanto, es importante que el programador verifique que el dato que se le va a asignar a una variable sea del mismo tipo de la variable, ejemplo: C := A / B; La operación A / B produce un resultado real, por lo que C debe ser de tipo real, si no se hace de esta manera el compilador marcará un error. En Pascal el operador div entrega como resultado un entero, es decir, trunca el resultado de la división, a diferencia del operador "/" que entrega como resultado un real por lo cual la variable a la que se le asigna el resultado del operador div debe de ser entera, mientras que el tipo de dato de la variable a la que se le asignaría el resultado de un operador "/" tendría que ser real, de otra manera el compilador marcará un error. En

Page 66: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

66

Pascal el operador mod calcula el módulo o residuo de la división entre dos operandos. En C el operador módulo se codifica con “%”. Ejemplo: en Pascal el enunciado:

A := 7 mod 3 entregará como resultado un entero 2.

Por ejemplo expresión se evalúa de la siguiente manera:

A ← B + C * D – E div F / G . \___/ . . . . T1. . . . . . \_____/ . . . T2 . . . \_____/

T3 . \______/ . T4 . \______________/ T5 A En la siguiente expresión los paréntesis son los que tienen la mayor precedencia por lo que las expresiones que se encuentren entre paréntesis se evalúan primero, ejemplo:

D ← A * (B + C) . \_____/ . T1 \_______/ T2 D En el lenguaje de programación C el tipo de dato real se declara como float, es decir, flotante. Si se dividen dos enteros el resultado producirá un entero por lo que si se requiere que el resultado de la división de un float es necesario escribir una de las constantes en formato flotante, esto se hace agregándole una parte decimal al número, ejemplo:

c = 5 * (f – 32) /9 dará un resultado entero cuyo valor es 0, pero la expresión:

c = 5.0 * (f – 32) / 9 dará un resultado flotante correcto.

Page 67: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

67

Otro tipo de enunciado es el llamado a procedimiento. Un llamado a procedimiento

es, como su nombre lo indica, un llamado a un código de un procedimiento que en este caso ya fue definido y compilado anteriormente. En C no hay procedimientos, una función en C se comporta como un procedimiento de pseudocódigo y de Pascal. El llamado puede llevar argumentos. Los argumentos son variables o constantes a través de las cuales el procedimiento que invoca envía datos al procedimiento invocado. El procedimiento invocado puede regresar resultados en alguna de estas variables. Ejemplo de llamado a procedimiento:

Lee (X) y Escribe (Y)

En el caso de Pascal, hay una lista de procedimientos y funciones incluidos en el

lenguaje. A estos procedimientos y funciones se les da el nombre de procedimientos y funciones estandar. En el caso de Pascal Read, Write, ReadLn y WriteLn son procedimientos estándar para los que no es necesario incluir ninguna librería o también llamada biblioteca. En C el lenguaje esta constituido por un Kernel (nucleo), por lo que se debe de incluir el heder de cualquier función que se utilice. Las dos librerías que generalmente se requieren en C son la <stdio.h> y la <math.h>. <stdio.h> contiene las funciones de entrada/salida y <math.h> contiene las funciónes matemáticas como las trigonométricas y las logarítmicas. Puede consultar la descripción de cualquier función o procedimiento en los probramas de Borland posicionando el cursor debajo del nombre del procedimiento o función y presionando las teclas Ctrl y F1 simultáneamente, así pordrá saber como se utiliza y la biblioteca en la que se encientra.

De tal forma que un programa en pseudocódigo queda de la siguiente forma: programa Suma A, B, C: entero comienza Lee (A) Lee (B) C = A + B Escribe (C) termina

Un programa en Pascal queda de la siguiente forma:

Page 68: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

68

program Suma;

var A, B, C: Integer;

begin ReadLn (A); ReadLn (B); C := A + B; WriteLn (C)

end. En cuanto al lenguaje de programación C el kernel o núcleo no incluye ninguna

función, como ya mencionamos, por lo que para utilizar cualquier función predefinida es necesario hacer la inclusión de la biblioteca (o librería) en la que se encuentra, es decir, no cuenta con funciones estandar. En C es necesario incluir la librería <stdio.h> (standar input output, la h significa header) para utilizar los procedimientos scanf y printf. El procedimiento scanf sirve para leer variables del teclado y el procedimiento printf sirve para desplegar variables en la pantalla.

Un programa en C queda de la siguiente manera:

#include <stdio.h> main () { int a, b, c; scanf (“%d”, &a); scanf (“%d”, &b); c = a + b; printf (“%d”, c); } La primera línea incluye la librería stdio.h en donde se encuentran definidas las funciones scanf y printf. Note que en C son funciones y no procedimientos ya que en C solo existen funciones (aunque funcionen también como procedimientos). Las llaves “{“y ”}” representan los metaparéntesis “comienza” y “termina”. Note que en C la declaración de variables se hace dentro del cuerpo del programa.

En cuanto a la función scanf lo que está entre comillas dobles en el paréntesis es el formato de impresión. El “%” es un caracter de escape para indicar que a continuación viene el tipo de la variable que se va a leer o escribir, en este caso, la “d” que es para indicar que el dato que se va a leer es un entero y el símbolo “&” (se pronuncia “andpersand”) es un operador que extrae la dirección de la variable (esto se verá más adelante) y finalmente la variable que se va a leer o escribir. Note que printf no requiere utilizar el operador “&” ya que el procedimiento no requiere la dirección de la variable sino únicamente su nombre, esto se aclarará más adelante. En C la representación en punto

Page 69: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

69

flotane (o real) se declara con el tipo “float”. Para desplegar un float se utiliza el formato de impresión para float, el cual es una “f”. Ejemplo:

Page 70: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

70

#include <stdio.h> void main () { float fahrenheit, celsius; scanf (“%f”, &fahrenheit); celsius = 5.0/9.0 * (fahrenheit – 32); printf (“%4.2f”, celsius); } Tanto en Pascal como en C es posible desplegar una lista de variables con caracteres alfanuméricos mezclados en una sola instrucción, esto se hace en Pascal poniendo la lista de variables y las cadenas intermedias enceradas en comillas y separadas por comas y en C se agregan a la cadena del formato de impresión como se muestra adelante: WriteLn (‘El valor de ‘, Celsius:12:2’, ‘ °Celsius corresponde a ‘, Fahrenheit:12:2, ‘ °Fahrenheit’); El 12 indica que se escribirá en un campo de doce caracteres con cuatro decimales. En C esto sería: printf (“El valor de %12.2f °Celsius corresponden a %12.2f °Fahrenheit\n”, celcius, fahrenheit); La cadena “\n” indica que se hará un salto de línea después de haber desplegado la línea.

Page 71: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

71

Para ayudar al estudiante se han incluido las tablas del orden de precedencia de operadores de C y las tablas de descripción de las funciones scanf y printf.

Operadores Asociatividad ( ) [ ] -> Izquierda a derecha ! - ++ -- + - * & (tipo) sizeof Derecha a izquierda * / % Izquierda a derecha + - Izquierda a derecha << >> Izquierda a derecha < <= > >= Izquierda a derecha == != Izquierda a derecha & Izquierda a derecha ^ Izquierda a derecha | Izquierda a derecha && Izquierda a derecha || Izquierda a derecha ?: Derecha a izquierda = += -= *= /= %= &= ^= |= <<= >>= Derecha a izquierda , Izquierda a derecha

Tabla de precedencia y asociatividad de operadores de C

Page 72: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

72

Carácter Dato de entrada; tipo de argumento

D entero decimal; int *. I entero; int *. El entero puede estar en octal (iniciando con 0) o

hexadecimal (iniciando con 0x o 0X). O entero octal (con o sin cero al principio); int *. U entero decimal sin signo; unsigned int *.

X,x entero exadecimal (con o sin 0x o 0X al principio); int *. C caracteres; char *. Los siguientes caracteres de entrada se podrán en el

arreglo indicado, hasta el número dado por el ancho de campo; el valor por omisión es 1. No se agrega ‘\0’. En este caso se suprime el salto normal sobre los caracteres de espacio en blando; para leer el siguiente carácter que no sea blanco, use %ls.

S cadena de caracteres que no es espacio en blanco (no entrecomillados);char *, apunta a un arreglo de caracteres suficientemente grande para contener la cadena y un ‘\0’ terminal que se agregará.

e,f,g número de punto flotante; float *. El formato de entrada para los float es un signo optativo, una cadena de números posiblemente con un punto decimal, y un campo optativo de exponente con una E o e seguida posiblemente de un entero con signo.

P valor apuntador como se imprime por printf(“%p”); void *. N escribe en el argumento el número de caracteres escritos hasta el

momento por esta llamada; int *. No se lee entrada alguna. La cuenta de elementos convertidos no se incrementa.

[...] coincide con la mayor cadena no vacía de caracteres de entrada del conjunto entre corchetes ; char *. Se agrega un ‘\0’. [ ] ...] incluye en el conjunto.

[ˆ...] coincide con la mayor cadena no vacía de caracteres de entrada que no sean del conjunto entre corchetes; char *. Se agrega un ‘\0’. [ˆ]...] incluye ] en el conjunto

% literal; no se hace ninguna asignación.

Tabla de conversiones scanf

Page 73: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

73

Carácter Tipo de argumento; Convertido a

d, I int; notación decimal con signo O int; notación octal sin signo (sin ceros al principio

X,x int; notación hexadecimal sin signo (sin 0x o 0X al principio), utilizando abcdef para 0x o ABCDF para 0X.

U int; notación decimal sin signo. C int; carácter sencillo, después de la conversión a unsigned char. S char *s; los caracteres de la cadena son impresos hasta que se alcanza

un ‘\0’ o hasta que ha sido impreso el número de caracteres indicados por la presición.

F double; notación decimal de la forma [-]mmm.ddd, en donde el número de d es especificado por la precisión. La precisión por omisión es 6; una precisión 0 suprime el punto decimal.

E,e double; notación decimal de la formma [-]m.dddddde±xx o [-]m.ddddddE±xx, en donde el número de d está especificado por la precisión. La precisión por omisión es 6; una precisión 0 suprime el punto decimal.

G,g double; usa %e o %E si el exponente es menor que –4 o mayor o igual que la precisión; de otra forma es usado %f. Los ceros y el punto decimal al finar no son impresos.

P void *; imprime como un apuntador (representación dependiente de la implantación).

N int *; en número de caracteres escritos hasta el momento por esta llamada a printf es escrito en el argumento. No es convertido ningún argumento.

% No es convertido ningún argumento; se imprime como %.

Tabla de conversiones de printf

Page 74: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

74

Secuencia de escape Acción

\a Character de alarma (campana) \b Retroceso \f Avance de hoja \n Nueva línea \r Regreso de carro \t Tabulador horizontal \v Tabulador vertical \\ Diagonal invertida \? Interrogación \’ Apóstrofo \” Comillas

\ooo Número octal \xhh Número hexadecimal

Tabla de secuencias de escape del formato de impresión de printf

Las palabras enunciado y sentencia se manejarán como sinónimos. El flujo de ejecución de los enunciados será controlado por las estructuras de control de flujo. Más adelante se verán estas estructuras, por lo pronto es suficiente decir que las estructuras de control de flujo controlan el flujo de la ejecución de un programa haciendo que cierta secuencia se ejecute o no bajo ciertas condiciones o que se ejecute un número de veces previamente establecido o hasta que se cumpla alguna condición de paro o mientras una condición sea verdadera. Hasta este momento únicamente hemos utilizado la primera estructura de control de flujo, la secuenciación, en la cual el orden en el que se ejecutan los enunciados del programa es secuencial, es decir uno después de otro. Si el programa requiere procedimientos que no se encuentren dentro de las bibliotecas de procedimientos estándar el programador los podrá definir y anexar al programa o crear sus propias librerías. Estos procedimientos tendrán una forma muy similar a la forma del programa principal salvo que no se pueden ejecutar independientemente, tienen que ser invocados. También es posible pasarles argumentos y ellos a su vez pueden regresar resultados a través de variables a los programas que los llamaron. De esta forma tendremos que un programa completo constará de un programa principal, un conjunto de procedimientos y un conjunto de funciones en donde se puede obtener un diagrama muy parecido al organigrama de una empresa en donde el programa principal es el gerente general y debajo de él están los gerentes y subgerentes y así sucesivamente, formando una estructura arbolada. A este árbol le he llamado árbol de jerarquía de procedimientos. De tal manera que un árbol de jerarquía de procedimientos se vería de la siguiente forma:

Page 75: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

75

Programa Principal / | \ Procedimiento 1 Procedimiento 2 Procedimiento 3 / \ \ \ Procedimiento 4 Procedimiento 5 Procedimiento 6 Procedimiento 7 En donde el programa principal puede llamar a los procedimientos 1, 2 y 3 únicamente, el procedimiento 1 llama al 4 y 5, el procedimiento 2 al 6 y el procedimiento 3 al 7. El programa principal debe reflejar el algoritmo que se está empleando para resolver el problema ocultando en la mayor medida de lo posible los detalles del lenguaje de programación. En cambio los procedimientos inferiores se encargarán de resolver las tareas "sucias" utilizando los recursos detallados del lenguaje. A esto se le conoce como carga semántica (o de significado), de tal forma que el programa principal sea el que mayor carga semántica tenga y los procedimientos inferiores la menor, es decir, el programa principal tendrá el mayor grado de abstracción mientras que los procedimientos inferiores harán funciones más simples. El árbol de jerarquía de procedimientos se debe presentar como parte de la información técnica del programa ya que teniendo únicamente el código será difícil ver la relación entre procedimientos y el programa principal, cosa que en el árbol se puede ver de una forma más clara. Hay programas que manejan recursión, en estos casos no se forma el árbol de jerarquía de procedimientos. La recursión es la propiedad de un procedimiento de invocarse a si mismo. PALABRAS RESERVADAS Ya que en un lenguaje se tienen que emplear ciertas palabras para los tipos de datos y la sintaxis de las estructuras de control no será posible utilizar una de estas palabras como un identificador de variable, procedimiento o función. Por lo tanto, palabras como “programa”, “entero”, “real”, “carácter”, “comienza”, “termina”, “si” y todas las demás se les da el nombre de palabras reservadas o palabras clave y a ninguna variable, procedimiento o función podrá dársele el nombre de una palabra reservada.

Page 76: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

76

IDENTIFICADORES A las variables, procedimientos y funciones habrá que "bautizarlos". A los nombres con los que hagamos ésto se les llama identificadores. Un identificador es el nombre que se le da a una variable o a un procedimiento o a una función. Cada lenguaje tiene sus reglas para los nombres de identificadores. Una regla general es que un identificador debe comenzar con una letra, esto se debe a que al leer una cadena, si el compilador detecta que el primer carácter es una letra analizará si es una palabra reservada o si es un identificador de procedimiento, función o de variable. Si una cadena comienza con un carácter numérico o los signos “+” o “– entonces se trará de una constante numérica. El nombre con el que se "bautice" a una variable deberá reflejar su función dentro del programa y es muy importante que sea el nombre adecuado para que el programa se autoexplique. La convención que se recomienda para Pascal es escribir los identificadores con la primera letra de palabra con mayúscula y las restantes con minúsculas ya que un identificador puede estar compuesto de varias palabras. Si el nombre del identificador es compuesto, concatenar las palabras poniendo en mayúscula la primera letra de cada palabra, ejemplo: GradosFahrenheit Si se desea abreviar el identificador una buena técnica es eliminar las vocales intermedias, ejemplo: GrdsFhrnheit Pascal no es sensible a mayúsculas por lo que el usuario se dará cuenta que escribir GradosFahrenheit es lo mismo que escribir gradosfahrenheit o GRADOSFAHRENHEIT, pero es claro darse cuenta de las ventajas de la convención llamada contrastada. También se puede abreviar el nombre de la variable cortándolo en algunos casos, ejemplo: Cont para Contador, Temp para temporal, Pot para potencia Fact para Factorial. Por otro lado, el lenguaje de programación C si es sensible a mayúsculas, C tiene su propia convención para crear identificadores en donde generalmente todo se escribe con minúsculas y en donde los identificadores compuestos se separan con el caracter de subrayado también llamado underline, ejemplo: grados_fahrenheit La longitud permitida de los identificadores generalmente es muy grande de tal manera que en general no nos preocuparemos por la longitud de un identificador. En turbo Pascal un identificador puede tener hasta 64 caracteres.

Page 77: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

77

Así pues, si se emplea bien la convención recomendada y si se asigna adecuadamente los identificadores a las variables, a los procedimientos y las funciones el programa será autoexplicable. Un programa autoexplicable es aquel que sin necesidad de comentarios, por su pura lectura, es posible comprender qué es lo que hace, aunque cabe mencionar que no es mala práctica poner comentarios al programa que ayuden a su mejor comprensión si es que en alguna parte resulta ser muy complejo. También es importante comentar que es buena práctica escribir como comentarios al inicio del programa quién y cuando se elaboró el programa y la versión con el propósito de llevar un mejor de control de autor, fechas de elaboración y versiones del programa. De la misma manera es importante ponerle al nombre del archivo un nombre que relacione lo que hace el programa, por ejemplo un programa de conversión Celsius Fahrenheit podría llamarse CELSFHAR.PAS en pascal o cel_fahr.c en en el ambiente de programación Linux. Lamentablemente cuando se crearon estos compiladores el nombre de los archivos estaba restringido a ocho caracteres por lo que esta es la longitud más larga que puede tener el nombre del archivo de un programa en Turbo Pascal 7.0 y C++ 3.0. Sin embargo, una vez generado el executable es posible cambiarle el nombre por un nombre más largo en caso de ser necesario.

Page 78: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

78

Page 79: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

79

EJERCICIOS CAPÍTULO 6 Fecha de entrega: ______________

Nombre comenzando por el apellido: __________________________________________

Número de aciertos únicamente con los programas en Pascal: 23.

1.- ¿Qué estructura tiene un programa? _______________________________________

______________________________________________________________________

_______________________________________________________________________

2.- ¿De qué elementos está constituido un programa? ____________________________

_______________________________________________________________________

3.- ¿Qué es un enunciado? _________________________________________________

______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

4.- De un ejemplo de un enunciado de asignación: ______________________________

_______________________________________________________________________

5.- De un ejemplo de enunciado de llamado a procedimiento: ______________________

_______________________________________________________________________

6.- ¿Cuales son los procedimientos estándar en Turbo Pascal? ____________________

_______________________________________________________________________

_______________________________________________________________________

7.- ¿Cómo se le llama a la estructura que forma el programa principal, sus procedimientos

y funciones? _____________________________________________________________

8.- Obtenga el orden de evaluación de la siguiente expresión y ponga el tipo de dato en el

que se puede representar cada variable y cada temporal. Considere que el operador

“mod” (módulo) es un operador que tiene como operandos dos enteros y produce un

entero. Si se utiiza el operador div (división entera) entonces este operador debe recibir

dos enteros y produce un entero. Una operación que tiene como operando al menos un

real produce un real. En pseudocódigo hay que especificar qué resultado produce la

división, esto es, representemos el tipo de dato entero por la letra “e” y el tipo de dato real

por la letra “r”, entonces hay que especificar si e/r / e/r produce e /r o si e/r / e/r produce

siempre r. Hay que especificar si la función “Cuadrado” recibe e/r y produce e/r o si

recibe e/r y siempre produce r. La funcón RaízCuadarada por lógica siempre produce un

Page 80: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

80

real. Generalmente el resultado de una función es un real. A partir de que hay un real en

la expresión, todas las variables que se deriven de esa variable deberán ser reales.

G ← A div B * C + D / E - F

Page 81: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

81

9.- Obtenga el orden de evaluación de la siguiente expresión y ponga el tipo en el que

puede ser representada cada variable y cada temporal:

G ← A + B * C / Cuadrado (D + E) - F

10.- Obtenga el orden de evaluación de la siguiente expresión y ponga el tipo en el que

puede ser representada cada variable de variable y cada temporal:

G ← A + Seno (-B) * C / D + E - F

Page 82: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

82

11.- Escriba la siguiente expresión en forma de enunciado de asignación (no haga el

programa, solo escriba la expresión) de acuerdo a la sintaxis de pseudocódigo y de

Pascal y de C, elabore el esquema de orden de evaluación de operadores de las

expresiones en Pascal y C y ponga el tipo en en el que puede ser representada cada

variable.

radical = b2 - 4ac

Tip: la función cuadrado es “Cuadrado ()”, en Pascal es “Sqr ()” de abreviatura de

“Square”. Puede escribirla como función o como múltiplicación doble. En C no existe la

función “sqr ()” en la biblioteca math.h por lo que se tiene que implementar con una

multiplicación.

Page 83: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

83

12.- Escriba la siguiente expresión (no haga el programa, solo escriba la expresión) de

acuerdo a la sintaxis de pseudocódigo, de Pascal y de C, elabore el esquema de orden

de evaluación y ponga el tipo en el que se podría representar cada variable:

_________

x1 = -b + √ _radical__

2 a

Tip: La función raíz cuadrada en pseudocódigo es “RaizCuadrada ()”, en Pascal es:

SqRt (), abreviatura de “SquareRoot” y en C es sqrt (), también abreviatura de

“scuare_root ()” y se encuentra en la biblioteca math.h.

Page 84: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

84

Desarrolle los siguientes programas en Pascal utilizando la siguientes tablas y formulas.

SMI SMD

1 mile 1.6093 Km

1 pound 2.2 Kg

1 galon 4.5461 Lt

SMD SMI

1 Km 0.6214 milles

1 Kg 0.436 pounds

1 Lt 0.26 galons

c = 5/9 (f – 32)

f = 9/5 c + 32

Donde “c” representa a los grados Celsius y “f” representa a los grados Fahrenheit

13.- Conversión de millas a kilómetros.

14.- Conversión de kilómetros a millas.

15.- Conversión de libras a kilogramos.

16.- Conversión de kilogramos a libras.

17.- Conversión de litros a galones.

18.- Conversión de galones a litros.

19.- Conversión de grados Celsius a grados Fahrenheit.

20.- Conversión de grados Fahrenheit a grados Celsius.

21:- Que calcule la ecuación una recta en función de la variable de entrada x. m y b

deben ser constantes numéricas, cualesquiera. Ejemplo: y = 2.0x +1.0

22.- Que calcule el valor de una función de segundo grado también en función de x. a,b y

c deben ser constantes numéricas cualesquiera. Ejemplo: y = 2.0x2+3.0x+1.0

23.- Que calcule el valor de una función de tercer grado también en función de x. c0,c1, c2

y c3 deben ser constantes numérticas, cualesquiera.

y = c0 + c1 x + c2 x2 + c3 x3

Por ejemplo:

Page 85: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

85

y = -10.0 +2.0x+0.001x2+0.00001x3

Page 86: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

86

Page 87: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

87

7.- LÓGICA PROPOSICIONAL La lógica fue una de las ciencias desarrollada por Aristóteles en Grecia en el siglo III antes de Cristo. Básicamente la preocupación de Aristóteles era encontrar las leyes que regían la mecánica del pensamiento. Así fue como definió el silogismo. Un ejemplo de silogismo es el siguiente. Todos los hombres son falibles. Todos los sabios son hombres. Conclusión: Todos los sabios son falibles. La lógica fue una esperanza para poder verificar si las estructuras propuestas por los filósofos eran consistentes. Prácticamente después de Aristóteles los avances de la lógica estuvieron detenidos hasta el siglo XIX. Varios filósofos y matemáticos contribuyeron al nacimiento de la lógica moderna como lo son Augustus De Morgan, George Boole, Leibinitz, Euler, Lambert y Bolzano. George Boole hace la aportación del álgebra de Boole en donde se puede tener variables lógicas y trabajar con ellas en expresiones cualquiera que sea su valor, falso o verdadero. En lógica no es posible que una proposición sea falsa y verdadera al mismo tiempo, tiene que ser falsa o verdadera pero no ambas. Augustus De Morgan aporta leyes que trabajan sobre el álgebra de Boole las cuales permiten manipular expresiones booleanas ya sea para reducirlas o para encontrar otras expresiones equivalentes. La lógica combinatoria de las computadoras aprovecha estas leyes para el diseño de la parte combinatoria de las computadoras. Otros precursores de la lógica moderna fueron Gottlob Ferge, Alfred North Whitehead, Bertrand Russell, David Hilvert y Kurt Gödel. Kurt Gödel en particular hace una aportación cuantiosa al demostrar que los sistemas formales de las matemáticas son incompletos, además demostró que no puede probarse la consistencia de un sistema formal, lo que mostró que es imposible construir sistemas formales completos y consistentes. Si desea ampliar su conocimiento en este tema puede consultar el libro, Introducción a la Computación y a la Programación Estructurada, Segunda Edición, Guillermo Levine, Mc Graw Hill, punto 5.4 Anexo: visión histórica de la lógica matemática. La parte de la lógica que nos interesa estudiar en este momento es la lógica proposicional o sentencial, que es una interpretación del álgebra desarrollada por Boole. En lógica proposicional una proposición es una oración o sentencia que puede ser falsa o verdadera. En esta lógica una variable es un término que puede tomar únicamente dos valores, falso o verdadero, pero no ambos. Ejemplo de una variable lógica: p p puede representar cualquiera de las siguientes proposiciones:

Page 88: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

88

Las pelotas son redondas. Las pelotas botan. Las pelotas nunca se ponchan. Por lo tanto la variable p puede ser falsa o verdadera dependiendo qué proposición se le asigne. Las constantes son términos con significado preciso. Las constantes en lógica proposicional únicamente son dos, falso y verdadero. Por ejemplo, después de evaluar las proposiciones podemos decir que la proposición "Las pelotas son redonda" es verdadera, que la proposición "Las pelotas botan" es verdadera y que la proposición "Las pelotas nunca se ponchan" es falsa. Sea p una proposición. Se define la negación de p como no p o ¬p como aquella proposición que es verdadera si p es falsa y es falsa si p en verdadera. Claramente el operador "negación de p" es unario; esto es, su rango de acción está limitado a una sola formula proposicional. Se emplea una notación tabular muy común llamada tabla de verdad para indicar los valores que toman las expresiones con las diferentes combinaciones de valores lógicos y los operadores. La tabla de verdad para la negación es:

p ¬p V F F V

Se define la conjunción de dos variables o proposiciones, p y q denotada p ^ q, como aquella que es verdadera cuando ambas, p y q son verdaderas y falsa en otro caso. La tabla de verdad correspondiente a este operador es la siguiente:

P q p ^ q F F F F V F V F F V V V

Page 89: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

89

Se define la disyunción inclusiva de p y q, denotada p v q como aquella que es verdadera cuando p o q o ambas son verdaderas y falsa en caso contrario. Esto se conoce como el "o inclusivo", que en latín se llama vel, de donde proviene el símbolo v.

P q p νi q F F F F V V V F V V V V

Se define la disyunción exclusiva de p y q, denotada p vx q como aquella que es

verdadera cuando p o q son verdaderas, pero no ambas y falsa en caso contrario. Esto se conoce como el "o exclusivo", que en latín se llama vel x.

P q p νx q F F F F V V V F V V V V

Estos tres operadores también se conocen como conectores lógicos ya que

conectan dos proposiciones convirtiéndolas en una. Cuando en una expresión booleana que contiene variables se sustituyen estas por constantes ésta se convierte en una función proposicional la cual tiene la característica de tener uno y sólo uno de los valores permitidos, es decir, una función proposicional únicamente puede ser verdadera o falsa, pero no ambas. Ejemplo:

(p ^ q) vi r se convierte en función proposicional cuando sustituimos los valores de p, q y c por: (las pelotas son redondas y las pelotas botan) oi las pelotas nunca se ponchan Al evaluar cada término el lector puede comprobar que el valor de esta función proposicional es verdadero. La tautología tiene la particularidad de que no importa qué valores lógicos tomen las variables que la componen es siempre verdadera, ejemplo: p vi ¬p siempre será verdadera De forma contraria, la contradicción es una expresión que no importa qué valores lógicos tomen sus variables será siempre falsa, ejemplo:

Page 90: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

90

p ^ ¬p siempre será falsa La lógica proposicional continua avanzando y forma una parte fundamental del campo de la inteligencia artificial y de los lenguajes declarativos como Prolog y Lisp. Estos conectores lógicos los utilizaremos para formar las condiciones de la estructura de control de flujo. Para escribir proposiciones también se utilizan los operadores relacionales, los cuales se basan en la propiedad llamada cardinalidad de los números enteros. Los operadores relacionales son:

Operador Interpretación = igual que > mayor que < menor que ≥ mayor o igual ≤ menor o igual

TABLA DE OPERADORES RELACIONALES

Con estos operadores podemos construir expresiones lógicas como:

A > B, C = D o E ≤ G En donde las variables pueden ser enteros o reales, con el cuidado de no utilizar el operador identidad "=" entre reales ya que la probabilidad de que un real llegue a ser igual que otro es relativamente cero, por lo que esta expresión nunca sería verdadera. En el álgebra de Boole el operador disyunción es representado por un "+", el operador conjunción por un "·" y la negación por una comilla. Por lo tanto un ejemplo de expresión en álgebra de Boole sería:

(A + B ) · C’ Utilizando ésta nomenclatura las leyes de De Morgan son:

(A + B)’ = A’ · B’ y (A · B)’ = A’ + B’ Con estas leyes podemos expresar una proposición en términos de conjunciones o disyunciones según nos convenga. Así tendremos expresiones del siguiente tipo:

A > B y C < D oi no A > B y no C = D

Las reglas de precedencia para evaluar estos operadores serán las siguientes:

Page 91: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

91

1. La evaluación es recursiva 2. Se evalúa la expresión que está entre paréntesis 3. Se evalúan los operadores relacionales 4. Se evaúal los operadores de negación 5. Se evalúan las conjunciones de izquierda a derecha 6. Se avalúan las disyunciones de izquieda a derecha

Existen varias nomenclaturas para los operadores lógicos, las pondremos en la siguiente tabla.

Page 92: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

92

Español Inglés Lógica

Proposicional Álgebra de Boole

o Or ∨i + y And ∧ •

no Not ¬ ’

Page 93: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

93

EJERCICIOS CAPÍTULO 7 Fecha de entrega: ______________

Nombre comenzando por el apellido: __________________________________________

La calificación se calcula sobre el número total de respuestas, en este caso, 22.

1.- ¿Quién el padre de la lógica? _____________________________________________

2.- ¿Qué aportación hace George Boole a la lógica proposicional? __________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

3.- ¿Qué aportación hace Augustus De Morgan a la lógica proposicional? ____________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

4.- ¿Qué es una variable lógica? _____________________________________________

_______________________________________________________________________

_______________________________________________________________________

5.- ¿Qué es una constante lógica? _________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

6.- ¿ Qué es una tabla de verdad? ____________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

7.- ¿ Cómo se define la negación? ___________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

8.- ¿Cómo se define la conjunción? ___________________________________________

Page 94: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

94

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

9.- ¿Cómo se define la disyunción inclusiva? ___________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

10.- ¿Cómo se define la disyunción exclusiva? __________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

11.- ¿Qué operadores son conectores lógicos? _________________________________

_______________________________________________________________________

12.- ¿Qué es una función proposicional? _______________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

13.- ¿Qué es una tautología? _______________________________________________

______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

14.- ¿Qué es una contradicción? _____________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

Page 95: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

95

15.- Construya un conjunto de cinco proposiciones acerca de un mismo concepto que

puedan ser falsas o verdaderas y evalúelas, es decir, juzgue si son verdaderas o son

falsas. Utilice el cuantificador “todas” o “todos” ejemplo: Todas las sillas tienen cuatro

patas.

A. __________________________________________________________________

B. __________________________________________________________________

C. __________________________________________________________________

D. __________________________________________________________________

E. __________________________________________________________________

16.- Sustituya las variables por los valores de verdad de las proposiciones anteriores y

evalúe la siguiente función proposicional:

A y no B y C oi D y E

17.- Sustituya las variables por los valores de verdad de las proposiciones anteriores y

evalúe la siguiente función proposicional:

A y no B y (C ox D) y E

Page 96: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

96

18.- Construya una tautología con álgebra de Boole: _____________________________

_______________________________________________________________________

_______________________________________________________________________

19.- Construya una contradicción con álgebra de Boole: ___________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

20.- Construya el árbol de evaluación de la siguiente expresión lógica con A = 5, B = 4, C

= 4 y D = 7.

A > B y C ≤ D

21.- Construya el árbol de evaluación de la siguiente expresión lógica con A = 0, B = 4, C

= 7 y D = 8.

A > B oi no C = D

Page 97: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

97

22.- Construya el árbol de evaluación de la siguiente expresión lógica con A = 1, B = 2, C

= 3, D = 4, E = 5 y F = 6. Evalúe primero las proposiciones.

A > B y no C = D ox E < F

Page 98: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

98

Page 99: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

99

8.- ESTRUCTURAS DE CONTROL DE FLUJO Y CONDICIONES Para resolver un problema la primera tarea es, como ya se mencionó, escribir en lenguaje natural una descripción del mismo, en qué consiste y los alcances que debe tener, en sí, qué se espera que haga el programa, es decir, se requiere tener el enunciado del problema o la especificación del programa que se desea realizar. El término especificación se utiliza en el área de Ingeniería de Software para dar una descripción de manera formal de lo que se va a desarrollar. En la industria todo producto que se fabrica debe tener una especificación. Una especificación es un documento que reune los datos técnicos, formas, planos, características, mecanismos de funcionamiento y componentes de un producto. Ésta debe ser clara y tan libre de ambigüedades como sea posible. Cuando un programa de computadora es sumamente complejo y de gran tamaño generalemnte se le llama sistema. Un sistema son un conjunto de elementos o componentes que trabajan en forma coordinada para ejecutar una o varias funciones. Esto puede llevar a confuciones ya que a las computadoras que albergan los programas también se les llama sistema, pero en este caso son sistemas de computo. Así, es útil diferenciar entre un “programa sistema” y “sistema de computo”. Comunmente se le llama sistema de computo al conjunto de elementos que conforman una computadora. Anteriormente los sistemas de computo de gran tamaño estaban constituidos por una computadora que contenía la memoria principal, la unidad de procesamiento central, puertos de entrada/salida y periféricos. Alrededor de la computadora se encontraban dispositivos de almacenamiento secundario los cuales podrían ser, uno o varios discos duros, unidades de cinta, impresoras, puertos seriales para terminales y comunicación remota, etc. Actualmente al área donde se encuentra el centro de computo de las instituciones, orgnizaciones o empresas se les llama “site” y cuentan con raks donde se montan los equipos, deben de estar refrigerados, con nobrack’s y plantas de emergencia.

Por otro lado se ha dado en llamar a los diseñadores de sistemas analistas de sistemas. Análisis es una palabra que deriba del griego y quiere decir separación. Cuando en química se habla de análisis se habla de las descomposición de una substancia en sus componentes. El análisis de sistemas consiste en plantear cuales pueden ser los diferentes subsistemas que pueden formar el sistema completo. A su vez, cada subsistema se revisará y se verá si es posible y óptimo que éste este formado de más subsistemas. El proceso se repite hasta que ya no hay ningún subsistema que se pueda diseñar con más subsistemas. Cuando ya no hay más subsistemas que analizar el trabajo hasta este punto quedara terminado. El siguiente trabajo es elaborar el código de cada subsistema que aún no esté elaborado y acoplar los subsistemas para que puedan trabajar en conjunto. Finalmente verificar que el sistema en su conjunto trabaje correctamente.

El proceso para elaborar el código de un programa que formará parte de un

subsistema no es un problema de análisis. Para solucionar el problema se deben resolver dos problemas. El primero es buscar la forma de representar los objetos del problema del mundo real (también llamado dominio del problema) con elementos computacionales, y el

Page 100: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

100

segundo es desarrollar el algoritmo solución. Una una vez resueltos estos dos puntos se prueba con algunos ejemplos, comenzando con los más sencillos y terminando con los más complejos. Estos ejemplos servirán más adelante como los casos de prueba. Si hacemos la descripción en lenguaje natural del algoritmo solución veremos que en ella aparecerán estos elementos, por lo que el primer punto es hacer la descripción en lenguaje natural del algoritmo solución. Entiendase lenguaje natural cualquier lenguaje humano. La tercera etapa consiste en expresar el algoritmo solución en términos computacionales, es decir, en pseudocódigo. Repetimos la definición de pseudocódigo: el pseudocódigo es un lenguaje neutro que no está asociado a ningún lenguaje formal y que funciona como un veículo descriptor de algoritmos. En muchas ocasiones ya existe un algoritmo solución del problema por lo que lo único que hay que hacer es describir el algoritmo en términos computacionales. Cuando no exista tal se procederá a desarrollar el algoritmo que lo resuelva. Una vez hecha la primera descripción computacional del algoritmo (versión 1) se prueba con los primeros casos de prueba elaborados anteriormente, recordamos que los primeros deben ser los más sencillos. Para hacer la descripción en términos computacionales nos valdremos de las estructuras de control, el llamado a procedimientos y las invocaciones a funciones. Las estructuras de control flujo o simplemente estructuras de control son esquemas que indican la secuencia en que se ejecutarán las instrucciones de un programa. Lo primero que resalta en una descripción es su naturaleza secuencial por lo que la primera estructura de control que veremos es la secuenciación. La secuenciación es una forma de direccionamiento implícito. Cuando se ejecuta un programa se comienza a ejecutar la primera instrucción que está en la dirección indicada por un registro llamado Contador de Programa (CP) en el microprocesador. Pero ¿Cómo sabe el microprocesador cual es la siguiente instrucción a ejecutar? Pues si no hay ningún salto, únicamente se incrementa el CP y se ejecutará la instrucción a la que apunte, es decir, la siguiente instrucción en secuencia a la dirección de memoria. En la secuenciación se indica el flujo poniendo una instrucción después de otra, es decir, la computadora sabe qué instrucción es la siguiente a ejecutar siguiendo la secuencia en que éstas están en la memoria. Pero generalmente en una descripción aparecen decisiones en base a condiciones, por lo que se hace necesaria la segunda estructura de control, la selección. “Si pasa ésto entonces has ésto, de otro modo has esto otro”. También podemos apreciar en las descripciones de algoritmos iteraciones sugeridas por frases como "repite ésto hasta que pase ésto otro", por lo que una tercera estructura de control necesaria será del tipo iteración condicional.

Page 101: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

101

Tanto la selección como la iteración condicional se evalúan mediante una condición booleana. El concepto de enunciado es complejo ya que es un concepto recursivo. Como se verá más adelante un concepto recursivo es aquel en el que se utiliza el definiens dentro del definiendum. Veámos, un enunciado es una expresión de un lenguaje. Un enunciado puede estar compuesto a su vez de enunciados. Los enunciados se pueden organizar en secuencia. Los enunciados más simples son los enunciados de asignación y de llamado a procedimiento. Las estructuras de control también son enunciados. Un bloque de enunciados también es un enunciado. Una estructura de control generalmente contiene dentro enunciados. Por lo tanto, un programa también es un enunciado. Las estructuras de control dirigen el flujo de ejecución de los enunciados. El enunciado más simple sobre el que trabajan las estructuras de control de flujo es el enunciado de asignación, es decir, siempre habrá al menos un enunciado de asignación dentro de las estructuras de control de flujo de los procedimientos o funciones de nivel semántico más bajo, no tiene sentido una estructura de control que no tenga enunciados adentro. Un enunciado de asignación, como su nombre lo indica, asigna el valor de una expresión a una variable, ejemplo: A ← 1 En los lenguajes hay un símbolo para la asignación y otro para el relacional de igualdad, en Pascal se implementa la operación de asignación con la secuencia de símbolos ":=" y el relacional de igualdad con el símbolo "=", el empleo de este símbolo lo veremos más adelante. En C se implementó el símbolo de asignación con el símbolo “=” y el símbolo de comparación con dos símbolos “=” concatenados, esto es, “==”. Otro tipo de enunciado es el llamado a procedimiento, ejemplo: Lee (A) En este caso Lee es un procedimiento de entrada/salida lo mismo que Escribe. Utilizaremos la siguiente notación para mostrar la sintaxis de las estructuras de control de flujo. Un enunciado cualquiera lo representaremos con la letra “e” y cuando haya necesidad de diferenciar entre varios enunciados estos se numerarán, ejemplo: e1, e2,....., en. Reprecentaremos una condición booleana con una letra mayúscula “C”. Los elementos más básicos de la programación son los enunciados, también llamados sentencias. Y éstos a su vez solo pueden ser de tres clases, enunciados de asignación, llamados a procedimiento y estructuras de control. Estos se pueden ver como los ladrillos con los que se construye un programa. Podremos construir un programa con estos tres tipos de enunciados. Un enunciado simple o sentencia es una instrucción imperativa que se le da a una computadora. Existen dos maneras de representar las estructuras de control ya descritas, una mediante diagramas de flujo y otra mediante pseudocódigo.

Page 102: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

102

En un principio no existían los lenguajes estructurados, el primer método que se implementó para manejar el flujo de los programas fueron los diagramas de flujo. Los diagramas de flujo son diagramas que se construyen con símbolos en donde se muestra el flujo que puede tener un programa. Estos son más intuitivos pero con el tiempo se comenzaron a ver sus desventajas. Cuando un programa crecía, el diagrama de flujo se hacia inmanejable por lo que se buscaron otras alternativas de programación. Lo que se encontró fue que sólo eran necesarios ciertos patrones de los diagramas de flujo y a éstos se les dio el nombre de estructuras de control de flujo o simplemente estructuras de control. Una estructura de control es un pequeño segmento de código que tiene la característica de tener una entrada y una salida y que tiene un diagrama de flujo asociado. Con éstas estructuras se diseñó un metalenguaje estructurado al cual se denominó pseudocódigo. Con este lenguaje se buscaba tener un lenguaje genérico universal para poder representar algoritmos y se encontró también que es más conveniente utilizar el pseudocódigo que los diagramas de flujo ya que se pueden obtener programas más claros, óptimos, fáciles de depurar y optimizar. Por todo lo anterior los diagramas de flujo quedaron en el pasado. Es importante hacer notar que al ser el pseudocódigo un lenguaje genérico se pensó que sería posible escribir todos los algoritmos en este metalenguaje y de éste lenguaje codificarlos en cualquier lenguaje de programación formal. De esta manera únicamente habría que tener una sola versión de los algoritmos en pseudocódigo que podría ser codificada en cualquier lenguaje formal y no sería necesario tener una versión del algoritmo en cada lenguaje que existiera. Hay que hacer notar que en ese tiempo todavía no había lenguajes estructurados por lo que había que codificar el programa en pseudocódigo (estructurado) en un lenguaje no estructurado. El pseudocódigo requiere de ciertos símbolos privilegiados que ya tienen un significado preciso y preestablecido. A tales indicadores del pseudocódigo se les conoce como palabras reservadas o clave. Será necesario que exista una palabra reservada para la selección otra para la iteración condicional y otras para las estructuras de control que veremos más adelante. Por ejemplo la palabra “si” que se utiliza para la selección es una palabra clave ya que tiene un significado preestablecido a diferencia de un identificador el cual puede ser asignado a cualquier variable, procedimiento o función. Un identificador es el nombre con el que se reconoce a una variable, función o procedimiento y la regla es que debe de comenzar con un símbolo alfabético, ejemplo: Temperatura, Presión, Volumen, Alumno1, etc. En virtud de que las palabras reservadas son palabras que hablan acerca de otras adquieren la categoría de metapalabras. A continuación se describen las tres estructuras de control empleando las tres formas ya explicadas: Secuenciación

Page 103: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

103

e1 e2

o bien e1; e2 Selección si C entonces e1 otro e2 Iteración condicional repite e hasta C Como se puede observar, existen palabras reservadas para la selección y para la iteración condicional pero no para la secuenciación ya que basta escribir un enunciado en cada renglón o escribirlos en el mismo renglón separados por punto y coma, utilizando el ";" únicamente para separarlos. Observe que cada una de estas estructuras de control tiene un solo punto de entrada y un solo punto de salida. Esto nos ayudará para armar programas completos uniendo salidas con entradas para formar cadenas de enunciados estructurados acomodados en secuencia. Como ya se dispone de estructuras de control básicas se procederá a hacer uso de ellas combinándolas de diversas maneras para escribir programas completos. Para este fin existe una regla fundamental de composición que dice lo siguiente: "Es posible combinar las estructuras de control de secuenciación, selección e iteración condicional para formar nuevas estructuras de secuenciación, selección e iteración condicional". Es decir, es posible hacer una secuencia de selecciones e iteraciónones condicionales o es posible hacer una selección de una secuencia y de iteraciones condicionales o es posible hacer una iteración condicional de secuencias o selecciones o es posible hacer selecciones de selecciones o iteraciones de iteraciones, es decir, todas las combinaciones posibles, dando como resultado un conjunto infinito de combinaciones, por lo que se demostró que cualquier algoritmo o programa se puede describir con estas tres estructuras de control primitivas. Si esta regla de composición parece rara es por que es recursiva. Una definición es recursiva si emplea el definiens dentro del definiendum, o en otras palabras, si dice como obtener conceptos nuevos empleando para tal fin el mismo concepto que se intenta definir. Un razonamiento recursivo tiene dos partes: una base y la regla recursiva de construcción. La base no es recursiva y es el punto tanto de partida como de terminación de la definición.

Page 104: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

104

Podría considerarse la siguiente la regla de formación de estructuras de control válidas: Base: La secuenciación, la selección y la iteración condicional son estructuras de control válidas que pueden ser consideradas como enunciados. Regla: Las estructuras de control que se pueden formar combinando de manera válida la secuenciación, selección e iteración condicional también serán válidas. Esto da origen al concepto de programación estructurada. Un programa estará bien construido si está formado por estructuras de control válidas, de acuerdo con la base y la regla de formación. Para ilustrar el uso de las estructuras de control como regla de formación consideremos lo siguiente: Tenemos dos enunciados, e1 y e2. e1

e2 Una secuencia de enunciados también es un enunciado. Si agregamos un tercer enunciado ésta seguirá siendo una secuenciación si consideramos a los primeros dos como uno solo y aplicando la regla de la secuenciación obtenemos que tres enunciados seguidos también son una secuenciación. e1

e2

e3

Al agregar un enunciado, el conjunto de enunciados se puede seguir viendo como un enunciado. De la misma manera podremos tener secuencias de iteraciones, selecciones de secuencias, secuencias de selecciones, iteraciones de selecciones y todas las combinaciones posibles de estas tres estructuras de control básicas. Si aplicamos las reglas básicas para construir estructuras de control válidas podemos ver que todo programa bien construido se puede reducir a un solo enunciado. A su vez, podremos decir que cualquier estructura de control, simple o compuesta que esté bien formada es un enunciado y también que el alcance sintáctico de un enunciado es de un enunciado. El alcance sintáctico es el dominio donde tiene acción un enunciado, por lo tanto, una estructura de control de selección solo podrá contener uno o dos enunciados (dependiendo de su estructura) y una iteración condicional solo un enunciado. Esto puede ser confuso, pero si se considera que una estructura de control bien formada se puede ver como un enunciado esto se puede ver más claro.

Page 105: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

105

Para lograr que existan "más de un enunciado" dentro de estas estructuras de control utilizaremos los llamados metaparéntesis. Los metaparéntesis ayudan a aumentar el alcance sintáctico de un enunciado haciendo ver varios enunciados como uno solo. Con estos podremos enmarcar un conjunto de enunciados agrupados secuencialmente convirtiéndolos en un solo enunciado, es decir, con estos metaparéntesis podremos convertir una secuenciación en un solo enunciado. Estos metaparéntesis son dos nuevas palabras del pseudocódigo y son "comienza" y "termina". De esta forma podemos tener bloques de enunciados dentro de cualquier estructura de control donde aparece un enunciado, ejemplo: si C entonces comienza e1 e2 termina otro comienza e3 e4 termina Si una estructura de control compleja está bien formada seguirá teniendo una sola entrada y una sola salida. De la misma manera, si un programa está bien formado seguirá teniendo una sola entrada y una sola salida. Utilizando las reglas de formación el número de estructuras de control nuevas que podemos formar es infinito. De acuerdo con Levine, cada algoritmo o programa nuevo tendrá una nueva estructura de control nueva. Claro que en la realidad habrá un límite técnico para la profundidad o anidamiento, es decir cuando hay estructuras de control dentro de estructuras de control y así sucesivamente, pero éste generalmente es elevado por lo que no nos preocuparemos por ésto. Para marcar la profundidad se utiliza lo que se conoce como indentado. El indentado es un sangrado que se deja para indicar que un enunciado está dentro de otro. A esta propiedad le llamaremos pertenencia de las estructuras de control. Cuando un enunciado se encuentre dentro de otro diremos que pertenece o que está anidado o qué está dentro de la estructura de control exterior. Ejemplos de anidamiento: repite si C1 entonces e hasta (C2) En este caso tenemos una selección dentro de un repite.

Page 106: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

106

Las estructuras de control adicionales del tipo iteración condicional son dos: mientras y ejecuta, con la diferencia de que primero evalúan la condición booleana y luego ejecutan el (o los) enunciados asociados hasta que se cumple la condición de terminación. Se puede demostrar que la estructura de control “repite” no es primitiva componiéndola como la secuenciación de un enunciado simple y una “iteración condicional mientras” para obtener un programa equivalente: e mientras (C) e que primero ejecuta una vez el enunciado y luego averigua si debe o no continuar haciéndolo. La segunda versión difiere de la primera en cuanto a la forma como se controla la iteración, que ahora está determinada por consideraciones numéricas con el valor de un índice de control de la siguiente manera: ejecuta I = LimitInferior, LimiteSuperior e Este pseudocódigo dice " ejecuta el enunciado e desde I = LimiteInferior a I = LimiteSuperior ". El lector podrá comprobar que éste pseudocódigo es la abreviatura de este otro: I = LimiteInferior mientras (I < LimiteSuperior) comienza e I = I + 1 termina Con lo que queda claro que no es una estructura de control primitiva. Por el lado de la selección existe una ampliación llamada caso que es la abreviatura de: si V = 1 entonces e1 otro si V = 2 entonces e2 otro si V = 3 entonces e3 otro .... Esta construcción anidada no es más que una prueba de opción múltiple sobre el valor de la variable V y que también puede representarse con esta estructura completa:

Page 107: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

107

caso V de constante1: e1 constante2: e2 . . constanten: en fin-caso La cual in extenso quiere decir: en caso que la variable sea igual a la constante1 se ejecute el enunciado1, pero en caso de que la variable V sea igual a la constante2 se ejecute el enunciado 2 y así sucesivamente; Esta estructura de control se utiliza cuando se tienen varios si's anidados que dependen del valor de una variable haciendo más claro el código y quitando el problema del indentado. El “caso” es muy usado menús de opciones. Esta estructura abrevia gran cantidad de si's anidados. A continuación agregamos la sintaxis del pseudocódigo definida por Guillermo Levine Gutierrez en su libro de Introducción a la Computación y a la Programación Estructurada, Ed. Mac Graw Hill. SINTAXIS DEL PSEUDOCÓDIGO Se utiliza “!” para comentarios. Las palabras reservadas van subrayadas. “e” representa cualquier enunciado. Metaparéntesis

comienza y termina Estructuras de Control

Estructura de Control de Flujo Secuencial

Salto de línea es separador de enunciados Si están en la misma línea utilizar como separador “;”

Estructuras de Control de Flujo Selectivas

si condición entonces e si condición entonces e otro e

caso V de A1: e A2: e A3:e fin-caso

Page 108: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

108

Donde A puede ser una variable o una constante o una comparación: Ejemplo: caso ALFA de

1.6 : tasa = factor * 2 < 38 : comienza lee beta escribe zeta tasa = factor * 3 termina : tasa = 0 fin-caso

Estructuras de Control de Flujo Iterativas

mientras (condición) e repite e hasta (condición) ejecuta i = Li, Ls e Condiciones En la estructura de control si la condición no va entre paréntesis En las estructuras de control mientras y repite la condición sí va entre paréntesis forzosamente Ejemplo si LISTA(ap) = VALOR entonces band = 1 otro ap = ap + 1 mientras(LISTA(ap) <> VALOR y ap <= FIN) ap = ap + 1 Se utiliza el “=” tanto para comparación como para asignación.

Símbolos Relacionales = igual > mayor que < menor que

>= mayor o igual que <= menor o igual que <> Diferente

Page 109: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

109

Conector Lógico

O disyunción Y conjunción

No negación

Llamadas a procedimiento proc principal enunciados llama uno enunciados fin. proc uno enunciados regresa fin.

Page 110: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

110

El paso de parámetros únicamente se hace por referencia, no se indica nada. proc principal entero a, b, resultado lee a, b llama suma (a, b, resultado) escribe “a + b = ”, resultado fin. a, b y resultado son parámetros actuales o reales o argumentos proc suma (s1, s2, r) entero s1, s2, r r = s1 + s2 regresa fin. a, b y resultado son parámetros actuales s1, s2, r son parámetros formales Utiliza paréntesis tanto para arreglos como para argumentos Ejemplo: entero LISTA (10) Es sensible a mayúsculas por lo tanto la variable “LISTA” es diferente de “lista”. Con esto terminamos la descripción de la sintaxis del pseudocodigo de Guillermo Levine. Los criterios para utilizar las estructuras de control repetitivas son los siguientes: Si se sabe de antemano el número de iteraciones que va a ejecutar el bucle se utilizará la estructura de control “ejecuta”. Si no se conoce de antemano el número de iteraciones antes de comenzar el bucle se utilizarán la estructuras de control “repite” o “mientras”. Si se requiere que no se ejecute ninguna iteración si no se cumple la condición se debe de utilizar un “mientras”, en otro caso se usará un “repite”. Generalmente las descripciones de algoritmos en lenguaje natural están hechas de modo que se hace algo hasta que alguna condición se cumple por lo que lo más intuitivo al hacer la descripción de un algoritmo en términos computacionales es utilizar la estructura de control repite-hasta cuando sucede esto. La estructura de control “ejecuta” incrementa la variable de control automáticamente la finalizar el ciclo a diferencia del repite y el mientras, que no lo hacen.

Page 111: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

111

Note que cualquier estructura de control también es un enunciado, por lo que si tenemos una secuencia de estructuras de control en un renglón estas deberán separarse con ";". Ahora jugaremos con los términos computacionales para mostrar como una receta de cocina se puede escribir en términos computaciones. Tendremos una descripción en lenguaje natural, la cual traduciremos en una descripción en términos computaciones. La receta es la siguiente: Huevos a la Inglesa 6 huevos frescos. 1 ½ tazas de queso gruyere rallado. ¼ de cucharadita de mostaza preparada. 1 ½ tazas de crema fresca. 2 cucharadas de harina cernida tres veces. 2 cucharadas de mantequilla. Sal y pimienta al gusto. La mantequilla se pone en una cacerola y ya que está derretida se le agrega la harina y se mueve hasta que esté ligeramente dorada. Se le agrega la leche, poco a poco y sin dejar de mover para que no se formen grumos. Ya que está cocida y queda como un atole espeso, se sazona con la sal y la pimienta y se retira del fuego. En un molde de loza refractaria, engrasado con bastante mantequilla, se van partiendo los huevos, procurando que éstos no se junten mucho; se espolvorean con sal, pimienta y el queso y se cubren con la salsa. Se pueden servir en un platón o en moldecitos individuales. La descripción en términos computacionales es: Programa Cocina unos Huevos a la Inglesa comienza Consigue 6 huevos frescos. Consigue 1 ½ tazas de queso Gruyere rallado. Consigue ¼ de cucharadita de mostaza preparada. Consigue 1 ½ tazas de crema fresca. Consigue 2 cucharadas de harina cernida tres veces. Consigue 2 cucharadas de mantequilla. Consigue Sal y pimienta. Pon la mantequilla en una cacerola; Derrítela; Agrégale (Harina);

Page 112: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

112

repite Mueve hasta (que esté ligeramente dorada) Agrégale (Leche, poco a poco y sin dejar de mover para que no se formen grumos); repite Bate hasta (que esté cocida y quede como un atole espeso) Sazónalo (Sal) Sazónalo (Pimienta) Retíralo (Fuego) Engrasa un molde con bastante mantequilla; Parte los huevos y ponlos ahí procurando que estos no se junten mucho Espolvoréalos (Sal) Espolvoréalos (Pimienta) Espolvoréalos (Queso) Cúbrelos (Salsa) Ponles (trocitos de mantequilla encima) Mételos al horno caliente a (350°) repite Retardo hasta (que cuajen) Escribe ('¿Como los quiere servir, si en un platón o en moldecitos individuales?') Lee ( Respuesta) si Respuesta = 'en un platón' entonces sírvelos en un platón .de otra forma sírvelos en moldecitos individuales; fin. Observe que esta descripción está hecha a través de ordenes, esto se debe a que en realidad en la programación se le dan ordenes a la computadora, es por esta razón que a este paradigma de programación se le llama programación imperativa, por lo tanto no está en infinitivo, sino en 2a persona. También se puede apreciar que en términos computacionales no es posible dar órdenes complejas, es decir dos instrucciones simultáneamente. Es necesario dar instrucción por instrucción ya que el nivel de reconocimiento de la gramática no permite todavía reconocimiento de lenguaje natural. Y finalmente es la misma descripción excepto que aparecen estructuras de control para dirigir el flujo del programa. Si tuviéramos un robot con la capacidad de interpretar y ejecutar las instrucciones cada vez que le solicitáramos unos huevos a la inglesa, este buscaría en su base de datos la receta (el programa) y si lo tiene, ejecutaría la receta entregándonos unos ricos huevos a la Inglesa, y esto sería las veces que nosotros se los pidamos.

Page 113: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

113

Esto tiene varios comentarios. Primero, que la receta en términos computacionales es primero que nada una descripción, pero que teniendo la descripción en esta forma y teniendo una máquina capaz de ejecutar la descripción nos podemos liberar de la tarea de preparar los huevos a la Inglesa. Tal vez existan personas a las que les guste cocinar, pero hay trabajos rutinarios que generalmente a nadie le gusta hacer como lavar la ropa, plancharla, limpiar la casa, lavar los platos o tender las camas, por lo que sería muy interesante construir autómatas que fueran capaces de hacer este trabajo liberándonos del trabajo rutinario. Claro que es probable que de todos modos tengamos que supervisarlos, ya que estos autómatas no tendrían la capacidad de razonar y no podrían resolver ciertos problemas que no hayan sido contemplados en el programa como sería que una sabana se rompió al tender la cama o que la plancha no calienta cuando no hay energía eléctrica. También podemos agregar que aunque la receta ya esté en lenguaje natural o en términos computacionales, la receta no son los huevos a la inglesa, es una forma de representar el platillo “huevos a la inglesa”, pero con la receta podemos hacer los huevos a la inglesa las veces que queramos y en teoría, si se sigue correctamente, los huevos saldrían exactamente iguales a los que hizo el que creó la receta. Esto es a lo que Levine se refiere como el cierre del ciclo de la transmisión del conocimiento que consiste en lo siguiente: Un individuo ha adquirido conocimiento y ha desarrollado un método para hacer algo y nadie más lo tiene. Este individuo especifica su método en una forma clara, precisa y completa escribiéndolo en lenguaje natural. Otro individuo lee la especificación y trata de comprenderla (interpretarla). La sigue al pie de la letra, y si la descripción del método es clara, precisa y completa, y si además el segundo individuo la sigue sin cometer errores entonces se habrá logrado la transmisión del conocimiento al lograr el segundo individuo reproducir los mismos resultados del primer individuo. individuo uno individuo dos

Proceso de transmisión del conocimiento El proceso se da de la siguiente manera: El individuo uno tiene un conocimiento. El individuo uno lo representa con elementos del lenguaje.

Page 114: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

114

Para transmitirlo genera una descripción del proceso. Emite la descripción en lenguaje natural. El otro individuo la recibe la descripción y la interpreta generando la misma representación en su mente. Si la representación es la misma ¡Se ha llevado a cabo el proceso de transmisión de conocimiento! De hecho, de esta forma es como los seres humanos enseñamos y aprendemos, aunque lo hacemos sin tener conciencia de cómo lo hacemos. En este caso un programa es una descripción que metemos a la computadora, las variables es la forma en que se representa la información. Si la descripción es correcta y completa la computadora logrará reconstruir el proceso para obtener los mismos resultados que nosotros podemos obtener manualmente con sus elementos, así que en cierta forma le estamos transfiriendo nuestro conocimiento, además de que la humanidad ya cuenta con una máquina que puede aceptar descripciones y representaciones y ejecutarlas, y no nada más eso, ya tenemos una forma de probar si nuestras descripciones y representaciones son correctas y completas. Este punto es fundamental para las ciencias de la computación. Incluiremos una tabla para indicar las diferentes formas de codificar los operadores lógicos en Pascal y C.

Operador Pascal C y And && o Or ||

no Not !

Tabla de operadores lógicos

Page 115: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

115

Relacional Pascal C

= = == > > > < < < ≥ >= >= ≤ <= <=

Tabla de símbolos relacionales

Operador Pascal C + + + - - -

Multiplicación * * División entera div int / int

División / / Módulo mod %

Observe que la estructura de un programa son una serie de cajas que obedecen solo a dos formas de agruparse, una en forma secuencial y otra en forma de una caja que contiene otra caja. Con estas dos propiedades podemos formar bloques que únicamente tendrán una entrada y una sola salida, además de que producirán secciones de código claras que solo efectúan una función, pero que esta función la realizan bien.

De esta manera la forma general de un programa si enmarcáramos todos los

enunciados simples y las estructuras de control quedará de la forma siguiente:

Enunciado

Estructura de control iterativa

Page 116: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

116

Agregaremos la sintaxis de las estructuras de control en Pascal. Selectivas

if C then e if C then e else e case Variable of Lista: e; Lista: e; . . end case Variable of Lista: e; Lista: e; . . else e end Iterativas while C do e; repeat e until C for Variable := ValorInicial to ValorFinal do e

Page 117: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

117

Sintaxis de las Estructuras de Control en C Selectivas If (C) e if (C) e else e switch (variable) { case exp-const1: case exp-const2: ….: case: exp-consti: e; break; case exp-constj: case exp-constk: e; break; . . default: e; break; } Iterativas while (C) e do e while (C) for (variable = valor_inicial; C; actualización de variable de control) e

Page 118: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

118

Page 119: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

119

EJERCICIOS CAPÍTULO 8 Fecha de entrega: ______________ Nombre (comenzando por el apellido): ________________________________________

Total de aciertos: 37

1.- En el siguiente programa marque en un recuadro rojo las sentencias de asignación,

con verde los llamados a procedimiento, con azul la estructura de control iterativa. Nota:

marque la estructura de control desde donde comienza hasta donde termina.

Nota: El objetivo de este ejercicio es que vea que un programa está formado por

estructuras.

programa Lineal

variables

entero X, Y

comienza

ejecuta X ← 0, 10

comienza

Y ← 2 * X + 5

escribe (Y)

termina

termina

Page 120: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

120

2.- Obtenga una receta de cocina y transcríbala:

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

Page 121: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

121

3.- Represente la misma receta en términos computacionales, es decir con estructuras de

control:

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

Page 122: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

122

4.- Desarrolle un programa que diga la relación cardinal de dos números suministrados,

es decir, si el primero es mayor que el segundo, si son iguales o si el segundo es mayor

que el primero. Codifíquelos en Pascal y C.

5.- Desarrolle un programa que encuentre la relación cardinal de tres números enteros

suministrados y codifíquelos en Pascal y C. Ejemplo: A es mayor que B y B es mayor que

C

6.- Desarrolle un programa en pseudocódigo Pascal y C que convierta un número en

base decimal a cualquier base que el usuario requiera, de base 2 a base 9. Ejemplo: 2010

es 101002. No importa que el número salga invertido, solo tiene que notificar el programa

al usuario que el número se se escribirá invertido, ejemplo: 20 en decimal equivale a

00101 (invertido) en código binario.

7.- Desarrolle un programa en pseudocódigo, Pascal y C que encuentre la suma de la

serie armónica hasta el elemento que el usuario indique (efecto acumulador).

n

Serie armónica ∑ 1/i

i = 1

8.-Desarrollar un programa en psudocódigo, en Pascal y en C que despliegue la serie de

Fibbonacci hasta el elemento de la serie que el usuario indique a partir del tercer término,

es decir si dice uno tiene que dar como salida 1, 1, 2, si dice 2 tiene que dar como salida

1, 1, 2, 3, y así sucesivamente.

Serie de Fibbonacci: 1, 1, 2, 3, 5, 8, 13, ............

9.- Escribir un programa en pseudocódigo, Pascal y C que permita encontrar el máximo

común divisor (MCD) de dos números mediante el algoritmo de Euclides. El algoritmo de

Euclides es el siguiente: al dividir A entre B se obtiene un cociente Q y un residuo R. A

toma el valor de B, B toma el valor de R. Se repite esta operación hasta que el residuo es

cero. El último divisor es el MCD.

10.- Elaborar un programa en pseudocódigo, Pascal y C que encuentre las raices de una

ecuación de 2º grado. En caso de que la función tenga dos raices debe desplegarlas, en

caso de que solo exista una raíz debe desplegarla o en caso de que las raices sean

imaginarias debe mandar un mensaje al usuario diciendo que las raíces son imaginarias.

Page 123: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

123

11.- Desarrolle los programas de conversión del capítulo 6 en Pascal y C pero que desploieguen una tabla de conversión desde un valor inicial entero dado por el usuario hasta el valor final entero también dado por el usuario, con incrementos de una unidad. Nota: todos los programas deben ser amigables y deben contar con documentación interna, es decir, el nombre de quién los editó, la fecha de edición, fecha de la última modificación en caso de haberla y la versión del programa.

Page 124: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

124

Page 125: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

125

9.- PROCEDIMIENTOS, FUNCIONES, PASO DE PARÁMETROS, VARIABLES GLOBALES, VARIABLES LOCALES, ALCANCE SINTÁCTICO Y RECURSIÓN. La programación es una herramienta muy poderosa ya que con ella se pueden hacer programas con muy alto grado de complejidad. Esta complejidad irá creciendo a medida que vayamos ganando experiencia en el arte de hacer programas. Nuestros primeros programas serán sencillos, pero a medida que progresemos nuestros programas serán más complejos. Es importante conocer el manejo de las funciones y los procedimientos antes de aprender a programar ya que serán herramientas importantes en el ejercicio de la programación. Utilizaremos un método de programación que yo llamo programación en lenguaje natural, no por que se programe en lenguaje natural (como el lenguaje en el que hablamos) sino porque programaremos lo más similarmente posible de la forma en la que hablamos, esto lo explicaremos más adelante cuando veamos métodos de programación. Las herramientas fundamentales para poder hacer programas más complejos son las funciones y los procedimientos. Una función es un segmento de código que evalúa una expresión de acuerdo a uno o más argumentos que se reciban y el resultado de la evaluación se regresa y se sustituye en el lugar donde fue invocada la función. Ejemplo: función Medio (LimiteInferior, LimiteSuperior: entero): entero comienza Medio ← (LimiteSuperior - LimiteInferior) / 2 Termina A ésta parte se le llama la definición de la función. A los argumentos de la definición les llamaremos parámetros formales. Después podremos invocar a la función en cualquier parte del programa de la siguiente manera: Posición ← LimiteInferior + Medio (LimiteSuperior, LimiteInferior) A los argumentos de la invocación les llamaremos parámetros actuales. Los parámetros formales y actuales pueden tener en general nombres diferentes. Esto se debe a que la definición de la función o el procedimiento puede ser muy general mientras que las invocaciones pueden ser muy particulares. Cabe recordar que el sueño de Charles Babbage era construir una máquina en la que se pudiera cambiar la función de cálculo, observe que esto se puede hacer fácilmente cambiando la definición de la función.

Page 126: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

126

Un procedimiento es algo muy parecido a una función, la única diferencia es que no se puede invocar dentro de una expresión algebraica, sino que se invoca directamente como una instrucción. Son tan similares que en C no existe diferencia, no hay procedimientos, todas son funciones. Cuando una función se utiliza como un procedimiento en C simplemente se escribe como una instrucción. Ejemplo: scanf(). En C las funciones regresan valores pero simplemente no se hace nada con los valores que regresan. Un procedimiento es un segmento de código que puede o no recibir argumentos y que realiza un proceso sobre ciertos datos, es una unidad autocontenida de código (o sea, dice todo lo que se requiere para entenderlo), tiene la característica de no ser directamente ejecutable, sino que debe ser llamado para efectuar sus funciones. En él las variables o son pasadas por parámetros o son declaradas internamente, pero no se debe hablar de una variable que sea pasada o declarada de la forma anterior. A los procedimientos se les da también el nombre de subrutinas (Fortran) o módulos. Generalmente la forma de regresar los resultados se hace a través de datos compartidos con los procedimientos que lo llamaron, a esta forma de pasar argumentos se le llama paso de parámetros por referencia. Para indicar en Turbo Pascal que el paso de parámetros se hará por referencia se pone la cadena var al inicio de la lista de variables en la definición del procedimiento.

En C las variables son pasadas por valor. Para pasar una variable por referencia se debe de hacer mediante apuntadores. El operador “*” indica la referencia a un área apuntada por un apuntador. Ejempo: temperatura = *ap; indica asignar el contenido de la memoria apuntada por ap a la variable temperatura. Para declarar una variable como apuntador simplemente se le antepone un asterizco. Ejemplo: int *ap; En C manejar el paso de parámetros por referencia no es intuitivo. Hay que enviar la dirección de la variable mediante el operador “&” y recivirlo en una variable apuntador con el mismo nombre de la variable que se pasó como parámetro actual, esto en caso de que quiera nombrar con el mismo nombre a la variable en la función que invoca y la función invocada. int vector [8]; main()

{ row, column, result, last: integer

. . set (&row, &column); . .

Page 127: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

127

} set( row, col) int *row, *col); { . vector[*col] = *row; .

Generalmente también es necesario enviar ciertos datos que serán requeridos por un procedimiento pero que no interesan al momento de finalizar el procedimiento, a esta forma de enviar argumentos se le llama paso de parámetros por valor. En el paso de parámetros por valor el procedimiento o la función realizan una copia del valor, de tal forma que el valor en la variable original permanecerá inalterado. Para indicar que el paso de parámetros es por valor no se tiene que hacer nada, solo poner el nombre de la variable y su tipo como parámetro. Podemos modelar los procedimientos como si fueran un sastre. El sastre es el procedimiento que procesa la tela y la transforma, pero es necesario darle elementos al sastre para que pueda trabajar, un elemento es la tela, la cual él va a procesar y la cual va a regresar pero convertida en un traje, por lo tanto la tela es un argumento que debemos pasar por referencia o variable ya que tiene que regresar transformada. Pero no solo eso, también necesitamos darle al sastre las medidas, ya que sin las medidas el sastre no sabrá como transformar la tela. Así, pasaremos al sastre las medidas. El sastre hará una copia de las medidas en un papelito las cuales no es importante que regrese. Ejemplo de procedimiento: procedimiento Intercambia (var X, Y: entero) var Temp: entero comienza Temp ← X; X ← Y; Y ← Temp termina En este procedimiento el paso de parámetros se hace por referencia ya que es necesario que después de ejecutado el procedimiento las variables registren la actualización. Si no se antepusiera la palabra “var” en la lista, el paso de parámetros se haría por valor no generando ningún cambio después de ejecutar el procedimiento. A la especificación de las variables que se reciben como argumentos se le llama especificación de los parámetros formales. A los argumentos enviados al invocar la función o el procedimiento se les llama parámetros actuales.

Page 128: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

128

Esto solo es válido para Pascal ya que en C no existen procedimientos, todas son funciones (como ya lo mencionamos), pero es posible invocar a una función de la misma manera que se invoca a un procedimiento en Pascal. En Pascal el procedimiento quedaría de la siguiente manera: procedure Intercambia (var X, Y: integer) var Temp: integer; begin Temp: X; X := Y; Y := Temp end; En C quedaría así: void intercambia (x, y) int temp, *x, *y; { temp = *x; *x = *y; *y = temp; }

VARIABLES GLOBALES Y VARIABLES LOCALES Un programa consta generalmente de código y de una serie de variables en las cuales se almacenarán datos para ser procesados. En ocasiones el problema requiere que existan una serie de datos durante toda la ejecución de un programa, esto es posible hacerlo mediante lo que se llaman variables globales. Un ejemplo de esto podría ser un programa que simula un juego de ajedrez. Será necesario modelar el tablero y las piezas de alguna manera. El tablero y las piezas deben de estar presentes durante toda la ejecución del programa. En general se ha establecido como buena práctica el tener el menor número posible de variables globales, y si es posible ninguna, ya que tener una variable global implica que cualquier procedimiento puede alterarla y en caso de haber un mal funcionamiento sería muy difícil saber cual módulo la está afectando inadecuadamente, además de que se viola el principio de autocontenidez que consiste en que todas las variables de las que se hable en un procedimiento deben de estar declaradas como variables locales o deben ser parámetros formales. Se puede citar una variable global en cualquier módulo sonando esto como algo fuera de contexto ya que la declaración de esa variable no estará cerca y será difícil recordar su tipo y el programa se hará más difícil de comprender. Así que solo en casos estrictamente necesarios se declararán variables globales.

Page 129: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

129

Es natural que para que un procedimiento pueda hacer su trabajo necesite contadores, índices, variables temporales, etc. por lo que normalmente se requerirán declarar variables que únicamente estarán vigentes solo cuando el procedimiento se está ejecutando. A éste tipo de variables se les llama variables locales. Todas las variables declaradas dentro de un procedimiento serán variables locales. Si una variable aparece en un procedimiento sin haber sido declarada ni haber sido pasada por argumentos el compilador tratará de resolver buscando hacia arriba la variable más cercana que tenga el mismo nombre. A ésto se le llama el alcance sintáctico de una variable, lo cual quiere decir que una variable puede ser invocada fuera del ámbito donde fue declarada, aunque de nuevo, esto rompe el principio de autocontenidez que deben cumplir como política los procedimientos. ALCANCE SINTÁCTICO El alcance sintáctico de un identificador es la sección de código donde éste identificador es reconocido. El alcance sintáctico de una variable global es todo el programa. El alcance sintáctico de una variable local es únicamente el procedimiento donde está declarada. Aunque generalmente las variables globales tienen nombres muy particulares, Turbo Pascal da la flexibilidad de que existan variables globales y locales con el mismo identificador. La forma de resolver del compilador a qué variable se refiere una línea de código es buscando la declaración más cercana hacia arriba, en éste caso, si el programa se encuentra ejecutando una instrucción del procedimiento la declaración a la que se hará referencia será a la local. Solo en caso de que no se haya declarado la variable como local en un procedimiento se estará haciendo referencia a la variable global. En general una variable puede ser citada una vez que ha sido declarada, por lo que a partir de que una variable es declarada puede ser citada en cualquier parte hacia abajo del programa. Pero hay que tener cuidado de que todas las variables que maneje una función o procedimiento se pasen como argumentos ya que de no hacerlo se violara el principio de autocontenidez. Aunque si se utiliza un índice, por ejemplo "I" en varias partes del programa, es tentador definirlo como global, pero no es recomendable hacer esto ya que se violaría el principio de auto-contenido. Es mejor definir la variable en cada procedimiento cada vez que se vaya a utilizar aunque esto parezca redundante. Por otro lado las variables globales, si es que son necesarias, deben tener nombres muy particulares para evitar confusiones con variables definidas localmente. LA RECURSIÓN La recursión es la invocación a si misma de la función o el procedimiento desde adentro. Existen problemas que se pueden resolver mediante algoritmos recursivos. Las funciones que utilizan la recursión básicamente constan de dos partes, el caso general y el caso límite. Algunos algoritmos no recursivos se pueden escribir en forma recursiva, tal el es el caso de una función potencia o factorial.

Page 130: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

130

Una función potencia la podemos escribir en forma iterativa como: función Potencia(N, M: entero): entero var I, X: entero comienza X ← 1 ejecuta I = 1, M X ← X * N Potencia ← X termina En forma recursiva ésta función se escribiría: función Potencia (N: real; M: entero): entero comienza si M = 0 entonces Potencia ← 1 otro Potencia ← N * Potencia (N, M -1) termina Definiremos las funciones en Pascal y C. En Pascal la función se define de la siguiente manera: function PotenciaIterativa (N: real; M: integer): real; var I, X: integer; begin X := 1;

for I= 1 to M do X := X * N; Potencia := X end; function PotenciaRecursiva (N: real; M: integer): real; begin if N = 0 then PotenciaRecursiva := 1 else PotenciaRecursiva := PotenciaRecursiva (N, M – 1) end; En C sería: float potencia_iterativa (n, m)

Page 131: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

131

int m, i; float n, x; { x = 1; for (i = 1; i <= M; ++i) x = x * n return x; } float potencia_recursiva (n, m) float n; int m; { if (m == 0) return 1 else return potencia_recursiva (n, m-1); } Es importante mencionar que depurar algoritmos recursivos es más difícil que los iterativos ya que el algoritmo regresa a él mismo y es dificil saber en qué nivel de recursión va. El problema de las torres de Hanoi es un buen caso de aplicación de la recursión. el problema consiste en pasar 64 discos de diferente tamaño de un poste a otro utilizando un poste central y en donde hay dos reglas: la primera es que no es permitido poner un disco más grande arriba de otro más chico y la segunda es que solo se permite mover un disco a la vez. Los 64 discos van disminuyendo en tamaño conforme son apilados. El problema se resuelve creando un procedimiento que pase la torre de altura H al poste deseado pasando por el poste restante. Considerando que el procedimiento se puede reinvocar y que se le puede solicitar mover los discos restantes, es decir, con altura H - 1 del poste fuente al poste destino, pasando por el poste restante, el problema se reduce a mover un solo disco. Esto es: Consideremos que hay tres estacas, la A, la B y la C y que hay una pila de discos de diferente tamaño en la estaca A. El objetivo es mover los discos de la estaca A a la estaca C utilizando la estaca B. El algorimo solución es el siguiente:

Consideremos que podemos invocar un procedimiento llamado mueve pila, el cual puede mover una pila de la estaca fuente, a la estaca destino pasando por la estaca paso de altura h. El procedimiento sería: MuevePila (var Fuente, Destino, Paso: arreglo de enteros; H: entero) Donde Fuente, Destino y Paso son arreglos de enteros. Suponiendo que éste procedimiento existe entonces Hanoi se escribiría así:

Page 132: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

132

programa Hanoi comienza MuevePila (A, C, B, H) termina Donde el poste de la izquierda se representa por A, el de en medio por B y el derecho por C. Si consideramos que el disco inferior no se mueve por el momento, podemos considerar el problema de mover la pila de arriba al poste intermedio, el disco inferior al poste destino y de nuevo la pila superior del poste intermedio al poste destino. Entonces MuevePila se puede escribir como: procedimiento MuevePila (var Fuente, Destino, Paso: arreglo; H: entero) comienza si H = 1 MueveDisco (Fuente, Destino) otro comienza Mueve Pila (Fuente, Paso, Destino, H - 1) MueveDisco (Fuente, Destino) MuevePila (Paso, Destino, Fuente, H - 1) termina termina Note que aunque el tercer argumento diga Destino, en realidad lo que importa es la posición del argumento, el primer argumento siempre será la fuente, el segundo siempre será el destino y el tercero siempre será el medio por el cual se va a realizar la transferencia. Los discos se pueden representar por números, los postes como arreglos de números de dimensión 64. Lo único que resta definir es el procedimiento MueveDisco. En el capítulo 11 definiremos este procedimiento. Para un programador es importante saber qué funciones ya están implementadas en la herramienta, por ésta razón facilitamos la tabla de funciones matemáticas estándar incluidas en Turbo Pascal.

Page 133: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

133

Nombre Argumento Devuelve: Abs (X) real o entero Valor absoluto

ArcTan (X) real o entero Arco Tangente Cos (X)* real o entero Coseno Exp (X) real o entero Exponencial Frac (X) real Parte decimal Int (X) real Parte entera Ln (X) real o entero Logaritmo natural

Pi ninguno Valor de Pi con 20 cifras significativas Round (X) real o entero Entero más próximo

Sin (X) real o entero Seno Sqr (X) real o entero Cuadrado Sqrt (X) real o entero Raíz cuadrada

Trunc (X) real Parte entera El argumento de las funciones trigonométricas siempre es en radianes. En C para utilizar las funciones matemáticas es necesario incluir el header “math.h”. Unidades en Pascal Las unidades son las bibliotecas donde se pueden definir constantes, tipos de datos, funciones y procedimientos. El primer paso para generar una Unidad es construir el código fuente. La primera línea debe comenzar con la palabra reservada “unit” seguida por el nombre de la unidad seguido por “;”. Después debe aparecer la palabra reservada “inteface” sin ningún “;” al final. Posteriormente la palabra “inteface” y adelante la lista de tipos de datos definidos si es que los hay seguido de los encabezados de las funciones y los procedimientos que serán públicos. Debe incluir también la lista de elementos de programación que podrán utilizar otros programas. Después debe aparecer la palabra “implementation” sin “;” al final. Finalizamos este capítulo diciendo que los procedimientos, las funciones y el paso de parámetros son elementos fundamentales para poder explotar los lenguajes de programación a su máxima potencia, sin ellos la complejidad sería inmanejable.

Page 134: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

134

Page 135: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

135

PREGUNTAS CAPITULO 9 Fecha de entrega:______________

Nombre: ________________________________________________________________

La calificación se calcula sobre el número total de respuestas, en este caso, 16.

1.- ¿Qué son las funciones? ________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

2.- ¿Qué son los procedimientos? ____________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

3.- ¿Cuáles son las dos formas de paso de parámetros? __________________________

_______________________________________________________________________

4.- ¿Cómo es el paso de parámetros por referencia? _____________________________

_______________________________________________________________________

_______________________________________________________________________

5.- ¿Cómo es el paso de parámetros por valor? _________________________________

_______________________________________________________________________

_______________________________________________________________________

6.- ¿Cuáles son las variables globales y cuándo se deben usar? ____________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

7.- ¿Cuales son las variables locales y cuando se usan? __________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

8.- En la siguiente figura, indique que tipo de paso de parámetros utilizaría.

Page 136: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

136

9.- Codifique el procedimiento Intercambia (X, Y) en Pascal y la función intercambia (x, y)

en C y haga programas para probarlos e imprima códigos y corridas.

10.- Desarrolle la función factorial en versión no recursiva y versión recursiva en Pascal y

C y haga un programa para probarlas e imprima códigos y corridas.

Nota: Como el factorial crece muy rápido manéjela con el tipo de dato entero largo

(longint) el cual es un tipo de dato entero de cuatro bytes que puede almacenar enteros

de poco más de nueve cifras significativas.

11.- Desarrolle la función Potencia en versión iterativa y en versión recursiva en Pascal y

C y haga un programa para probarlas e imprima códigos y corridas. Utilice longint como el

tipo de dato de la función.

12.- Codifique el programa Hanoi y el procedimiento MuevePila (Fuente, Destino, Paso,

Altura) en Pascal y mueve_pila (fuente, destino, paso) en C sin el procedimiento

MueveDisco (mueve_disco). Éste procedimiento se elaborará en el capítulo diez. No es

necesario que el programa corra. Imprimir únicamente códigos.

Sastre

Medidas Paso de parámetros por: ___________________

Tela Paso de parámetros por: ___________________

Traje

Page 137: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

137

Page 138: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

138

Page 139: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

139

10.- ¿Qué es un programa?, ¿Qué es programar?, pseudocódigo, método Páez de implementación de algoritmos iterativos, refinamientos sucesivos y codificación. Una vez que se han definido la mayoría de los elementos de la programación ya podemos comenzar a usarlos para construir programas. La primera pregunta que surge es ¿qué es un programa? De hecho la pregunta ¿qué es programar? va relacionada con ésta. Para contestar estas preguntas daremos primero algunos antecedentes. El concepto programar aparece cuando los científicos logran crear una máquina capaz de ejecutar instrucciones. En las primeras computadoras se programó en código de máquina, por lo que hacer programas era algo que requería mucho trabajo. El siguiente paso fueron los ensambladores, en donde se le decía a la máquina que tenía que hacer a través de mnemónicos y el programa traducía los mnemónicos a código de máquina ahorrando el trabajo de hacer la traducción a hexadecimal u octal y binario. Programar en estos lenguajes era muy problemático ya que se tenía que conocer la arquitectura de la computadora y saber en que zonas de memoria se podían cargar los programas y los datos, además de que el hacer programas con un alto grado de complejidad implicaba muchas horas de trabajo tanto de elaboración como de prueba (y solo con saltos condicionales e incondicionales y llamados a subrutinas). Más adelante aparecieron los macro-ensambladores en donde era posible reutilizar código ya escrito sin necesidad de volverlo a escribir, aunque seguían siendo muy altas las limitaciones. De hecho, aún a la fecha un macroensamblador es desarrollado para cada procesador nuevo que se fabrica ya que aún es necesario hacer ciertos programas de bajo nivel en ensamblador. Finalmente se desarrollaron los sistemas operativos y los lenguajes formales en donde ya no era necesario que el programador conociera la arquitectura de la computadora y las instrucciones del procesador, y en donde ya no se tenían que preocupar por el manejo de la memoria, de esto se encarga el sistema operativo y de la traducción a código de máquina el compilador. Los primeros lenguajes que aparecieron utilizaban únicamente saltos condicionales e incondicionales, como en el ensamblador, por ejemplo Fortran. Los programas así obtenidos podrían ser en exceso complicados e imposibles de depurar o de alterar, ya que los rizos podían quedar traslapados, por lo se buscó una solución a éste problema. El resultado fueron los lenguajes estructurados en donde se utilizan estructuras de control de flujo para dirigir el flujo del programa.

Page 140: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

140

Hay quien piensa que la programación apareció con las computadoras, pero en realidad el concepto de programación es más antiguo. Babbage y Adda Lovelance ya lo habían concevido. Para programar lo único que se necesita es un lenguaje de especificación que no sea ambiguo, algo que se requiera representar y un proceso que se requiera describir. Se podría decir que los primeros programas que aparecieron en la historia fueron las obras de teatro de los griegos, en donde a través de un lenguaje se narraba algún acontecimiento de la historia de forma en que se hacía una reconstrucción de los hechos de la manera en que se dieron y en donde cada personaje de la obra podría ser interpretado por un diferente actor, de tal forma que se podría decir que el guión de la obra de teatro es también un programa. Nótese la capacidad de las obras de reconstruir virtualmente una realidad acontecida en el pasado. Por cierto, el teatro tiene los géneros drama y comedia. El drama es una obra que siempre acaba en tragedia y la comedia es una obra en donde todo lo que pasa tiene el objetivo de hacernos reír, de ahí que el símbolo del teatro sean las dos caritas, una llorando y la otra sonriendo. Finalmente la vida es una tragicomedia. Más adelante hubo necesidad de implementar un lenguaje para representar sonidos, compases, en sí, música. Así es como nace la notación musical a través de la cual el músico puede representar melodías y en donde cualquier interprete unívocamente, es decir, sin temor reproducir otra cosa, puede reproducir exactamente lo que el autor compuso. De esta forma se puede decir que las partituras musicales son también programas que al ejecutarse (interpretarse) reconstruyen idénticamente la melodía que el autor compuso originalmente. De la misma manera que en el teatro y la música, a través de un lenguaje de especificación es posible describir aspectos de la realidad en una computadora y reconstruirlos tantas veces como se quiera. En la computadora es posible hacer descripciones-representaciones de la realidad. Estas descripciones-representaciones las haremos a través del lenguaje descriptivo. Así pues un programa es un conjunto de instrucciones que se le dan a una computadora con el objeto de tener descripciones-representaciones en términos computacionales de aspectos de la realidad. Ejemplo: Supongamos que somos matemáticos y cada vez que tenemos un sistema de ecuaciones lineales es muy laborioso encontrar la solución. Sabemos como resolverlo y además sabemos que el procedimiento de solución es muy mecánico. Entonces, a través de un lenguaje de programación podemos hacer la descripción de cómo se resuelve el sistema de ecuaciones y una vez que la descripción está hecha, cada vez que requiramos resolver un sistema simplemente ejecutamos esa descripción-representación (es decir, corremos el programa) y alimentándolo con los nuevos datos resolvemos el problema. Nos ahorraremos trabajo, ¿no?

Page 141: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

141

Luego entonces, podemos decir que programar es hacer una descripción en términos computacionales de una parte de la realidad a través de un vehículo descriptor. Programar es más que escribir líneas de código, es transmitirle a la computadora nuestro conocimiento de cómo resolver problemas. La programación estructurada apareció antes que los lenguajes estructurados, así que lo que se hacia originalmente programar con estructurass de control e implementar las estructuras de control con los elementos del lenguaje utilizado. De hecho en la UAMI se implementó en los 80’s un preprocesador que tuvo mucho éxito en donde se programaba en un lenguaje estructurado y se compilaba a Fortran, posteriormente se compilaba el programa en Fortran para obtener el programa ejecutable. Al autor tuvo la experiencia de programar su compilador de la materia de compiladores en este lenguaje. Para programar estructuradamente fue necesario crear un lenguaje universal a través del cual fuera posible programar y después traducir este lenguaje a algún lenguaje en particular. El resultado fue el pseudocódigo. El pseudocódigo abarca desde una versión muy burda del algoritmo hasta una versión que no presenta problema para ser codificada, es decir, tolera secciones de código en lenguaje natural y, a través de refinamientos sucesivos se va bajando el código de nivel semántico hasta que éste ya puede ser codificado. Utiliza sus propias estructuras de control las cuales, de acuerdo a lo que se encontró, son suficientes y necesarias para implementar cualquier algoritmo. Niclaus Wirth el creador de Pascal tuvo la idea de implementar un lenguaje que manejara las estructuras de control tal como estaban descritas en el pseudocódigo (o al menos casi) y así economizar esta traducción, por lo que programar en Pascal se convirtierte prácticamente en escribir los algoritmos en pseudocódigo. Con el pseudocódigo, como ya se mencionó, también se puede emplear la técnica de refinamientos sucesivos (o progresivos) que puede ser útil cuando no se tiene la idea completa del algoritmo. Cabe mencionar que el pseudocódigo no es la traducción al español del programa, el pseudocódigo es un lenguaje por derecho propio y solo tiene algunas diferencias con el lenguaje de programación Pascal. También cabe mencionar que el lenguaje C también es un lenguaje estructurado, pero, aunque las estructuras de control no son idénticas a las del pseudocódigo sí tienen su equivalencia uno a uno con él. Por lo tanto, como ya vimos, los pasos para la elaboración de un programa son: 1) Entender el problema 2) Hacer el análisis del mismo. 3) Programar en pseudocódigo el modelo de solución propuesto. 4) Codificarlo. 5) Cargarlo en la computadora para su ejecución y ajuste. 6) Darle mantenimiento durante su tiempo de vida.

Page 142: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

142

Se ha llamado al método anterior Método de Cascada, ya que haciendo la metáfora con una cascada, el método cae en cada nivel en un nivel de cascada, donde como en una cascada, no se puede regresar a una etapa anterior. Así, en el método de cascada, no se contempla un regreso a una etapa anterior, por lo que el método de cascada no contempla el regreso a pasos anteriores en caso de un error de diseño o de programación (cosa que generalmente pasa). Sin embargo, este método fue el primero que se desarrolló y es conveniente comenzar a programar con él cuando se es principiante (aunque acabemos regresando a etapas anteriores para hacer ajustes). Método de Desarrollo Descendente (Top-Down) Existe un método de desarrollo de programas muy poderoso llamado Método de Desarrollo Descendente o De Arriba A Abajo (Top –Down). Este método consiste en plantear en el programa principal una solución del problema desde el más alto nivel de abstracción. No es necesario que los procedimientos que se invoquen existan, únicamente es necesario saber que pueden desarrollarse después, es decir, que son descriptibles. Podemos proponer el siguiente probema, crear un programa que encuentre los primeros n números primos. Etapa 1) Comprender bien el problema. Se trata de que la computadora pregunte cuántos números primos desea el usuario y ella encuentre los números primos hasta completar el número de números primos que pide el usuario. Etapa 2) Hacer el análisis del problema. Para hacer el programa en realidad en este momento no necesitamos saber como se encuentra el siguiente número primo, únicamente es necesario saber que es posible invocar una función (que todavía no está creada) que nos diga si un número es primo o no y únicamente a través un contador llenar el requisito del usuario. Etapa 3) Programar en pseudocódigo el modelo de la solución propuesto. Podemos utilizar la Metodología Páez (o sea, la mía y lo ponemos con mucha humildad) para la creación de algoritmos iterativos. Esta metodología consta de los siguientes pasos: Si el problema tiene solución iterativa:

1° Encontrar cual es la o las instrucciones núcleo del algoritmo. 2° Preparar variables para el siguiente ciclo. 3° Encontrar la estructura de control de flujo que las envuelve. 4° Inicializar variables. 5° Entregar resultados.

Page 143: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

143

6° Declarar las variables y poner el nombre del programa, procedimiento o función.

Si el problema tiene solución recursiva entonces: 1° Encontrar el caso base 2° Desarrollar la parte recursiva del cuerpo del algoritmo

Como el problema tiene solución iterativa: 1° Encontrar cual es la instrucción núcleo o las instrucciones núcleo del algoritmo. Las instrucciones núcleo podrían ser las siguientes: si EsPrimo (Contador) entonces comienza Escribe (Contador) NmroDPrms ← NmroDPrms + 1 termina Observe que las instrucciones núcleo se escriben algo indentadas y en el centro de la hoja de papel o del área de trabajo para que podamos escribir lo que va alrededor indentando hacia la izquierda sin que nos vaya a faltar papel y así completar el programa. 2° Paso, preparar las variables para el siguiente ciclo. Como no sabemos antes de comenzar el bucle cuantas iteraciones se van a realizar las dos instrucciones que se pueden utilizar son “repite” y “mientras”, pero no el “ejecuta”. Escogeremos el “repite” ya que el ciclo o bucle se requerirá ejecutar al menos una vez. Como necesitaremos utilizar un contador y el “repite” no tiene autoincremento necesitaremos actualizar el contador para el siguiente bucle quedando el algoritmo de la siguiente manera: si EsPrimo (Contador) entonces comienza Escribe (Contador) NmroDPrms ← NmroDPrms + 1 termina Contador ← Contador + 1

3° Encontrar la estructura de control de flujo que las envuelve. Como mencionamos en el punto anterior, la estructura seleccionada será un repite, quedando el algoritmo de la siguiente forma: repite comienza si EsPrimo (Contador) entonces comienza

Page 144: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

144

Escribe(Contador) NmroDPrms ← NmroDPrms + 1 termina Contador ← Contador + 1 termina hasta (NumroDPrmos = NmroDPrmosUsrio) 4° Inicialización de variables. En este paso se observa qué variables requieren inicialización. Hay dos formas de inicializar una variable, una a través de un enunciado de asignación y otra a través de una lectura. Por lo tanto el algoritmo quedará: I ← 2 NmroDPrmos ← 0 Lee (NmroDPrmosUsrio) repite comienza si EsPrimo (Contador) entonces comienza Escribe (Contador) NmroDPrms ← NmroDPrms + 1 termina Contador ← Contador + 1 termina hasta (NmroDPrmos = NmroDPrmosUsrio) 5° Entrega de resultados. Existen algoritmos en donde se entrega el resultado hasta el final del algoritmo y otros como éste que al mismo tiempo que se van realizando las iteraciones se van entregando resultados, por lo tanto éste paso ya se realizó. 6° Declaración de variables, nombre del programa, procedimiento o función. Una vez que ya sabemos cuantas y cuales variables vamos a necesitar lo único que hay que hacer es declarar las variables. Solo tenemos que identificar con qué tipo de dato podemos representar cada variable. Al final del algoritmo terminamos con un punto final. De tal forma que el programa principal quedará de la siguiente forma:

Page 145: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

145

pograma NumerosPrimos declaraciones Contador, NmroDPrms, NmroDPrmsUsrio: entero comienza Contador ← 2 NmroDPrmos ← 0 Lee (NmroDPrmosUsrio) repite comienza si EsPrimo (Contador) entonces comienza Escribe (Contador) NmroDPrms ← NmroDPrms + 1 termina Contador ← Contador + 1 termina hasta (NmroDPrmos = NmroDPrmosUsrio) termina Podemos correr en papel nuestro algoritmo para probar que funciona.

El siguiente paso es definir la función “EsPrimo”, así que haremos este trabajo para que nuestro programa quede completo. Para poder contestar si un número es primo o no tenemos que consultar a la definición de ¿Qué es un número primo? Un número primo es un número natural que únicamente puede ser dividido por exactamente por dos número naturales, él mismo y la unidad. El número “1” no es considerado un número primo por definición. Se puede decir que la definición de un número primo se puede tomar también como una especificación. Lamentablemente todavía no podemos alimentar a las computadoras con especificaciones como ésta para que ellas puedan contestar preguntas o hacer el trabajo en base a la especificación. Los lenguajes que se han desarrollado para las computadoras no alcanzan a “comprender” todavía lo que se conoce como lenguaje natural (lenguaje en el que esta hecha la especificación anterior) y por lo tanto, será necesario re-escribir esta especificación para que la computadora la pueda procesar. Podemos cambiar la especificación para que sea más fácil representarla en términos computacionales re-escribiéndola de la siguiente manera: "Dado un número natural, si existe al menos un divisor entre la unidad y el número dado, dicho número no es primo, en otro caso, sí lo es".

Page 146: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

146

Esta especificación si es descriptible en términos computacionales ésta y ésto será todo lo que vamos a tener que hacer, revisar si existe un divisor intermedio entre la unidad y el número. A todas luces éste es un algoritmo iterativo por lo que podemos utilizar de nuevo la Metodología Páez para desarrollo de algoritmos iterativos. 1° Escribir la instrucción núcleo o instrucciones núcleo, es decir, la instrucción o instrucciones que se van a repetir muchas veces en el algoritmo pensando en una corrida con muchas iteraciones. Como ya mencionamos, esto se hace al centro del área de trabajo dejando un sangrado.

si N módulo Contador = 0 entonces Primo ← falso

Esto quiere decir que si encontramos un número cuyo residuo de dividir nuestro número y él es cero hemos encontrado al menos un número que divide en forma exacta a nuestro número por lo que la variable Primo tomará un valor falso. Observe también la forma de programar con si´s (if´s en inglés). Es posible crear otra función que se llame divisible para hacer más clara la definición. Esta función lo único que haría es recibir dos números y contestar “verdadero” si es que son divisibles y “falso” en caso contrario. El operador “módulo” generalmente tiene mayor precedencia que el operador “=” por lo que no se requieren los paréntesis. 2° Preparación de variables para el siguiente ciclo y actualización de variables. Para que los bucles se realicen adecuadamente es necesario actualizar variables al final de cada uno para que las variables estén en el número correcto en el siguiente, de otra manera podemos generar bucles infinitos.

si N módulo I = 0 entonces Primo ← falso Contador ← Contador + 1

Note que en pseudocódigo no se utilizan separadores de enunciado “;” a menos que dos enunciados estén en una linea. 3° Escribir la estructura de control que envuelve a la instrucción núcleo. Si se sabe de antemano cuantos bucles se van a ejecutar usar un “ejecuta”. Si no sabemos de antemano el número de bucles que realizará el ciclo lo más recomendable es utilizar un “repite” o un “mientras”. Si el ciclo no se debe realizar si la condición no se cumple entonces se utilizará un “mientras”.

Page 147: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

147

Si el ciclo se debe realizar al menos una vez se utilizará un “repite”. En este utilizaremos un “repite” pensando en de la siguiente manera:

repite comienza si N módulo Contador = 0 entonces Primo ← falso Contador ← Contador + 1 termina hasta Primo = falso o Contador >= N

4° Inicialización de variables. Es necesario inicializar variables, de otra manera puede ser que tengan basura ocasionando que nuestro algoritmo de resultados erróneos.

Primo ← verdadero Contador ← 2 repite comienza si N módulo Contador = 0 entonces Primo ← falso Contador ← Contador + 1 termina hasta Primo = falso o Contador >= N

Note que no se inicializa la variable “N”, ésta se inicializará en el paso de parámetros. Como ya mencionamos, en general todas las variables se deben inicializar, excepto en los casos “repite” en que la actualización se hace al inicio dentro del bucle y por lo menos se actualizará una vez la variable antes de llegar a una prueba de condición como en el caso de un menú como se verá más adelante. Si analizamos el algoritmo se comporta bien para casos mayores que 3, en el caso de “2” el algoritmo falla ya que el intervalo entre 2 y 2 es cero, y como la comparación se hace con respecto a N, el intervalo queda entre 2 y 1 por lo que sacaremos a 2 del algoritmo. Primo ← verdadero

si N > 2 y entonces comienza Contador ← 2 repite comienza si N módulo I = 0 entonces Primo ← falso Contador ← Contador + 1 termina

Page 148: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

148

hasta Primo = Falso o Contador >= N -1 termina

Es importante agregar algunos filtros para que el algoritmo se comporte bien con casos especiales todo tipo de entrada posible, por lo que quedaría de la siguiente forma:

Page 149: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

149

Primo ← verdadero si N > 2 entonces comienza si N <> 2 entonces comienza Contador ← 2 repite comienza si N módulo Contador = 0 entonces Primo ← falso Contador ← Contador + 1 termina hasta no Primo o Contador >= N termina termina otro Primo ← falso

5° Entrega de resultados. En general el sentido de todo algoritmo es entregar un resultado, por lo que es necesario poner una instrucción que escriba el resultado, de otra manera no sabremos que pasó adentro de la máquina, en este caso, el resultado de regresará en el nombre mismo de la función, así que no haremos nada ya que al finalizar el algoritmo el resultado quedará ya en el nombre de la función, no hay que hacer ninguna otra asignación.

Ya hemos terminado nuestro primer intento de algoritmo y ya podemos ponerle el comienza y termina de los extremos.

Page 150: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

150

comienza

Primo ← verdadero si N > 2 entonces comienza Primo ← verdadero Contador ← 2 repite comienza si N módulo Contador = 0 entonces Primo ← falso Contador ← Contador + 1 termina hasta no Primo o Contador >= N termina otro Primo ← falso regresa Primo

termina 5° Declaración de variables. Una vez que ya está terminado el algoritmo podemos declarar las variables. Esto es mejor que primero declarar variables y luego hacer el programa, puesto que todavía no sabemos que variables iremos a usar.

Page 151: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

151

declaraciones Contador: entero Primo: booleano comienza

Primo ← verdadero si N > 2 entonces comienza Contador ← 2 repite comienza si N módulo Contador = 0 entonces Primo ← falso Contador ← Contador + 1 termina hasta no Primo o Contador >= N regresa Primo termina otro

Primo ← falso regresa Primo termina

6° Nombre de la función

función EsPrimo (N: entero): booleano; declaraciones Contador: entero Primo: booleano comienza

Primo ← verdadero si N > 2 entonces comienza Contador ← 2 repite comienza si N módulo Contador = 0 entonces Primo ← falso Contador ← Contador + 1 termina hasta no Primo o Contador >= N regresa Primo termina otro

Primo ← falso regresa Primo

Page 152: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

152

termina Etapa 4) Codificar en turbo Pascal o C Este trabajo se le deja al estudiante. En esta etapa el código fuente debe constar con mensajes que hagan al programa amigable para el usuario. Etapa 5) Cargarlo en la computadora para su depuración, ajuste y pruebas. Cargarlo y depurar el programa de errores lexicográficos y sintácticos. Hacer pruebas al programa de casos simples y límite comenzando por el ejemplo más simple que se elaboró en la etapa 1 y/o 2 del desarrollo. A partir de éste momento ya podemos comenzar a depurar nuestro programa. Esto lo haremos corriendo el programa paso a paso con el depurador para ver si el programa hace lo que nosotros queremos. La primer prueba que haremos será alimentar el programa con el caso más simple. Comenzaremos pidiendo sólo un número primo. Lo primero que hará la herramienta para correr el programa paso a paso será compilar el programa. El compilador comprobará que el programa es un programa producido por su gramática. En caso de no serlo el compilador marcará errores en los casos en donde no pueda reconocer al programa. Si hay cosas extrañas pero salvables únicamente enviará advertencias (warnings). Será necesario que el programador remueva todos los errores para que el programa pueda correr. No será lo mismo con las advertencias, es responsabilidad del programador dejar las advertencias. Generalmente los errores que marca un compilador son errores sintácticos. Estos errores se producen cuando no se emplea el formato adecuado de las estructuras de control. Cada estructura de control tiene una sintaxis, es decir, un formato que tiene que ser respetado, de otra manera el compilador no la reconocerá como parte de su gramática. En cuanto a los refinamientos sucesivos se puede comenzar planteando el problema a grandes rasgos aunque éste no esté a un nivel semántico que la computadora pueda entender y poco a poco irlo bajando hasta que llegue al nivel codificable. Éste método requiere que existan barios borradores, cada uno de menor nivel semántico hasta tener la versión final que podrá ser codificada en un lenguaje de programación. Un ejemplo de este método lo encontramos en el problema de las ocho reinas que resuelve Gillermo Levine en su libro de Introducción a la Computación y a la Programación Estructurada en el capítulo 7 página 238. De nuevo, se pueden incluir los refinamientos sucesivos en nuestro método si se comienza editando el programa principal como un borrador en semilenguaje natural y poco a poco se va implementando el

Page 153: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

153

algoritmo con nombres de procedimientos que aún no existen pero que se desarrollarán más adelante.

Etapa 6) Mantenimiento del sistema, para los alcances de este curso este paso no lo realizaremos.

Page 154: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

154

Page 155: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

155

EJERCICIOS CAPÍTULO 10 Fecha de entrega: ______________

Nombre: ________________________________________________________________

Número de aciertos: 12

1.- Codifique el programa que encuentra los primeros n números primos que el usuario

solicita en Pascal y C, cárguelo, depúrelo y pruébelo.

2.- Escriba los programas que calculen las siguientes funciones con un error menor al que

solicite el usuario (presición) con la siguiente condición de paro: El error del valor

calculado por el programa debe ser menor que el error solicitado por el usuario. El criterio

de error puede ser el siguiente: El error calculado puede ser el valor de la mitad del último

término sumado. Observe que en las series un término es positivo y otro es negativo por

lo que se debe tomar el valor absoluto del término y por lo que el valor real debe estar a

una distancia menor al último valor sumado del último valor calculado. Ejemplo: el primer

valor para la serie del seno es x por lo que si comenzamos de cero, la incertidumbre para

la primera iteración es x/2, es decir el valor calculado es x ± x/2. En las sigientes

iteraciones la incertidumbre se irá reduciendo tanto como se reduzcan los términos.

Observe que los términos se reducen muy rápido ya que se dividen entre la función

factorial y la función factorial es la que crece más rápido. Utilice funciones para calcular

las potencias y los factoriales y utilice longint para el tipo de dato de la función factorial,

ya que ésta crece muy rápido. El valor de x está dado en radianes. 360° equivalen a 2π

radianes. Ejemplo: 180 ° = 3.1416.

Ejemplo de pregunta: Calcule el valor del seno de 0.5 radianes con un error menor a 0.1?

Page 156: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

156

Llene la siguiente tabla con sus resultados.

Grados Radianes Seno con precisión <

0.1

Error Seno con precisión <

0.01

Error

0 0

30 π/6

45 π/4

57.29 1

60 π/3

90 π/4

Grados Radianes Seno con precisión <

0.001

Error Seno

0 0 0.000000

30 π/6

45 π/4 0.7071

57.29 1

60 π/3

90 π/4 1.00000

n

sen x = Σ -1 (i-1) x (2 i - 1) = +x1 - x3 + x5 - ……

i = 1 (2 i - 1) ! 1! 3! 5!

Page 157: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

157

Grados Radianes Coseno con

precisión de 0.1

Error Coseno con

precisión < 0.01

Error

0 0

30 π/6

45 π/4

57.29 1

60 π/3

90 π/4

Grados Radianes Coseno con precisión a

0.001

Error Coseno

0 0 1.000000

30 π/6

45 π/4 0.7071

57.29 1

60 π/3

90 π/2 0.00000

n

cos x = Σ -1 (i-1) x (2 i - 2 ) = +1 – x2 + x4 - ……

i = 1 (2 i - 2) ! 0! 2! 4!

n

ex = Σ -1 (i - 1)_x (i-1) = +x0 – x1 + x2 - ……

i = 1 (i - 1)! 0! 1! 2!

Page 158: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

158

n

ln ( 1 + x ) = Σ -1 (i - 1) x i = +x1 – x2 + x3 - ……

i = 1 i 1! 2! 3!

Nota: todos los programas deben ser amigables, deben contener documentación interna,

no deben contener errores tipográficos, ni ortográficos, deben respetar las buenas

prácticas de programación y deben respetar la convención dependiendo del lenguaje

utilizado.

Page 159: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

159

11.- ARREGLOS, CADENAS Y REGISTROS. Hasta ahora sólo hemos trabajado con los tipos de datos básicos, enteros, reales, caracter y booleanos. Con todos estos datos es posible construir arreglos, cadenas y estructuras. ARREGLOS Un arreglo es un conjunto de datos organizados en forma de celdas. La celda de un arreglo se puede acceder mediante una constante o una variable llamada índice. Un índice es una variable entera por medio del la cual se puede seleccionar la celda que se va a acceder. En Pascal y en todos los lenguajes en general los compiladores no proporcionan los arreglos inicializados a cero, por lo que si un arreglo se va a emplear es importante que exista una sección que inicialice todas las celdas antes de comenzar a trabajar con él.

En Pascal un arreglo se declara de la siguiente manera: var A: array [1..5] of integer; en donde se declara un arreglo de enteros de tamaño 5. En C un arreglo se declara de la siguiente manera: int a[4]; en donde se indica que la variable a es un arreglo de enteros decinco elementos, de 0 a 4.

En Pascal es posible declarar un arreglo de la dimensión deseada únicamente agregando la siguiente dimensión seguida de comas dentro del paréntesis cuadrado. Ejemplo: si se requiere declarar un arreglo de enteros de dimensión dos de tamaño 10 se hace de la siguiente manera: var A: array [1..10, 1..10] of integer; En C es posible declarar un arreglo de dos dimensiones de la siguiente manera: int a[4][4]; En Pascal, si se agregan dimensiones se puede tener un arreglo de la dimensión que se requiera. Ejemplo:

Page 160: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

160

A: array [1..10, 1..10, 1..10] of integer; En este caso A es un arreglo de enteros de dimensión tres de tamaño 10. En C se hace de la siguiente manera: int a[9][9][9]; En C el sentido que se les da a los arreglos es que un arreglo de dos dimensiones es un arreglo de arreglos, un arreglo de tres dimensiones es un arreglo de arreglo de arreglo del tipo especificado. Es importante mencionar que la computadora tiene una memoria principal finita y que si los arreglos son demasiado grandes pueden generar problemas en la ejecución del programa, por lo que no es muy conveniente declarar arreglos exageradamente grandes. El acceso a los elementos de los arreglos generalmente se hace a través de índices como ya lo mencionamos. Por ejemplo, si queremos inicializar todo el arreglo con ceros tendríamos que hacer lo siguiente: Como sabemos de antemano cuantos ciclos vamos a ejecutar nos conviene utilizar la estructura de control “ejecuta” Ejecuta I = 1, 10 Ejecuta J = 1, 10 A [I, J] = 0

En Pascal se haría de la siguiente forma: for I := 1 to 10 do for J := 1 to 10 do A [I, J] := 0;

En C es de la siguiente manera:

for (i = 1; i < 9; ++i) for (j = 1 ;to I < 9; ++i) a [i] [j] = 0; Con los arreglos es posible representar todo tipo de cosas que se muevan sobre un tablero, ejemplo, damas inglesas, ajedrez, gato y también elementos matemáticos como matrices. Ya habiendo definido lo que es un arreglo se puede crear algoritmos que busquen un elemento en el arreglo. A tales algoritmos se les llama atgoritmos de búsqueda. O que ordenen el arreglo ya sea de mayor a menor o de menor a mayor, A tales algoritmos se

Page 161: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

161

les llama algoritmos de ordenamiento. Los algoritmos de ordenamiento son ejemplos muy útiles para ilustrar el uso de arreglos. Los algoritmos de búsqueda son muy importantes ya que sin ellos sería imposible acceder a los datos en los grandes sistemas en tiempos prácticos. Los algoritmos de búsqueda más simples son el algoritmo de búsqueda secuencial y el de búsqueda binaria. Existen varios algoritmos de ordenamiento, uno de los más famosos es el método de la burbuja que consiste en pasar recorridos de ordenamiento de dos a la vez por todo el arreglo hasta que el arreglo quede perfectamente ordenado. Se le llama de la burbuja ya que en cada pasada el elemento mayor queda al final de la sección del arreglo que se está ordenando, es decir, se va moviendo hacia arriba de la misma forma que lo hace una burbuja. El inconveniente de éste algoritmo es que se realizan muchos cambios para poder ordenar el arreglo. Es extremadamente simple en líneas de código pero no es el más eficiente. El algoritmo es el siguiente:

En pascal el algoritmo se escribe así: for I := 1 to Limite -1 do for J := 1 to Limite - 1 do if A [J] > A [J +1] then begin Temp := A [I]; A [I] := A [I +1]; A [I+1] := Temp end; En C el código es el siguiente: for (i = 0; limite –1; ++limite) for (j = 0; limite-1; ++limite) if (a [j] > a [j+1]) { temp = a [i]; a [i] = a [i +1]; a [I + 1] = Temp; }; También existen otros algoritmos de ordenamiento como el Insertion Sort, Selección Sort, y el Shell Sort, y algoritmos recursivos como el Quick Sort y el Merge Sort. El Inserton Sort consiste en considerar que la lista va creciendo a partir de un elemento y que la lista está ordenada, de tal manera que cada vez que se agrega un elemento a la lista, se sacará el elemento de la lista poniéndolo en una variable temporal,

Page 162: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

162

generando ésto un hueco. Se desplazan todos los elementos de la lista mayores a éste, de tal forma que el hueco quede en la posición donde le corresponde al nuevo elemento y ahí será donde se inserte, de ahí el nombre de Insertion Sort. El algoritmo termina cuando se inserta el último elemento de la lista. Se tiene la lista completa, pero por medio de indices se tiene una sublista que en un principio es de un elemento. En la medida que el índice va creciendo la lista va aumentando y en esa lista es en donde “se incerta el siguiente elemento”, como mencionamos esto se hace a través de corrimientos. En los inicios de la computación estos algoritmos de ordenamiento jugaron un papel preponderante ya que una de las primeras habilidades que se pueden explotar en la computadora es su capacidad de ordenar y clasificar información en forma masiva, ésto fue tan importante que en España a las computadoras hasta la fecha se les llama “ordenadores”. Los primeros algoritmos de ordenamiento que se crearon fueron muy intuitivos pero poco eficientes y poco a poco se fueron elaborando algoritmos más complejos en base a la experiencia de los primeros. En cuestión de ordenamiento no se puede decir que un algoritmo es categóricamente mejor que otro, solo se puede decir que para algunos casos es mejor uno y para otros otro. Aquí mostraremos de nuevo el programa de las torres de Hanoi ya que para resolver este problema se requieren arreglos. Como recordamos el programa es el siguiente y lo único que agregaremos es el procedimiento MueveDisco el cual es implementado con arreglos que operan como pilas. Una pila es un arreglo visto en forma vertical en donde el elemento con el índice menor se encuentra abajo y el elemento con el índice mayor se encuentra arriba. La pila requiere de una variable apuntador que apunta al elemento que se encuentra en el tope de la pila. Este índice se inicializa con 1 si se implementa en Pascal y en 0 si se implementa en C. Cada vez que se ingresa un elemento a la pila se incrementa primero se almacena en la celda apuntada por él la información y luego se incrementa el índice. Cuando se extrae un elemento de la pila primero se decrementa el apuntador en una unidad se utiliza la información apuntada por el apuntador. Como se requieren tres pilas se requieren tres apuntadores. Estos apuntadores son variables de tipo entero. programa Hanoi comienza MuevePila (A, C, B, ApA, ApC, ApB, H) termina Donde el poste de la izquierda se representa por A, el de en medio por B y el derecho por C, ApA, ApC, ApB son apuntadores que indican el tope de las pilas A, B, C. procedimiento MuevePila (var Fuente, Destino, Paso: arreglo; var ApA, ApC, ApB: entero H: entero) comienza

Page 163: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

163

si H = 1 MueveDisco (Fuente, Destino, ApF, ApD) otro comienza Mueve Pila (Fuente, Paso, Destino, ApF, ApP, ApD, H - 1) MueveDisco (Fuente, Destino, ApF, ApD) MuevePila (Paso, Destino, Fuente, ApP, ApD, ApF, H - 1) termina termina Mueve Disco (var Fuente, Destino, ApF, ApD: arreglo) comienza ApF ← ApF - 1; Destino[ApD] ← Fuente[ApF]; Fuente[ApF] ← 0; ApD ← ApD + 1 termina La inicialización de las estacas y el despliegue de las estacas se le deja al estudiante. CADENAS En Pascal al tipo de dato cadena se le llama string, en realidad es un arreglo de caracteres unidimensional del tamaño que el usuario requiera. Pero ¿por qué son necesarias las cadenas de caracteres? En realidad una variable caracter no nos serviría de mucho ya que generalmente el lenguaje se escribe por medio de cadenas de caracteres, éste texto por ejemplo está compuesto de cadenas de caracteres. El caso más común de cadenas de caracteres es una lista de nombres. También, gracias a las cadenas se pueden escribir los programas para computadora.

En Pascal es posible manejar cadenas como si fueran números, es decir, se pueden utilizar los operadores relacionales entre dos cadenas como se hace con variables numéricas. No es necesario utilizar funciones especiales para comparar cadenas. Por ejemplo es posible saber por medio de un relacional qué cadena va después de otra en orden ascendente.

También es posible manipular los caracteres de una cadena individualmente de tal forma que se pueden crear juegos como el ahorcado en donde el usuario tiene que adivinar la cadena oculta únicamente proporcionando en cada tirada un caracter. Si el caracter se encuentra en la cadena éste y su o sus posiciones en la cadena se irán revelando al usuario a través de la pantalla. También es posible representar cadenas de moléculas por medio de cadenas y buscar ciertas secuencias. La forma de declarar una cadena en Pascal es: Nombre: string [20];

Page 164: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

164

La forma de referirse a un elemento de la cadena Nombre es: WriteLn (Nombre[1]); Esta instrucción despliega el primer caracter de la variable Nombre. También es posible copiar cadenas. La forma de hacerlo es la siguiente: Nombre1 := Nombre2; En fin, las cadenas de caracteres juegan un papel fundamental en la programación. Las cadenas en C se manejan como arreglos de caracteres. El tipo string no existe en C por lo que lo que se hace es definir un arreglo tipo char. Existe una librería que contiene funciones para manejar cadenas. La librería es <string.h>.

En ella se cuenta con las funciones siguientes: strcat (s, t) concatena t al final de s strncat (s, t) concatena n caracteres de la cadenta t después de la cadena s strcmp (s, t) regresa negativo, cero, o positivo para s < t, s = t, s > t strncmp (s, t, n) igual que strcmp pero solo en los primeros n caracteres strcpy (s, t) copia t en s strlen (s) regresa la longitud de s strchr (s, c) regresa un apuntador al primer t que esté en s, o NULL si no está presente strrch (s, c) regresa un apuntador al último c que esté en s o NULL si no está presente REGISTROS Un registro es una estructura de datos que puede estar formada de conjuntos de datos del mismo tipo, como por ejemplo vectores, en donde cada vector puede tener dos o más coordenadas o de diferente tipo como los registros de clientes de una base de datos bancaria que contienen cadenas de caracteres (simplemente cadenas), enteros y datos tipo moneda. Este tipo de dato es útil cuando se requiere guardar información conformada con datos de diferente tipo que tienen un valor útil siempre y cuando estén juntos. Los datos de una persona están formados por tipos de datos de diferente tipo. Por ejemplo el nombre y la dirección se pueden representar por cadenas mientras que la edad se puede representar un entero. A cada uno de los elementos de un registro se le llama campo.

Page 165: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

165

Registro Campo 1 Campo 2 Campo 3 Campo 4 Campo 5 Generalmente en las bases de datos la información se almacena con éstos tipos de datos, es decir con “registros”, por lo que es importante mencionarlos en este capítulo. Mencionamos anteriormente la enorme capacidad de la computadora de buscar en grandes volúmenes de información de manera muy rápida. Esta capacidad se explota principalmente en lo que se conocen como Bases de Datos. Una Base de Datos es un conjunto de archivos que almacenan información que está relacionada entre si de una organización, empresa, organismo gubernamental, etc. En nuestro caso utilizaremos bases de datos de un solo archivo más adelante. Éste archivo lo iremos llenando con registros. Cuando necesitemos consultar nuestra base de datos consultaremos los registros para recuperar la información deseada. En este capítulo no construiremos la base de datos, por el momento lo único que nos interesa es que el estudiante se familiarice con este tipo de dato. Para declarar en Pascal un tipo de dato registro se hace lo siguiente: type persona = record Nombre: string [30]; Direccion: string [40]; Telefono: string [10] end; var Empleado: persona; La lectura de la información se debe hacer por campo. Para referirse a los campos de una variable registro se hace lo siguiente: ReadLn ( Empleado.Nombre); Es decir, se hace poniendo el nombre del registro seguido de un punto seguido del nombre del campo que queremos manipular. Pascal proporciona una manera de evitar reescribir varias veces el nombre del registro con el que se va a trabajar. Esto se hace por medio de la proposición with. La sintaxis es la siguiente:

Page 166: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

166

with identificador de registro do proposición

Page 167: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

167

Ejemplo: with Empleado do begin WriteLn (Nombre); WriteLn (Direccion); WriteLn (Telefono); end En un sistema de empleados generalmente se crea una estructura “Empleado” y un archivo de estructuras de tipo “Empleado”. No es necesario tener toda el archivo simultaneamente en memoria principal ya que generalmente vamos a trabajar con la información de un solo empleado y, si el archivo es muy grande no nos cabría en la memoria principal, por lo que solo se utilizan dos estructuras, una donde se cargan los datos de la estructura a buscar (en el caso de una búsqueda) y otra donde se van cargando las diferentes estructuras del archivo y se va comparando hasta que uno de los campos coincide con el campo de la estructura que se acaba de leer. La búsqueda se puede hacer por nombre o por alguna clave o número de empleado. A cada archivo en la teoría de las Bases de Datos se llama Tabla. Una Base de Datos consiste en un conjunto de Tablas que almacenan toda la información de la organización y Tablas que a su vez representan una relación entre las “Entidades”.

Una entidad es un objeto distinguible que tiene ciertos atributos (campos) que pertenece a alguna categoría. Por ejemplo “Empleado” es una persona que pertenece a la clase “Empleado” de una organización. Todo esto se puede ver con más detalle en la materia de Bases de Datos. En un principio la base de datos está vacía y se tiene que llenar con datos útiles, pero una vez que la base ya está cargada el trabajo sobre ella es dinámico, se dan de alta empleados, se dan de baja empleados, se actualizan datos, se hacen listados, etc.

Por lo pronto lo que nos interesa mostrar son las estructuras y su uso. En C a los “registros” se les llama “estructuras” (struct). Una estructura se declara

de la siguiente manera: struct point { int x; int y; } Para declarar una variable de tipo estructura: struct point pt;

Page 168: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

168

Se hace referencia a un miembro de una estructura en particular en una expresión con una construcción de la forma:

nombre-estructura.miembro Entonces, para acceder a un campo de una estructura se utiliza el operador

miembro de estructura “.” que conecta al nombre de la estructura con el del miembro. Por ejemplo para leer un miembro de una estructura se emplea la siguiente instrucción:

scanf (“%d”, &pt.x); y para desplegar un miembro de una estructura hace de la siguiente manera: printf (“%d”, pt.x); Para declarar un arreglo de estructuras se utiliza la siguiente sintaxis: struct struct_name { field variable_name; . . } array_name [domention]; El código anterior es equivalente a: struct struct_name { field variable_name; . . } struct struct_name array_name [dimention]; La inicialización de un arreglo de estructuras puede ir seguida por un signo “=” y

una lista de constantes separadas por comas y enmarcadas entre llaves. También se puede definir un tipo de dato nuevo tipo estructura de la siguiente

forma: typedef struct name_type { fields }

Finalizamos el capítulo diciendo que los “arreglos” y los “registros” o “estructuras”

constituyen una parte fundamental de la programación ya que con ellos ha sido posible

Page 169: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

169

hacer reprecentaciones matriciales y almacenar información de objetos con diferentes atributos.

Page 170: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

170

Page 171: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

171

EJERCICIOS CAPÍTULO 11 Fecha de entrega: ______________ Nombre (comenzando por el apellido): _______________________________________

1.- Suponga que tiene una caja con cinco casilleros numerado del 1 al 5 y cinco bolas de

pull de billar, es decir, bolas numeradas, no necesariamente seguidas. ¿Sería usted

capaz de ordenar las bolas en orden ascendente? Escriba el algoritmo que usted utiliza

en pseudocódigo utilizando el método de diseño descendente que ordene las bolas en

orden ascendente.

(Tip: analice qué es lo que usted hace para ordenarlas y escríbalo en términos

computacionales, si esto no ayuda escriba lo que usted hace en lenguaje natural paso a

paso y luego escríbalo en términos computacionales, identifique lo que se hace

iterativamente)

2.- Codifique el algoritmo en Pascal y C.

3.- Cárgelo y pruébelo.

4.- Sustituya el 5 por una constante “limite = 5” al inicio y sustituya todos los 5 por “limite”

en el algoritmo y corralo.

5.- Ahora cambie “límite” por 10 y vea que funciona el programa. Escriba que utilidad

tiene hacer esto.

6.- Optimice el algoritmo anterior.

7.- Cambie el algoritmo para que trabaje con cadenas.

8.- Haga un programa para ordenar una lista de n números por medio del método de la

burbuja.

9.- Haga un programa para ordenar una lista de n números por medio del método de

inserción. Imagine que se encuentra jugando cartas. Piense qué es lo que hace un

jugador para ordenar sus cartas. Se toma la primera como referencia. Se comienza con la

segunda. Si es menor que la primera se recorre la primera y se inserta la segunda, si no

se deja en su posición. Luego se toma la tercera y se le busca posición que puede ser

antes de la primera, entre la primera y la segunda o después de la segunda y se inserta.

Esto se hace hasta que la última carta ha sido insertada en su posición, de aquí su

nombre de insertion sort algorithm.

10.- Escriba un programa que despliegue el cuadro mágico de la dimensión que quiera el

Page 172: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

172

usuario. El cuadro mágico es un cuadro en el que todas sus columnas y todos sus

renglones suman lo mismo. El cuadro mágico lo puede elaborar con arreglos de tamaño

impar. En la casilla del centro pone el número 1, el siguiente número lo pondrá arriba a la

derecha siempre y cuando la celda no esté ocupada. Si la celda ya está ocupada lo

pondrá abajo de la casilla en turno. Si se sale del cuadro al hacer el cálculo del siguiente

lugar reentre por el lado contrario, es decir, si se sale por arriba, reentre por abajo, si se

sale por el lado derecho, reentre por el lado izquierdo hasta colocar el último número.

Después de hacer esto la suma cada una de las columnas y de cada uno de los

renglones dará el mismo número.

11.- Escriba un programa que sume matrices.

12.- Escriba un programa que multiplique matrices.

13.- Escriba un programa en donde se declare una arreglo de 10 registros, en donde el

registro se llame “persona” y en donde tenga los siguientes campos: nombre: cadena 30,

dirección: cadena de 40, edad: entero, teléfono: cadena de 15, celular: cadena de 15,

correo electrónico: cadena de 25 y página web: cadena de 20. El programa debe de leer

los campos de cada persona y almacenarlos. El programa debe presentar un menú en

donde haya un procedimiento para leer un registro, otro para editar un registro y otro para

desplegar todo el arreglo de registros.

Page 173: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

173

12.- MODO GRÁFICO. Las interfaces hombre máquina han ido cambiando y evolucionado conforme a ido pasando el tiempo. En un principio la comunicación con la computadora era mediante tarjetas perforadas. Después se hizo interactiva a través de monitores y finalmente se convirtió en gráfica haciendo uso de iconos y botones. El modo gráfico ofrece una alternativa más colorida de comunicación con el usuario. Es posible pintar líneas, círculos y hasta hacer animación en la pantalla. La graficación en modo gráfico se hace a través de pixeles. Un pixel (picture element) es un punto de la pantalla. Es posible ordenarle a la computadora pintar un pixel del color que nosotros queramos en cualquier punto de la pantalla. Generalmente la pantalla es una matriz de 639 por 479 pixeles. El pixel (1,1) es el pixel que se encuentra en la parte superior izquierda de la pantalla y el pixel (639, 479) se encuentra en la parte inferior derecha de la pantalla. Debido a que las coordenadas en el eje Y crecen de arriba hacia abajo y que el punto (1, 1) está a la izquierda de la pantalla es necesario hacer una inversión de “Y” y un desplazamiento de 238 pixeles hacia abajo y 218 en X en caso de querer hacer graficación de una línea recta cuyo centro pase por el centro de la gráfica. Lo primero que tenemos que hacer para manejar el modo gráfico es declarar en el uses la librería Graph, esto se hace mediante la siguiente instrucción:

uses Graph; Después declarar las variables GraphDriver y GraphMode como tipo entero: var GraphDriver, GraphMode: integer; Posteriormente inicializar GraphDriver con la función Detect; GraphDriver := Detect; Finalmente inicializar el modo gráfico con la instrucción InitGraph, su sintaxis es la siguiente: InitGraph (GraphDriver, GraphMode, PathToDriver); Donde GraphDriver es el argumento que indica el manejador de video que se desea emplear y GraphMode es la constante que indica el modo gráfico deseado. PathToDriver es la ruta donde se encuentra el archivo el manejador de la interfase gráfica

Page 174: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

174

que en la actualidad utilizando un monitor SuperVGA es EGAVGA.BGI. Este archivo generalmente se encuentra en la ruta C:\TP\BGI\. El procedimiento Detect detecta por nosotros cual es el manejador de video que más conviene utilizar y hace que GraphMode sea el modo de más alta resolución posible. Generalmente el manejador más utilizado que Detect envía como resultado es el EGAVGA.BGI. Ejemplo: InitGraph (GraphDriver, GraphMode, 'C:\TP\BGI\'); En la versión 7.0 de Turbo Pascal para Windows a veces presenta algunos problemas cuando se corre el modo gráfico y estos problemas dependen de la máquina y del sistema operativo que esté corriendo ya que Turbo Pascal fue originalmente diseñado para correr bajo MS-DOS. Por ejemplo en Windows Milenium y Windows 2000 al agregar el FDelay sí corren los programas pero no puede ejecutarlos paso a paso, reporta que no encuentra un archivo fuente en TP\SURCE\FDELAY.PAS, así que se puede crear archivo con ese nombre y ponerlo en éste directorio y correr sus programas paso a paso. Como se pudo observar para inicializar el modo gráfico en el procedimiento InitGraph uno de los argumentos es el manejador de la interfase gráfica (GraphDriver). El manejador es un programa que se encarga de manejar el periférico en cuestión, en éste caso la interfase gráfica (el monitor) y al que el programa le envía comandos gráficos para que éste a su vez los traduzca al código del periférico. Éste manejador es diferente para cada tipo de monitor. Conforme han ido evolucionando los monitores desde blanco y negro y resoluciones bajas hasta los monitores de color y de alta resolución que hoy conocemos se han ido desarrollando los diferentes manejadores. El tipo de monitor más común que se maneja actualmente es el SuperVGA por lo que el manejador más utilizado es el EGAVGA.BGI que soporta este monitor. Lo primero que hace el procedimiento es buscar el manejador en el directorio donde se encuentra el programa, pero si no lo encuentra lo busca en la ruta de acceso (path) que se da como el tercer argumento en InitGraph y si no lo encuentra ahí el programa marcará un error. Pero si se requiere que el programa corra independientemente en un disco flexible será necesario agregar el manejador al disco. Para saber cuales son los valores máximos de X y Y se utilizan las siguientes funciones: GetMaxX; y GetMaxY;

Page 175: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

175

Los colores disponibles son los siguientes: Black (0) Negro Blue (1) Azul Green (2) Verde Cyan (3) Azul Cianuro Red (4) Rojo Magenta (5) Magenta Brown (6) Café LightGray (7) Gris Claro DarkGray (8) Gris Oscuro Light Blue (9) Azul Brillante LightGreen (10) Verde Brillante LightCyan (11) Cyan Brillante Light Red (12) Rojo Claro Light Magenta (13) Magenta Claro Yellow (14) Amarillo White (15) Blanco A continuación pondremos un programa para gráficar una función de grado 3, aunque se puede expandir fácilmente a funciones de grado n. program GraphFunction; {program edited by Sergio Páez Rodea Date of Edition: 20140318 Last modification: 20141104 Ver: 1.1} uses FDelay, CRT, Graph; const VctrLngth = 3; type Vector = array [0..VctrLngth] of double; function Pot (X: double; I: integer): double; begin if I = 0 then Pot := 1 else Pot := X * Pot (X, I - 1) end; function F (var C: Vector; Grade: integer; X: double): double; var Acumulator: double; I: integer; begin

Page 176: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

176

Acumulator := 0; for I := 0 to Grade do Acumulator := Acumulator + C[I] * Pot (X, I); F := Acumulator; end; procedure ReadVector (var C: Vector; Grade: integer); var I: integer; begin for I := 0 to Grade do begin Write ('C ', I , ': '); ReadLn (C [I]) end end; {main} var GrphDriver, GrphMode, ErrCode, XMAx, YMax, Grade, X, YScreen, Y2, XScreen, LeftX, RightX, ShiftX: Integer; Delay1: LongInt; C: Vector; Y: real; begin Grade := 3; {Write ('grade: '); ReadLn (Grade);} ReadVector(C, Grade); {Write ('BottomX: '); ReadLn (LeftX);} LeftX := -318; {Write ('RightX: '); ReadLn (RightX);} RightX := 318; ShiftX := 318; {BottomLmt := 1;} {ReadLn (BottomLmt);} {TopLmt := 639;} {ReadLn (TopLmt);} Delay1 := 0; GrphDriver := Detect; InitGraph(GrphDriver, GrphMode,'C:\TP\BGI'); ErrCode := GraphResult; if ErrCode = grOk then begin { Do graphics }

Page 177: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

177

XMax := GetMaxX; YMax := GetMaxY; Line (1, YMax div 2, XMax, YMax div 2); Line (XMax div 2, 1, XMax div 2, YMax); for X := LeftX to RightX do begin Y := F (C, Grade, X); Y2 := Round (Y); YScreen := YMax div 2 - Y2; if YScreen < 1 then YScreen := 1 else if YScreen > 479 then YScreen := 479; XScreen := X + ShiftX; PutPixel (XScreen, YScreen, Yellow); Delay (Delay1); end; repeat until KeyPressed; CloseGraph; end else Writeln('Graphics error:', GraphErrorMsg(ErrCode)); end. A continuación mostraremos una corrida de este programa con C2 = 1x 10-2 y C3 = 1 x 10 -4.

Page 178: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

178

A continuación pondremos algunos procedimientos y funciones que se pueden utilizar en el modo gráfico. INSTRUCCIONES GRÁFICAS

SetColor (Color) Establece el color a utilizar en los procedimientos. SetBkColor (Color) Establece el color del fondo. PutPixel (X, Y, Color) Pinta un pixel en la pantalla. MoveTo (X,Y) Mueve el cursor a estas coordenadas. MovRel (X, Y) Mueve el cursor X, Y unidades del actual. Line (X1, Y1, X2, Y2) Pinta una línea de las coordenadas iniciales a las

finales.

Page 179: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

179

LineTo (X2, Y2) Pinta una línea de las coordenadas actuales a las indicadas.

SetLineStyle (LineStyle) Establece el tipo de línea a pintar. Rectangle (X1, Y1, X2, Y2) Pinta un rectángulo en la pantalla entre las

esquinas dadas. Circle (X, Y, Radius) Pinta un circulo de radio R con centro en X, Y. Ellipse (X, Y, StAngle, EndAngle, XRadius, YRadius) Pinta una elipse en las

coordenadas X, Y en el ángulo de inicio, con ángulo de terminación, con radio en X XRadius y con radio en Y en YRadious.

Arc (X,Y, StAngle, EndAngle, Radius) Pinta un arco en X, Y con ángulo de inicio StAngle, ángulo de terminación EndAngle y radio Radius.

Sector (X, Y, XRadius, YRadius, StAngle, EndAngle) Pinta un sector con centro X,Y, radio en X XRadius y radio en Y YRadius, ángulo de inicio StAngle y ángulo de terminación EndAngle. PieSlice (X, Y, StAngle, EndAngle, Radius) Pinta un sector similar al anterior pero relleno. COLOREAR Y RELLENAR Los patrones del tipo de rellenado son los siguientes EmptyFill (sólido, con el color del fondo) SolidFill (sólido, con el color especificado) LineFill (se rellena con guiones) LtSlashFill (se rellena con ///) SlashFill (se rellena con /// gruesas) LtBkSlashFill (se rellena con ///) BkSlashFill (se rellena con \\\ gruesas) HatchFill (se rellena con un ligero sombreado) XHatchFill (se rellena con un sombreado denso) InterLeaveFill (intercala líneas)

Page 180: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

180

WideDotFill (se rellena con puntos muy dispersos) CloseDotFill (se rellena con puntos distribuidos densamente) UserFill (patrón de rellenado definido por el usuario) INSTRUCCIONES PARA EL COLOREADO Y RELLENADO SetFillStyle (FillType, Color) establece el tipo de rellenado y el color. FloodFill (X, Y, Color) rellena una región determinada por un punto de la región y el color de la frontera. TEXTO EN UNA PANTALLA GRÁFICA SetTextStyle (Font:Word; Direction: word; CharSize: word); Es para seleccionar el tipo de imprenta y el tamaño para los caracteres. El parámetro Font puede ser uno de los siguientes: DefaultFont TriplexFont SmallFont SansSeriFont GothicFont

La primera opción se refiere al tipo de letra basado en los bits, el resto corresponden a tipos de letra con un trazo particular. El parámetro Direction puede tomar uno de los siguientes valores: HorizDir VerDir El parámetro CharSize tiene un valor definido por omisión de 1 para el tipo de letra con base en los bits y 4 para tipos de letra con cierto trazo. Se pueden elegir otros valores para tamaños mayores de tipos. SetTextJustify (Horiz, Vert: word);

Page 181: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

181

Establece la forma en que se debe colocar el caracter en relación con el pixel. De manera horizontal el pixel puede estar en la esquina izquierda, el centro o la esquina derecha del caracter, mientras que verticalmente el pixel puede estar en la esquina superior, al centro o en la esquina inferior del caracter. Las opciones de Horiz son: LeftText (alineado a la izquierda) CenterText (centrado) RightText (alineado a la derecha) Las opciones para Vert son: BottomText (abajo) CenterText (centrado) TopText (arriba) OutText ('String'); Envía la cadena a la posición donde esté el apuntador activo. OutTextXY (X1, Y1, 'String'); Envía la cadena a la posición indicada con coordenadas en modo gráfico. ALMACENAMIENTO Y RECUPERACIÓN DE IMÁGENES ImageSize (X1, Y1, X2, Y2): integer; Esta función regresa el número de bytes necesarios para almacenar la imagen en el rectángulo indicado en los parámetros en el modo gráfico activo. GetImage (X1, Y1, X2, Y2, Variable); Este procedimiento almacena el rectángulo indicado en la variable de tipo arreglo. PutImage (X1, Y1, Variable, CopyPut) Esta instrucción copia el rectángulo en las coordenadas indicadas tomado de la variable indicada. El último parámetro índica la forma de ser copiada. CopyPut indica que la imagen se copiará sorbe los pixeles existentes. EL PUERTO DE VISUALIZACIÓN Y RECORTE

Page 182: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

182

SetViewPort (X1, Y1, X2, Y2: integer; Clip: boolean); Es para exhibir gráficas en una porción rectangular de la pantalla. El parámetro Clip determina si las operaciones de dibujo son recortadas en las fronteras del puerto de visualización. Clip puede tomar los valores de ClipOn o ClipOff. El puerto de visualización definido por omisión está en las coordenadas (0, 0, GetMaxX, GetMaxY) sin recorte. Esta instrucción también se usa en los juegos cuando se quiere actualizar solo una parte de la pantalla. ClearViewPort; Es para eliminar el puerto de visualización activo y mover el apuntador activo a (0, 0). SONIDO Write (Chr (7)); Es para emitir un bip por la bocina. El llamado a procedimiento Sound (n) emite un sonido de frecuencia n. El llamado a procedimiento NoSound corta el sonido que se este emitiendo. Para calcular frecuencias de las notas musicales se usa la siguiente función exponencial: f (n) = F Exp (K n) donde: n es el número de la nota F es la frecuencia de la nota cero K es una constante Por convención "la" de la quinta octava tiene una frecuencia de 440 Hz, así que F = 440. En la música occidental una octava se divide en 12 semitonos:

do do# re re# mi fa fa# sol sol# la la# si La escala tiene 8 octavas, un incremento de una octava equivale a multiplicar por dos la frecuencia, o sea:

f (n + 12) = 2 f (n)

Exp (k (n + 12)) = 2 Exp (K n) Exp (K n) * Exp (12 K) = 2 Exp (K n)

Page 183: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

183

por lo tanto: K = ln (2) / 12

La música occidental usa intervalos de 1/16, 1/8, 1/4, 1/2, 1, 2, y 4 tiempos. No hay una definición de cuanto es un tiempo, y puede ser muy corto en un arreglo "molto vivace" haciendo que la música lleve un ritmo acelerado, regular en un "andante" y muy largo en un "adagio" haciendo que la música lleve un ritmo muy lento. LECTURA Y ESCRITURA DE DATOS La lectura y desplegado de datos tienen su problemática cuando se trabaja en modo gráfico. Por ejemplo si no se agrega la librería Crt, el modo gráfico puede correr sin FDelay y de esta forma se pueden hacer Read's y Write's, inclusive Write's conteniendo variables, el problema es que no se pueden utilizar todos los procedimientos que están contenidos en la librería Crt como lo son ClrScr, GoToXY, ReadKey y KeyPressed, además de que si se termina la pantalla al hacer scrolls la gráfica se irá corriendo hacia arriba por lo que habrá que dar un ClearViewPort. Cuando se declara la biblioteca Crt ya se pueden utilizar los comandos citados anteriormente, el problema es que los Write's ya no serán ejecutados. Por lo que no será posible desplegar ninguna variable pero si se podrán hacer lectura de datos en cualquier parte de la pantalla o directamente utilizando el procedimiento ReadKey. Cuando se utilizan Read's hay que tener cuidado donde se encuentra el cursor antes de leer ya que el número tecleado aparecerá en la pantalla en formato ASCII y alterará lo que se encuentre desplegado. También puede hacer la lectura de los datos en modo ASCII antes de que entre al modo gráfico si es que el problema requiere datos para graficar. Inclusive puede salir de modo gráfico y regresar a modo ASCII después, o puede estar pasando de modo ASCII a modo Gráfico y viceversa intermitentemente si así lo desea. Como comentábamos anteriormente, lamentablemente la interface gráfica de Pascal no cuenta con procedimientos para escribir variables en la pantalla por lo que solo se podrá escribir texto predefinido. Utilice el procedimiento MovTo(X, Y) para posicionar el cursor de modo gráfico en el lugar donde Ud. requiera el texto y luego escriba el texto con el procedimiento OutText('string'), ejemplo: MoveTo (50, 50); OutText ('Dame el valor de X. '); ReadLn (X); PARA CERRAR EL MODO GRÁFICO O REGRESAR AL MODO ESTÁNDAR Finalmente para salir del modo gráfico hay que cerrarlo, esto se hace con la instrucción:

Page 184: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

184

CloseGraph; Finalizamos el capítulo diciendo que las interfaces más vistosas y amigables son las interfases en modo gráfico por lo que se han convertido en un estandar para crear las interfases hombre máquina. Es importante resaltar que la información presentada en modo gráfico es más agradable a la vista que la información presentada en una pantalla en modo ASCII (también llamado modo texto). Se puede agregar que la parte de graficación ha sido fundamental para desarrollar el concepto de realidad virtual y forma una parte fundamental en la síntesis de imágenes artificiales siendo esta explotada por las empresas que se dedican a los juegos electrónicos. Cabe agregar que no es la única aplicación que se le puede dar al modo gráfico, los físicos las utilizan mucho para sus modelos, los ingenieros en las diferentes disciplinas para simulación y cálculo ya que un diseño tridimensional es mas ilustrativo que ver únicamente números, y no se diga de los matemáticos, que trabajan en topología y gráficas de cuerpos en tres dimensiones. Actualmente todaslas interfaces hombre-máquina trabajan en modo gráfico. En fin, los campos de aplicación son muchos y es importante hacer notar que este campo no solo es desarrollado por las compañías de juegos electrónicos.

Page 185: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

185

EJERCICIOS CAPÍTULO 12 Fecha de entrega: ______________

Nombre: ________________________________________________________________

1.- En una hoja de papel cuadriculada dibuje un carrito coloreado de perfil con figuras

geométricas.

2.- Haga un programa que dibuje ese carrito en pantalla.

3.- Haga que el carrito se mueva a la derecha y a la izquierda de la pantalla hasta que el

usuario pulse una tecla.

4.- Dibuje un escenario.

Page 186: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

186

Page 187: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

187

13.- ARCHIVOS El manejo de archivos juega un papel muy importante en la programación. En ocasiones existen programas que únicamente alimentarlos requiere una gran cantidad de tiempo y si se comete un error al introducir un dato se tiene que repetir todo el proceso. También existen programas en los que no es fácil desplegar en pantalla el resultado de su proceso por ser éste muy extenso, así que es mejor escribirlo en un archivo para poderlo examinar con detenimiento. En otros programas la salida puede ser la entrada de otro. Finalmente también existen programas que manejan tal cantidad de datos que no sería suficiente la memoria principal para manejarlos. La solución a todos estos problemas nos la proporcionan los archivos. Un archivo es una colección de datos que se almacena en una unidad de almacenamiento secundario (unidad de disco). Existen archivos que se acceden secuencialmente y archivos indexados los cuales es posible acceder a través de un índice. El acceso secuencial tiene sus ventajas así como sus desventajas. Una ventaja es que su estructura es muy simple, la desventaja es que para acceder a un dato tenemos que recorrer casi todo el archivo para encontrarlo, en promedio la mitad para ser exactos (n/2) donde n es el número de elementos del archivo. Pero en el peor de los casos habremos de recorrerlo todo en vano. Para grandes bases de datos los archivos secuenciales son inoperantes. De ésta forma es posible hacer un programa que lea los datos de un archivo y también es posible hacer un programa que mande los resultados a un archivo, del mismo modo es posible que lea los datos de un archivo y escriba los resultados en otro y hasta es posible que actualice los datos de uno o varios archivos simultáneamente, lo cual se hacen los manejadores de bases de datos. Una base de datos son un conjunto de archivos que almacenan la información de una entidad como una empresa u organización como la información de sus empleados, sus salarios, sus departamentos, su contedido de almacen o bodega, sus carteras de clientes, sus carteras de proveedores, su contabilidad, etc. La forma de hacer esto varía de acuerdo a los diferentes lenguajes, pero la esencia es la misma. En Pascal lo primero que tenemos que hacer es declarar qué tipo de dato va a conformar nuestro archivo. Los archivos pueden contener datos tipo entero, real, caracter, arreglos, cadena o registros, en general cualquier tipo de dato estándar o definido por el usuario. Por lo tanto, en el área para declarar las variables globales se declarará también el tipo de archivo con el que vamos a trabajar. Si lo que vamos a almacenar en él son datos tipo registro entonces declaramos:

Page 188: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

188

type Alumno = record Nombre: string [30]; Carrera: string [35]; Telefono: string [15]; EMail: string [30]; end; Archivo = File of Alumno; var Alumno1, Alumno2: Alumno; InfAlumnos: Archivo; En donde InfAlumnos es un identificador de archivo. Lo segundo que tenemos que hacer para manejar un archivo en Pascal es asignarle al identificador un nombre de un archivo. La sintaxis de la instrucción para hacer esto es: Assign (IdDArch, 'NombreDelArchivo. extención'); ejemplo: Assign (InfAlumnos, 'InfAlumnos.txt'); Después de asignarle un nombre de archivo al identificador de archivo es necesario reinicializar el archivo. Todo archivo contiene índices que apuntan al último elemento que se accesó. Para acceder al primer elemento es necesario reinicializar el archivo. Esto se hace con la instrucción Reset (IdDArch). Es recomendable antes de reinicializar un archivo desactivar los mensajes de error de entrada/salida con el objeto de evitar que se pare el programa en caso de que el archivo no haya sido creado aún. El código sería el siguiente: {$I-} Reset (InfAlumnos); {$I+} Posteriormente hacer la siguiente pregunta: if IOResult <> 0 then ReWrite (InfAlumnos); “IOResult” es una variable del compilador a través de la cual es posible saber si hubo un error de entrada/salida, por eso no es necesario declararla. Así como ésta, existen varias que ya están declaradas pero solo se utilizan en caso necesario.

Page 189: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

189

La instrucción ReWrite (IdDArch) crea un archivo nuevo con el nombre que se le asignó al identificador con la instrucción de asignación o borra el ya existente en caso de que éste no haya sido creado dejándolo vacío. Generalmente esta instrucción solo se ejecuta la primera vez cuando el archivo no ha sido creado. Es posible crear un archivo vacío con el editor de Turbo Pascal, pero esto es un poco más complicado para un principiante aunque es necesario que un programa pueda crear un archivo si es que este no existe ya. Una vez que el archivo ya está asignado e inicializado ya podemos trabajar con él haciendo lecturas y/o escrituras. Para escribir en el archivo únicamente se debe poner el identificador de archivo antes de la lista de variables a escribir en el llamado a procedimiento Write. La sintaxis es la siguiente: Write (IdentificadorDArchivo, lista de variables); ejemplo: Write (InfAlumnos, Alumno1); La sintaxis de la instrucción de lectura para un archivo es la siguiente: Read (IdentificadorDArchivo, lista de variables); ejemplo: Read (InfAlumnos, Alumno1); Al finalizar de usar el archivo es necesario cerrarlo. Mientras un archivo esté en uso no podrá ser abierto por otro programa. La sintaxis de la instrucción para cerrar un archivo es: Close (IdentificadorDArchivo); ejemplo: Close (InfAlumnos); Para leer el archivo hasta el final se utiliza la función EoF (IdentificadorDArchivo) la cual es verdadera cuando se ha llegado al final del archivo. Un bucle que lee un archivo hasta el final sería: while not EoF (InfAlumno) do Read (InfAlumno, Alumno1);

Page 190: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

190

El “while” se utiliza para proteger al programa en caso de que el archivo esté vacío y no se pueda hacer ni siquiera una lectura. En los programas en donde se almacenan registros en un archivo y solo es necesario tener dos registros como variables. Para buscar un registro en el archivo, en un registro se almacena el dato que se requiere buscar y en el otro la información leída del archivo, se comparan y si son iguales se detiene la búsqueda puesto que ya se ha encontrado la información buscada. Otro procedimiento que es muy útil en el manejo de archivos es el comando:

Seek (IdDe Archivo, número de elemento) Este procedimiento ubica el apuntador de archivo en el registro indicado por localidad, ejemplo la instrucción: Seek (InfAlumno, 5) posicionará el apuntador de archivo en el registro 5 de tal manera que el siguiente Read o Write se hará sobre el registro indicado. Otra función útil es FileSize (IdDArchivo). Esta función regresa el tamaño del archivo. Puede ser útil para agregar registros al final del archivo editando el siguiente código: Seek (InfAlumno, FileSize(InfAlumno)) Esta línea posiciona el apuntador de archivo al final de éste, de tal manera que si se requiere anexar registros al archivo solo es necesario ejecutar posteriormente una escritura. La función “FileSize” regresa un entero que es mayor por uno al número de elementos. Si posteriormente se agrega un elemento más al archivo a esta operación compuesta se conoce como append.

Page 191: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

191

LOS ARCHIVOS EN EL LENGUAJE “C” Enseguida transcribimos el apartado 7.5 del libro “El lenguaje de programación C” de Richie y Kernighan ya que lo consideramos adecuado para tratar este tema.

Antes de que pueda ser leido o escrito un archivo tiene que ser abierto por la función “fopen”, la cual toma un nombre externo de archivo y hace algunas negocioaciones con el sistema operativo y regresa un apuntador que será utilizado en posteriores lecturas o escrituras del archivo.

Esta variable la cual es un apuntador de archivo apunta a una estructura que contiene información acerca del archivo, tal como la ubicación de un buffer, la posición de carácter actual del buffer, si el archivo está siendo leído o escrito y si han ocurrido errores en el archivo. Los usuarios no necesitan saber los detalles, debido a que las definiciones obtenidas de <stdio.h> incluyen una declaración de estructura llamada FILE. La única declaración necesaria para un apuntador de archivo se ejemplifica por:

FILE *fp; FILE *fopen (char *name, char *mode); Esto dice que fp es un apuntador a un FILE, y fopen regresa un apuuntador a

FILE. Nótese que FILE es un nombre de tipo, como “int”, no un rótulo de estructura; está definido por un typedef.

La llamada a fopen en un programa es: fopen (name, mode); El primer argumento de fopen es una cadena que contiene el nombre del archivo.

El segundo argumento es el modo, también una cadena de caracteres, que indica como se intente emplear el archivo. Los modos disponibles incluyen lectura “r”, escritura “w” y añadido (apend) “a”. Algunos sistemas distinguen entre archivos de texto y binarios; para los últimos debe escribirse una “b” luego de la cadena de modo.

Si un archivo que no existe se habre para escribir o añadir, se crea, si es posible.

Abrir un archivo existente para escribir proboca que los contenidos anteriores sean deshechados, mientras que abrirlo para añadir los preserva. Es un error tratar de leer un archivo que no existe, y también pueden haber otras causas de error, como tratar de leer un archivo cuando no se tiene permiso. Si existe cualquier error, fopen regresa NULL. (El error puede ser identificado en forma más precisa).Lo siguiente que se requiere es una forma de leer o escribir el archivo una vez que está abierto. Existen varias posibilidades, de las cuales getc y putc son las más simples. Getc regresa el siguiente carácter de un archivo; necesita un aapuntador del archivo para decirle cúal es:

int getc (FILE *fp); getc regresa el siguiente carácter del flujo al que se refiere fp; regresa EOF si ocurre

algún error.

Page 192: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

192

putc es una función de salida: int putc (c, FILE *fp); putc escribe eñ carácter c en el archivo fp y regresa el carácter escrito, o EOF si

ocurre un error. Tal como getchar y putchar, getc y putc pueden ser macros en lugar de funciones.

Cuando se arranca un programa en C, el medio ambiente del sistema operativo es

responsable de abrir tres archivos y proporcionar apuntadores de archivo para ellos. Estos archivos son la entrada estándar, la salida estándar y el error estándar; los apuntadores de archivo correspondientes se llaman stdin, stdout, stderr y están declarados en <stdio.h>. Normalmente stdin se direcciona al teclado, stdout y stderr se conectan a la pantalla, pero stdin y stdout pueden ser redirigidos a archivos o a interconecciones (pipes).

getchar y putchar pueden estar definido en términos de getc y putc, stdin y stdout

como sigue: #define getchar () getc (stdin) #define putchar () putc (c, stdout)

Para entrada y salida de archivos con formato se pueden usar las funciones fscanf y fprintf. Estas son identicas que scanf y printf, exepto en que el primer argumento es un apuntador de archivo que especifica el archivo que será leído o escrito; la cadena de formato es el segundo argumento. int fscanf (FILE *fp, char *format, …) int fprintf (FILE *fp, char *format, …)

Habiendo hecho a un lado los prerrequisito, ya estamos ahora en posición de escribir el programa cat, que concatena archivos. El diseño se ha encontrado conveniente para muchos programas. Si existen argumentos en la linea de comando, se interpretan como nombres de archivos y se procesan en orden. Si no hay argumentos se procesa la entrada estándar.

Page 193: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

193

#include <stdio.h> /* cat : concatena archivos, versión 1 */ main (int argc, char *argv []) { FILE *fp; void filecopy (FILE *, FILE *); if (argc == 1) /*sin args; copia la entrada estandar */ Filecopy (stdin, stdout); else while (--argc > 0) if ((fp = fopen (*++argv, “r”)) == NULL) { printf (“cat no se puede abrir%s\n”, +argv); return 1;

} else { filecopy (fp, stdout); fclose (fp); } return 0;

} /* filecopy: copia el archivo ifp al archivo ofp */ void filecopy (FILE *ipf, FILE *ofp) { int c; while ((c = getc (ifp)) ¡= EOF) putc (c, putc); } Los apuntadores de archivo stdin y stdout son objetos de tipo FILE *. Sin embargo, son constantes, no variables, por lo que no es posible asignarles algo. La función int fclose (FILE *fp)

Es lo inverso a fopen; interrumpe la conección que fue establecida por fopen entre el apuntador de archivo y el nombre externo, liberando al apuntador de archivo para otro archivo. Puesto que la mayoría de los sistemas operativos tienen algunas limitantes sobre el número de archivos que un programa puede tener abiertos simultáneamente, es una buena idea liberar los apuntadores de archivo cuando ya no son necesarios, como se hizo en cat. También hay otra razón para usar fclose en un archivo de salida. Cuando un programa termina normalmente, fclose es llamado automáticamente para cada archivo abierto. (Se puede cerrar

Page 194: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

194

stdin y stdout si no son necesarios. También pueden ser reasignados por la función de biblioteca freopen). Aquí termina la transcripción del apartado 7.5. Ahora agregaremos el apartado 7.6 Manejo de errores –stderr y exit, ya que consideramos que también es útil. El manejo de los errores en cat no es el ideal. El problema es que si no se puede tener acceso a uno de los archivos por alguna razón, el diagnóstico se imprime al final de la salida concatenada. Eso podría ser aceptable si la salida va a la pantalla, pero no si va hacia un archivo o hacia otro programa mediante una interconección. Para manejar mejor esta situación, se asigna un segundo flujo de salida llamada stderr, a un programa en la misma forma que stdin y stdout. LA salida escrita hacia stderr normalmente aparece en la pantall, aún si la salida estandar es redirigida. Corrijamos cat para escribir sis mensajes de error en el archivo de error estandar. #include <stdio.h> /* cat: concatena archivos, versión 2*/ main (int argc. char argv [0]); { FILE *fp; void filecopy (FILE *, FILE *); char prog = argv [0]; /* nombre del programa para errores */ if (argc == 1) /* sin args; copia la entrada entrada estandar */ filecopy (stdin, stdout)

Page 195: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

195

EJERCICIOS DEL CAPÍTULO 13 Fecha de entrega: ______________ Nombre: ________________________________________________________________

1.- ¿Qué es un archivo? ____________________________________________________

2.- ¿Cuantos tipos de acceso archivos existen? _________________________________

3.- ¿Cuando es necesario emplear archivos en un programa? ______________________

_______________________________________________________________________

4.- Diseñe un programa que funcione como un directorio telefónico.

5.- Altere el programa para que funcione como un diccionario.

Page 196: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

196

Page 197: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

197

14.- MÉTODOS DE DESCOMPOSICIÓN, DESARROLLO DESCENDENTE (TOP- DOWN) Y PROGRAMACIÓN MODULAR. El método de desarrollo descendente es un excelente método para desarrollar los programas, sobre todo programas grandes y con un alto nivel de complejidad. Este método nos garantiza que por muy grande y compleja que sea nuestra solución jamás perderemos el control del proyecto además de poder entregar resultados en un tiempo finito y de buena calidad. A grandes rasgos el método de desarrollo descendente consiste en programar el programa principal de tal modo que tenga la mayor carga semántica y que muestre el algoritmo solución global de tal forma que en el programa principal muestre los subprogramas o sub-problemas a resolver. La estrategia principal de este método es "divide y vencerás". El algoritmo se repite con estos subprogramas hasta que ya no se puedan descomponer más. La estructura que formarán el programa principal y los procedimientos será una estructura arbolada. Cuando se termina de programar el último procedimiento ya estamos listos para codificar el programa. En detalle el método de diseño descendente consiste en: 1° Plantear el problema en lenguaje natural (es decir, en el lenguaje en el que hablamos). Esto puede servir al mismo tiempo como los comentarios del encabezado del programa para indicar que hace el programa iniciando con la frase "Este programa calcula...." por ejemplo. 2° Esbozar el algoritmo a grandes rasgos con estructuras de control. Para esto se pueden nombrar procedimientos o funciones que aún no se hayan definido (éstas se definirán después y serán de menor nivel). Se usarán funciones en las condiciones para dirigir el flujo del programa de la siguiente manera, ejemplo: si EsPrimo (N) entonces Lo que quiere decir en lenguaje natural: si N es primo entonces 3° Se tomará el primer procedimiento o función que aparezca en el programa principal y se repetirá recursivamente el mismo proceso que empleamos para el programa principal desarrollando todos los procedimientos y funciones que se necesiten para que este corra. Este procedimiento tendrá menor carga semántica que el programa principal es decir, tendrá menos relación con el problema que estamos resolviendo y tendrá más relación con instrucciones en el lenguaje de programación y menos llamadas a procedimientos. 4° Esto se repetirá sucesivamente hasta que no quede ningún procedimiento y función sin definir. Se pueden usar funciones estándar del lenguaje.

Page 198: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

198

Cuando se terminen de codificar todos los procedimientos y funciones tendremos la primera versión de nuestro programa.

El siguiente paso será cargarlo. Para cargarlo he irlo probado simultáneamente podemos utilizar el siguiente método.

Cargar el programa principal y poner todas las invocaciones a procedimientos dentro de "WriteLn" para que el programa no entre en los procedimientos. Si aparecen funciones definirlas. De esta forma el programa principal estará corriendo aunque los procedimientos no estén definidos aún.

Posteriormente cargar el primer procedimiento con todos los procedimientos que cuelguen de el y probar que al correr el programa esa parte funcione bien.

Luego hacer lo mismo con los procedimientos restantes hasta que ya no haya ningún procedimiento en el programa principal que no esté cargado. Procederémos a la depuración y pruebas.

Una vez hechas las pruebas ya podemos generar el ejecutable. Está será nuestra versión 1.0 de nuestro programa y deberemos hacer una copia de seguridad por cualquier cosa que suceda. Lo peor que le puede pasar a un programador en no tener nada que entregar. Las siguientes versiones serán optimizaciones y ampliaciones de nuestro programa. Pondremos un ejemplo de desarrollo del método de desarrollo descendente. Problema: Hacer un programa que maneje un directorio telefónico. El programa debe ser capaz de dar de alta un nuevo nombre, consultar o actualizar los datos de una persona. El programa principal sería el siguiente: program Directorio; var Opcion: char begin repeat begin Opcion := ReadKey; case Opcion of: 'a': WriteLn('Altas'); 'c': WriteLn('Consultas); 'e': WriteLn('Edicion'); 's': WriteLn('Salir')

Page 199: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

199

else WriteLn('opción inválida) end; end until Opcion = 's'; end. Este sería el bosquejo del programa principal. Podríamos correr el programa para revisar el flujo y ver que funciona. Este uso del case es una forma muy práctica para navegar dentro del programa. Observe como no es necesario tener los procedimientos definidos para que el programa corra. El siguiente paso es cargar el procedimiento Altas. Repetimos la misma estrategia. Como en este procedimiento lo que se va a hacer es pedirle los datos al usuario y escribirlos en el archivo eso es lo que se hará. uses Crt; const N = 30; C = 20; T = 10; type alumno = record Nombre: string [N]; Carrera: String [C]; Telefono: string [T]; end; var Opción: char; Alumno1: alumno; F: archivo; procedure Altas { Este procedimiento lee los datos en un registro y los escribe en un archivo.} begin with Alumno1 do begin ReadLn (Nombre); ReadLn (Carrera); ReadLn (Telefono); end Assign (F, 'DATOS.TXT'); {$I-}

Page 200: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

200

Reset (F); {$I+} if IOResult <> 0 then ReWrite (F); Write (F, Alumno1); Close (F); end; { Altas} Una vez terminado este procedimiento se procede a quitar el WriteLn correspondiente a Altas y a probar y depurar el procedimiento. Después se carga el siguiente procedimiento, en este caso "Consultas" y se define y se sigue el mismo procedimiento que con "Altas". Esto se hace con todos los procedimientos que aparecen en el programa principal y una vez que se desarrolla el último procedimiento el programa ya puede correr completo por primera vez. Revisamos que haga lo que queremos y entonces ya tenemos nuestra versión 1.0. Finalmente como tip de programación le recomendamos que al estar desarrollando un programa, si aún no sabe como se comportan algunos procedimientos o tipos de datos en el lenguaje haga un programa para hacer algunas pruebas para adquirir éste conocimiento y posteriormente utilice lo aprendido en el diseño de su programa, o sea, no espere hasta que se necesite este conocimiento para hacer las pruebas ya que ésto le consumirá más tiempo.

Page 201: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

201

EJERCICIOS CAPÍTULO 14 Fecha de entrega: ______________

Nombre: ________________________________________________________________

1.- Explique en que consiste el método de desarrollo descendente: __________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

_______________________________________________________________________

2.- Desarrolle los procedimientos de Consultas, Edición y Listado del programa Directorio

mostrado en el capítulo.

3.- Desarrolle el siguiente problema utilizando el método de desarrollo descendente. Se

requiere colocar en un tablero de ajedrez ocho damas que no se ataquen. Haga un

programa que encuentre todas las soluciones.

Tips: Llene el tablero de arriba a abajo y de izquierda a derecha. Se sabe si una reina

ataca a otra en una diagonal si sus coordenadas suman lo mismo (diagonal que sube) o

restan lo mismo (diagonal que baja). No es necesario revisar hacia atrás ya que si se

puso una nueva reina ya se revisó que las anteriores no se atacan entre si. Utilice back

track cuando se llegue a una solución sin salida. El back track consiste en mover la reina

anterior en una posición si es que se llegó a un estado en donde no se pueden colocar

más reinas. El retroceso se hace recursivamente hasta que se llegue a un estado de no

bloqueo. El programa termina cuando la primera reina ya recorrió todas las posiciones y

la siguiente posición estaría fuera del tablero.

Page 202: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

202

Page 203: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

203

APÉNDICE A REGLAS DE INDENTADO Otro aspecto a considerar para la escritura de los algoritmos estructurados es el indentado. El indentado es el sangrado que se le da a la parte interna de una estructura de control para indicar pertenencia. Todo aquello que se encuentre indentado dentro de una estructura de control indicará la pertenencia.

Se recomienda indentar con cuatro espacios o un tabulador los metaparéntesis después de una estructura de control.

Se recomienda indentar todas las sentencias dentro de una estructura de control cuatro espacios un tabulador a partir de la anterior.

Si sólo es una sentencia indentar sólo dos espacios o un tabulador.

Indentar dentro de una estructura de control y desindentar cuando esta termine.

Cada metaparéntesis debe terminar en la misma columna que en la que abrió su correspondiente metaparéntesis.

El programa debe terminar en la misma columna en que abrió su correspondiente metaparéntesis.

Generalmente los metaparéntesis de inicio y final de programa no se indentan.

En ocasiones se puede escribir el primer metaparentesis a continuación del inicio de la estructura de control para ahorrar un renglón y cuando se quiere que los procedimientos largos queden en una sola hoja.

Page 204: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

204

Page 205: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

205

APÉNDICE B MENEJO DE ERRORES EN PASCAL var

Value: Integer; Ok: Boolean;

begin Ok := False; while not OK do

begin Write (‘proporcione un número entero: ‘);

{-I} ReadLn (Value); {+I} Ok := (IOResult = 0) If not Ok then

WriteLn (‘intente de nuevo, éste valor no es un número entero’) end; end;

Page 206: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

206

Page 207: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

207

APÉNDICE C CREACIÓN DE UNIDADES EN PASCAL Las unidades son las bibliotecas donde se pueden definir constantes, tipos de datos, funciones y procedimientos. La estrucura de una unidad es la siguiente unit NameOfUnit; interface

type . Encabezados de funciones y procedimientos;

implementation Definiciones de funciones y procedimientos Nota: las definiciones de funciones y procedimientos pueden contener definiciones de funciones y procedimientos internas que no podrán ser alcanzadas por los usuarios de la unidad. Se selecciona la opción para enviar el archivo compilado en disco y se compila. El resultado es un archivo “.TPU” que funcionará como una unidad que puede ser invocada.

Page 208: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

208

Page 209: NOTAS DEL CURSO INTRODUCCIÓN A LA PROGRAMACIÓNsgpwe.izt.uam.mx/pages/cbi/spaez/index_files/NotasIP20151130.pdf · Copiado del Libro Introducción a la Computación y a la Programación

209

BIBLIOGRAFÍA

1. Levine Gutierrez Guillermo, Intoducción a la Computación y a la Programación Estructurada, 2ª Ed. McGraw Hill, 1989

2. Peter Gorgono, Programción en Pascal, Ed. Addison Wesley, 1984. 3. Luis Joyanes Aguilar, Turbo Pascal, Ed. McGraw Hill. 4. Larry Joel Goldstein, Turbo Pascal, Ed. Prentice Hall. 5. Julien Henifeld, Turbo Pascal con Aplicaciones, Grupo Editorial Iberoamérica, 2ª

Ed., 1992. 6. Luis Joyanes Aguilar, Luis Rodriguez Baenay Luis Rodriguez Azuela, Matilde

Fernandez Azuela, Fundamentos de Programación, De McGraw Hill. 7. Glen Brookshear, Introducción a las Ciencias de la Computación, Addison Wesley,

4a Edición, 1995. 8. Gullermo Levine Gutierrez, Computación y Programación Moderna, Ed. Addison

Wesley, 2001. 9. Brian W Kernighan y Dennis M. Ritchie, El Lenguaje de programación C, 2ª Ed.,

Editorial Pearson Educación. 10. Swedan Fathi, Turbo Pascal 7: Referencia Rápida, Addison Wesley

Iberoamericana, 1994. 11. Haiduk H. Paul, Turbo Pascal Orientado a Objetos, Ed. McGraw Hill, 1994. 12. Kernighan B. W. Y Ritchie D. M., El lenguaje de programación C, 2ª Edición,

Pearson Education, México, 1991.