Universidad de Los Andes Facultad de Ciencias Laboratorio SUMA Programación y Diseño Algorı́tmico I Marzo, 2006 Autores: Kay A. Tucci C. Francisco J. Hidrobo T. Mayerlin Y. Uzcátegui S. Índice General 1. El Computador 1.1. Desarrollo Histórico . . . . . . . . . . 1.2. Arquitectura básica del computador . 1.2.1. El Procesador . . . . . . . . . 1.3. La Memoria . . . . . . . . . . . . . . 1.4. Los Dispositivos de Entrada y Salida 1.5. Los Canales de Comunicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 7 7 8 8 8 2. Diseño Algorı́tmico 2.1. Algoritmos . . . . . . . . . . . . . . 2.2. Aspectos Básicos de los Algoritmos 2.3. Sintaxis de los algoritmos . . . . . 2.3.1. Identificadores . . . . . . . . 2.3.2. Palabras reservadas . . . . . 2.3.3. Sı́mbolo especiales . . . . . 2.3.4. Tipos de Datos . . . . . . . 2.3.5. Constantes . . . . . . . . . . 2.3.6. Variables . . . . . . . . . . . 2.3.7. Subprogramas . . . . . . . . 2.3.8. Expresiones . . . . . . . . . 2.4. Evaluación de expresiones . . . . . 2.5. Metodologı́a General . . . . . . . . 2.6. Problemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 10 10 10 11 11 11 12 12 12 13 15 16 17 3. Sentencias o instrucciones Simples 3.1. Asignación . . . . . . . . . . . . . 3.1.1. Casos Relevantes . . . . . 3.2. Llamada a procedimiento . . . . . 3.2.1. Casos Relevantes . . . . . 3.3. Problemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 20 21 21 21 . . . . . 4. Estructuras de Selección 26 4.1. Estructuras de Selección Simple . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.2. Problemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 A. Tabla ASCII 29 B. Algunas identidades matemáticas 30 Capı́tulo 1 El Computador 1.1. Desarrollo Histórico Desde hace mucho tiempo, el hombre ha buscado la mejor manera de realizar sus cálculos y procesar información con mayor eficiencia y velocidad. Los antiguos pobladores empezaron utilizando sus dedos para contar a sus animales, cuando ya no eran suficientes, hacı́an marcas en los árboles o utilizaban piedras (calculos en latı́n) para calcular. Esto se fue perfeccionando, hasta que hace unos 5000 años, los chinos inventaron el ábaco, que quizá fue el primer dispositivo mecánico de contabilidad que existió, y que todavı́a se sigue utilizando. Un avance fundamental en el cálculo se dio con John Napier o John Neper (1550-1617), matemático escocés, quien es conocido por introducir el primer sistema de logaritmos. Napier fue uno de los primeros, si no el primero, en utilizar la moderna notación decimal para expresar fracciones decimales de una forma sistemática. También inventó sistemas mecánicos para realizar cálculos aritméticos en 1617. Tomando las ideas de Napier el inglés William Oughtred en 1633 creó un instrumento que hoy se conoce como regla de cálculo, utilizado hasta hace unos años. Grandes inventores también intentaron hacer máquinas que simplifiquen las operaciones matemáticas, es ası́ que Leonardo Da Vencı́ (1452-1519) trazó las ideas para una sumadora mecánica. Siglo y medio después, el filósofo y matemático francés Blaise Pascal (1623-1662) por fin inventó y construyó la primera sumadora mecánica. Se le llamo Pascalina y era una máquina a base de engranes y ruedas. A pesar de que Pascal fue enaltecido por toda Europa debido a sus logros, la Pascalina, resultó un desconsolador fallo financiero, pues para esos momentos, resultaba más costosa que la labor humana para los cálculos artiméticos. Charles Babbage (1793-1871), visionario inglés y catedrático de Cambridge, adelantó la situación del hardware computacional al inventar la máquina de diferencias, capaz de calcular tablas matemáticas. En 1834, cuando trabajaba en los avances de la máquina de diferencias Babbage concibió la idea de una máquina analı́tica. En esencia, ésta era una computadora de propósitos generales. Conforme con su diseño, la máquina analı́tica de Babbage podı́a sumar, substraer, multiplicar y dividir en secuencia automática a una velocidad de 60 sumas por minuto. El diseño requerı́a miles de engranes y mecanismos que cubrirı́an el área de un campo de futbol y necesitarı́a accionarse por una locomotora. Los escépticos le pusieron el sobrenombre de “la locura de Babbage”. Charles Babbage trabajó en su máquina analı́tica hasta su muerte. Los diseños detallados de Babbage describı́an las caracterı́sticas que hoy en dı́a son incorporadas en las computadoras. El diseño de Babbage mezclaba las ideas de cáculo mecánico, de Da Vinci, Pascal y otros Página: 1 de 31 inventores, con las de tarjetas perforadas para almacear procedimientos e información. Las tarjetas perforadas fueron creadas para los telares de tejidos en 1801 por el francés JosephMarie Jackard (1753-1834). El telar de Jackard opera de la manera siguiente: las tarjetas se perforan estratégicamente y se acomodan en cierta secuencia para indicar un diseño de tejido en particular. Charles Babbage quiso aplicar el concepto de las tarjetas perforadas del telar de Jackard en su motor analı́tico. En 1843 Lady Ada Augusta Lovelace sugirió la idea de que las tarjetas perforadas pudieran adaptarse de manera que propiciaran que el motor de Babbage repitiera ciertas operaciones. Debido a esta sugerencia algunas personas consideran a Lady Lovelace la primera programadora. Otro hecho fundamental del Siglo XIX corresponde al desarrollo realizado por el británico autodidacta George Boole de una nueva álgebra. En 1847, a los 32 años, publica “El análisis matemático del pensamiento”, lo cual le vale una cátedra en el Queen’s College de Dublin. En 1854 publica su obra magna “Las leyes del pensamiento”. Su álgebra consiste en un método para resolver problemas de lógica que recurre solamente a los valores binarios V eradero y F also y a tres operadores: AN D (y), OR (o) y N OT (no). A partir del álgebra binaria de Boole se desarrolló posteriormente lo que conocemos hoy como “código binario”, que utilizan todos los computadores actuales. El siguiente paso importante en la evolución de la computación se dio cuando la oficina de censos estadounidense no terminó de procesar los datos del censo de 1880 sino hasta 1888. La dirección de la oficina ya habı́a llegado a la conclusión de que el censo de cada diez años tardarı́a más que los mismo 10 años para terminarlo. Se comisionó al estadista Herman Hollerit (1860-1929) para que aplicara su experiencia en tarjetas perforadas y llevara a cabo el censo de 1890. Con el procesamiento de las tarjetas perforadas y el tabulador de tarjetas perforadas de Hollerit, el censo se terminó en sólo 3 años y la oficina se ahorró alrededor de $5,000,000 de dólares. Ası́ empezó el procesamiento automatizado de datos. Hollerit no tomó la idea de las tarjetas perforadas del invento de Jackard, sino de la fotografı́a de perforación utilizada por algunas lı́neas ferroviarias de la época las cuales expedı́an boletos con descripciones fı́sicas del pasajero; los conductores hacı́an orificios en los boletos que describı́an el color de cabello, de ojos y la forma de nariz del pasajero. Eso le dió a Hollerith la idea para hacer la fotografı́a perforada de cada persona que se iba a tabular. Hollertih fundó la Tabulating Machine Company y vendió sus productos en todo el mundo. La demanda de sus máquinas se extendió incluso hasta Rusia. El primer censo llevado a cabo en Rusia en 1897, se registró con el Tabulador de Hollerith. En 1911, la Tabulating Machine Company, al unirse con otras Compañı́as, formó la ComputingTabulating-Recording-Company. Los resultados de las máquinas tabuladoras tenı́an que llevarse al corriente por medios manuales, hasta que en 1919 la Computing-Tabulating-RecordingCompany anunció la aparición de la impresora/listadora. Esta innovación revolucionó la manera en que las Compañı́as efectuaban sus operaciones. Para reflejar mejor el alcance de sus intereses comerciales, en 1924 la Compañı́a cambió el nombre por el de International Bussines Machines Corporation (IBM). Durante décadas, desde mediados de los cincuentas la tecnologı́a de las tarjetas perforadas se perfeccionó con la implantación de más dispositivos con capacidades más complejas. Dado que cada tarjeta contenı́a en general un registro (nombre, dirección, etc) el procesamiento de la tarjeta perforada se conoció también como procesamiento de registro unitario. Desde el punto de vista de la teorı́a de la computación el avance más importante lo dio el inglés Allan Turing (1912-1954) que en su afán de responder a la pregunta ¿Existe al menos en principio algún método definido, o proceso mediante el cual toda cuestión matemática pueda ser 1.1. Desarrollo Histórico Página: 2 de 31 demostrada? i Esta pregunta, llamada entscheidugsproblem, fue formulada por David Hilbert en el Congreso Internacional de Matemáticos de 1900. Turing definió el concepto de método y como un proceso se convierte en metódico para ası́ buscar una forma de hacerlo mecánicamente. En 1936 en el artı́culo On Computable Numbers, Turing desarroyó un modelo formal de computador, la Máquina de Turing, que es el primer modelo teórico de lo que es hoy en dı́a un computador programable. Una máquina de Turing es un dispositivo teórico que convierte luego de algunos pasos una entrada, en código binario, en una salida también en código binario. Consiste en una cinta de información infinitamente larga. La unidad de lectura y escritura sólo puede procesar un bit a la vez. La máquina tiene una serie de estados internos finitos que también se pueden numerar en binario. Una instrucción en una Máquina de Turing se ejecutan si el estado de la máquina y el bit leido de la cinta coinciden con la instrucción. Al ejecutar una instrucción, la máquina lee un bit de la cinta y puede cambiale su valor o lo dejarlo igual, luego cambia su estado interno y por último mueve la cinta hacia la derecha o hacia la izquierda de acuerdo a lo que indique la instruccion que se esté ejecutando. Una vez que se mueve la cinta se lee el siguiente bit y se repite el mismo ciclo. Por ejemplo una instrucción tı́pica puede ser: bit L 0000 | {z } Edo. actual z}|{ 1 bit E 1101 | {z } Edo. nuevo z}|{ 1 |{z} 1 D/I que significa si la máquina se encuentra en el estado interno 0000 y lee un 1 en la cinta, entonces pasa al estado interno 1101, escribe un 1 y desplaza la cinta hacia la izquierda (1). Casi simultaneamente al anuncio de los resultados de Turing, el estadounidense Alonzo Church respondı́a a la entscheidugsproblem basandose en una notación formal, el cálculo lambda, mediante el cual transformaba todas las fórmulas matemáticas a una forma estándar. Una persona poco conocida pero con un gran aporte al avance de las computadoras es sin duda alguna, Konrad Zuse (1910-1995). Si bien sus conocimientos pasaron desapercibidos para el oeste debido a la guerra que se aproximaba a Europa en el año 1936. Zuse construyó en 1938 la Z1 que fue la primera computadora binaria del mundo y la primera computadora electromecánica digital controlada por programación. Más tarde la modificó y eliminó de ellas los pricipales defectos llamándola Z2. Zuse trató inútilmente de persuadir al gobierno nazi de las ventajas de su invento. La Z3 se terminó de construir en 1941. Sin embargo, ninguna de estas máquinas sobrevivieron a la II guerra mundial con excepción de la Z4, construida años más tarde en Austria. En 1937, Howard Aiken, profesor de Harvard, se fijó la meta de construir una máquina calculadora automática que combinara la tecnologı́a eléctrica y mecánica con las técnicas de tarjetas perforadas de Hollerith. Con la ayuda de estudiantes de postgrado e ingenieros de la IBM, el proyecto se completó en 1944. El aparato terminado se denominó la computadora digital Mark I. Las operaciones internas se controlaban automáticamente con reles electromagnéticos, y los contadores aritméticos eran mecánicos; ası́, la Mark I era una computadora electromecánica. El primer prototipo de computadora electrónica se concibió entre 1937-1938 por el doctor John Vincen Atanasoff y Clifford Berry, su asistente de postgrado. La computadora, que la llamaron ABC (Atanasoff-Berry Computer), empleaba bulbos al vacı́o para almacenar datos y efectuar operaciones aritméticas y lógicas. Durante 1940 y 1941 Atanasoff y Berry se reunieron con John W. Mauchly y le mostraron su trabajo. Mauchly, que trabajaba en la School of Electrical Engineering de la Universidad de 1.1. Desarrollo Histórico Página: 3 de 31 Pennsylvania, comenzó a pensar en la forma de construir una computadora de aplicación general (la ABC se diseñó con el objetivo especı́fico de resolver sistemas de ecuaciones simultáneas). Mauchly formó un equipo con J. Presper Eckert Jr., estudiante de postgrado de ingenierı́a en la Moore School, para organizar la construcción de ENIAC a principios de la década de 1940. ENIAC fue la primera computadora electrónica de aplicación general que entró en funcionamiento. Financiada por el ejército de Estados Unidos, se construyó en la Moore School como proyecto secreto durante la Segunda Guerra Mundial debido a que el ejército se interesaba en la preparación rápida de tablas de trayectorias de proyectiles. La ENIAC, con 30 toneladas de peso, llenaba un cuarto de 6 m x 12 m, contenı́a 18,000 bulbos, y podrı́a realizar 300 multiplicaciones por segundo y cálculos matemáticos 1,000 veces más rápido que cualquier máquina sumadora de su tiempo. Este gigante tenı́a que programarse manualmente conectándola a tres tableros que contenı́an más de 6,000 interruptores. Ingresar un nuevo programa era un proceso muy tedioso que requerı́a dı́as o incluso semanas. Las instrucciones de operación de esta computadora no se almacenaban internamente más bien se introducı́an por medio de tableros de clavijas e interruptores localizados en el exterior. El ejército norteamericano utilizó la ENIAC hasta 1955. En 1945, John Von Newman, que habı́a trabajado con J. Presper Eckert y John Mauchly en la universidad de Pennsylvania, publicó un artı́culo acerca del almacenamiento de programas sugiriendo utilizar sistemas de numeración binarios para construir las computadoras y que las instrucciones para la computadora ası́ como los datos que se manipulara, se almacenaran internamente en la máquina. Esta es una idea importante porque el sistema de numeración binario utiliza únicamente dos dı́gitos (0 y 1) en vez de los 10 dı́gitos del sistema decimal con el que todo mundo está familiarizado. Dado que los componentes electrónicos están normalmente en uno de dos estados (encendido o apagado), el concepto binario simplificó el diseño del equipo. El concepto de programa almacenado permitió la lectura de un programa dentro de la memoria de la computadora, y después la ejecución de las instrucciones del mismo sin tener que volverlas a escribir. La primera computadora en usar el citado concepto fue la llamada EDVAC (Electronic Discrete-Variable Automatic Computer), desarrollada por Von Newman, Eckert y Mauchly. Los programas almacenados dieron a las computadoras una flexibilidad y confiabilidad tremendas, haciéndolas más rápidas y menos sujetas a errores que los programas mecánicos. Una computadora con capacidad de programa almacenado podrı́a ser utilizada para varias aplicaciones tan solo cargando y ejecutando el programa apropiado. Hasta ese punto, los programas y datos podrı́an ser ingresados en la computadora sólo con la notación binaria, que es el único código que las computadoras entienden. El siguiente desarrollo importante en el diseño de las computadoras fueron los programas intérpretes, que permitı́an a las personas comunicarse con las computadoras utilizando medios distintos a los números binarios. En 1952, Grace Murray Hopper una oficial de la Marina de Estados Unidos, desarrolló el primer compilador, un programa que puede traducir enunciados parecidos al inglés en un código binario comprensible por la máquina. Más tarde, desarrolló el COBOL (Common Business Oriented Language), un proyecto financiado por compañı́as privadas y organismos educativos, junto con el gobierno federal norteamericano durante la última parte de los años 50. COBOL permitı́a que un programa de computadora escrito para una máquina en especial, pudiera correrse en otras máquinas sin tener que recodificarse. De pronto, los programas se transportaban fácilmente, y el mundo de los negocios comenzó a aceptar a las computadoras con entusiasmo. Los computadores se pueden agrupar en generaciones. Se conocen como computadores de primera generación a aquellas contruidas entre 1941 y 1958, las cuales emplearon bulbos para 1.1. Desarrollo Histórico Página: 4 de 31 procesar información. Los operadores ingresaban los datos y programas en código especial por medio de tarjetas perforadas. El almacenamiento interno se lograba con un tambor que giraba rápidamente, sobre el cual un dispositivo de lectura/escritura colocaba marcas magnéticas. Entre las principales caracterı́sticas de los computadores de primera generación tenemos que: utilizan tecnologı́a de válvulas de vacı́o, la memoria pasaba información de registros de válvulas a núcleos de ferrita y la memoria secundaria lo hacia de tarjetas y cintas perforadas a tambores y cintas magnéticas. A nivel lógico utilizan aritmética binaria y programación en ensamblador. Los principales equipos que se destacan en esta generación son Mark I, Colossus, ABC, ENIAC, UNIVAC I, EDVAC, EDSAC, IAS, y las comerciales IBM 650, 701, 704 y 709. La segunda generación comprende desde 1949 hasta 1964 y nace gracias al trabajo de tres cientı́ficos de los laboratorios Bell, John Bardeen, William Shockley y Walter Brattain, que en 1947 ganaron el premio Nóbel al inventar y desarrollar el transistor, que es más rápido, confiable y 200 veces más pequeño que un bulbo o tubo electrónico. El transistor hizo posible una nueva generación de computadoras, más rápidas, pequeñas y con menores necesidades de ventilación. En 1954 construyeron el TRADIC en la Bell, que fue el primer computador transistorizado, pero además de los transistores, en los computadores de segunda generación se consolidan las memorias de ferrita, aparecen los canales de E/S, los lenguajes de alto nivel como el FORTRAN, COBOL, ALGOL, PL1; y se impone el procesamiento tipo batch o por lotes. Entre estos compuadores tenemos a UNIVAC 1107, BURROUGH D-805, PDP-5 de DEC, y las cientı́ficas IBM 7070, 7090, 7094. Las computadoras de la tercera generación 1964-1970 emergieron con el desarrollo de los circuitos integrados en las cuales se colocan miles de componentes electrónicos en un chip. En 1964 IBM anunció la tercera generación de equipo de cómputo: Su familia System 360 de macro computadoras, en la que cada uno de los procesadores de tenı́a un conjunto muy amplio de instrucciones internas que podı́a ejecutar. Algunas de esas instrucciones eran especialmente útiles en aplicaciones cientı́ficas, mientras que otras eran más apropiadas para procesamiento de archivos. Para evitar competir directamente con la IBM, Digital Equipment Corporation (DEC) redirigió sus esfuerzos hacia computadoras pequeñas, mucho menos costosas de comprar y operar que las computadoras grandes. Estas mini computadoras se desarrollaron durante la segunda generación y se extendió su uso durante los años 60 y 70. En 1960, DEC introdujo la primera mini computadora, la PDP-1 y en 1969 tenı́a ya una lı́nea de exitosas mini computadoras. En los computadores de tercera generación se integran los transistores y aparecen los circuitos integrados SSI y MSI. Aparecen las Familias de Computadores y se produce una explosión de los mini-computadores. Además se comienza el uso de las tarjetas de circuito impreso, las memorias electrónicas sustituyen a las de ferrita, aparecen las memorias cache y los registros son de propósito general. A nivel de software aparecen los nuevos lenguajes de alto nivel BASIC, PASCAL, C; y hay gran avance en los S.O. especialmente con el UNIX que permite la multiprogramación. Entre los equipos más detacados tenemos a los computadores IBM 360, PDP-8 y PDP-11. Dos mejoras en la tecnologı́a de las computadoras en 1971 marcan el inicio de la cuarta generación: el reemplazo de las memorias con núcleos magnéticos, por las de chips de silicio, y la colocación de muchos más componentes en un chip. Intel llevó esta idea a la conclusión lógica creando el microprocesador, un chip que contiene todos los circuitos requeridos para hacerlo programable. El tamaño reducido del microprocesador hizo posible la creación de las computadoras personales (PC). Para 1972, dos jóvenes programadores, Bill Gates y Paul Allen habı́an fundado una empresa 1.1. Desarrollo Histórico Página: 5 de 31 llamada Traf-O-Data, en esta fecha Gates y Allen estaban completando un programa que podı́a traducir instrucciones escritas en BASIC a los códigos de lenguaje de máquina que requerı́an los procesadores de Intel. La Traf-O-Data se convirtió en Microsoft Corporation para vender el programa de BASIC Gates-Allen y la licencia del Microsoft BASIC se concedió a MITS a finales de 1975. En la primavera de 1976 un joven técnico de la Hewlett-Packard llamado Steve Wozniak compró un microprocesador de MOS Technology y se propuso construir una computadora a partir de él. Esta computadora, la Apple I, se exhibió en el Homebrew Computer Club (club de computadoras hechas en casa) en el Valle del Silicio. Wozniak ofreció su diseño a Hewlett-Packard, que no se interesó por él. Un amigo de Wozniak, Steve Jobs, le propuso que formaran una compañı́a para vender la Apple. Con la ayuda financiera y administrativa de Mike Markkula, antiguo ingeniero y ejecutivo de mercadeo de Intel, Apple, con su Apple II, se convirtió repentinamente en un competidor importante en la industria de las computadoras. La cuarta generación, que comprende desde 1971 hasta el presente, se distingue por el microprocesador y la computadora personal. Todo esto gracias al incremento de la escala de integración (SSI, MSI, LSI, VLSI) lo que permitió integrar en un chip todo un procesador. También en esta generación se logra más integración de las memorias; los discos duros tienen más capacidad; aparecen los coprocesadores (FPU) para el tratamiento en punto flotante y los gestores de memoria (MMU). A nivel de software se normaliza el uso de la memoria virtual; los S.O. permiten la multitarea y el multiproceso; se producen avances en los lenguajes de alto nivel. Todo esta evolución en las herramientas y tecnologı́a para el cómputo no lleva a lo que llamamos actualmente computador o computadora que no es más que un dispositivo que permite procesar datos siguiendo las instrucciones de un programa para obtener algún tipo de resultados. La figura 1.1 muestra el esquema básico de los procesos de cáculo utilizando computadores. Es importante destacar que tanto los datos, como los programas y los resultados no forman parte Figura 1.1: Esquema de un sistema de computo. del computador, sino que le son suministrados por el usuario, y es justamente esta caracterı́stica la que hace tan versátiles a los computadores. El hecho de permitir el procesamiento de cualquier tipo de información de acuerdo a las necesidades que cada usuario pueda tener, hace que el computador sea una herramienta multiuso, como ninguna otra creada por el hombre. 1.1. Desarrollo Histórico Página: 6 de 31 1.2. Arquitectura básica del computador Actualmente los computadores están siendo utilizados practicamente en todas las actividades que realizamos, pero, ¿cómo están construidas estas máquinas para poder realizar tantas tareas tan diferentes? Básicamente todo computador está compuesto por cuatro componentes: El procesador, la memoria, los dispositivos de entrada y salida, y los canales de comunicación que conectan los tres componentes anteriores. La figura 1.2 muestra en forma esquemática y simplificada la forma como se relacionan las partes del computador. Figura 1.2: Arquitectura interna de un computador. 1.2.1. El Procesador El procesador es el motor del sistema de cómputo, se encarga de ejecutar las instrucciones dadas en el programa realizando operaciones aritméticas y lógicas a los datos. Tı́picamente los sistemas tienen un único procesador conocido como Unidad Central de Procesamiento o CPU Central Processing Unit, pero actualmente muchos sistemas de computación poseen más de un procesador, por ejemplo existen computadores con procesadores vectoriales y con procesadores paralelos. El procesador está compuesto por: la unidad de control, la unidad aritmética y lógica, los registros y los microprogramas. La operacion de un procesador está caracterizada por el ciclo Buscar - decodificar - ejecutar. En el primer paso el procesador busca la instrucción a ejecutar en la memoria, la dirección de memoria donde se encuentra la instrucción se almacena en un registro interno conocido como PC Program Counter. Mientras el procesador espera por la información solicitada el PC se incrementa. 1.2. Arquitectura básica del computador Página: 7 de 31 En la etapa de decodificación, la instrucción solicitada a la memoria se almacena en otro registro interno el IR Instruction Register. El IR contiene código de una instrucción simple en código de máquina, la cual es decodificada y ası́ poder realizar las operaciones necesarias para ejecutar la instrucción en el próxima etapa del ciclo. En la etapa de ejecución se lleva a cabo la instrucción. Frecuentemente para llevar a cabo una instrucción se requieren otras operaciones que involucran a la memoria, como por ejemplo buscar el o los operandos en la memoria y almacenar el resultado de la operación. Una vez culminada la instrucción el procesador busca una nueva instrucción, cerrandose el ciclo. 1.3. La Memoria La memoria es un componente pasivo que simplemente almacena información hasta que otro componente la requiera. La memoria puede actuar alimentando al procesador con datos e instrucciones, para luego servir tanto de fuente como de destino para la información trasferida por los dispositivos de entrada y salida. Para tener acceso a la información que se encuantra en la memoria, es necesario hacer referencia a la dirección de memoria en la cual la información se encuentra. 1.4. Los Dispositivos de Entrada y Salida Los dispositivos de entrada y salida E/S (I/O Input/Output) trásfieren información, sin alterarla, entre el mundo exterior y uno o más componentes internos del computador. Algunos dispositivos E/S sirven para que el usuario se comunique directamente con el computador, por ejemplor, el teclado, el ratón, el monitori o la impresora; pero existen otro tipo de dispositivos E/S que han sido diseñdos especı́ficamente para cumplir con ciertas tareas como la de adquirir datos de un equipo o controlarlo. 1.5. Los Canales de Comunicación Los canales de comunicaciones mantienen unidos a el resto de los componentes que conforman al computador. Estos canales pueden ser tan simples, y solamente conectar a dos componentes, o mucho más complejos, conmutando para permitir la comunicación entre cualesquiera de los multiples componentes del sistema cuando esto sea necesario. 1.3. La Memoria Página: 8 de 31 Capı́tulo 2 Diseño Algorı́tmico 2.1. Algoritmos La palabra algoritmo proviene del nombre del famoso matemático Abu Ja’far Muhammad ibn Musa al-Khwarizmi1 (780-850), conocido como el padre del álgebra. Se sabe poco de su vida salvo que vivió en la primera mitad del siglo IX y que trabajó en la biblioteca del califa de Bagdad. Escribió libros sobre geografı́a, astronomı́a y matemática. En su obra Artimética, traducida al latı́n como Algoritmi de numero Indorum explica con detalle el funcionamiento del sistema decimal que usaban en la India y los algoritmos para calcular con este sistema de numeración. Esta obra fue de gran importancia pues contribuyó a la difusión en occidente del sistema de numeración ı́ndio y al conocimiento del cero. Actualmente el término algoritmo se refiere a una secuencia ordenada y finita de pasos, excenta de ambigüedades, que seguidas en su orden lógico nos conduce a la solución de un problema especı́fico. Los algoritmos deben: Estar compuestos de pasos o instrucciones simples. No tener ambigüedades. Seguir un orden preestablecido. Ser efectivo, es decir debe resolver el problema de forma general y en un número finito de pasos. Ser preciso. Bajo las mismas condiciones el algoritmo siempre debe arrojar los mismos resultados. En general las instrucciones básicas que se pueden dar en un algoritmo son: obtención de datos de alguna fuente externa al algoritmo; asignación, que consiste en darle un valor especı́fico a una variable; decisión, que es la acción de seleccionar, de acuerdo a alguna condición, cuál instrucción continúa en el algoritmo; repetición, que sirve para indicar que una o varias instrucciones se deben efectuar más de una vez; y por último devolución de los resultados. 1 al-Khwarizmi nació en lo que hoy se conoce como Uzbekistán, al sur del mar Aral. Su nombre significa ”Mohamed, hijo de Moisés, padre de Jafar, el de Khorezm” Página: 9 de 31 2.2. Aspectos Básicos de los Algoritmos Como ya se menciono anteriormente, los algoritmos son una serie de instrucciones sencillas que se siguen para resolver un problema. Pero el término sencillo depende fundamentalmente de quién es nuestro interlocutor, es decir, a quién le estamos dando esas instrucciones. Por ejemplo, si nuestro problema consiste en hacer un depósito en un banco y nuestro interlocutor es un adulto que con frecuencia va al banco, el algoritmo se reducirı́a a dos o tres pasos: 1. Ir al banco 2. Llenar la planilla de depósito 3. Entregar en la taquilla la planilla y el dinero Para un usuario del sistema bancario son suficientemente simple estos tres pasos, pero si nuestro interlocutor es un niño que por primera vez va a un banco las instrucciones no son tan sencillas y nuestro algoritmo deberá explicar con un mayor número de pasos, que serán más sencillos. Cuando diseñamos algoritmos para volverlos programas las instrucciones se las estamos dando a un computador. El computador no comprende ni hace suposiciones por lo que para el diseño de algoritmos existe una serie de reglas muy bien definidas, las cuales son seguidas por los lenguajes de programación de proposito general. Estas reglas que permiten darle al computador las instrucciones necesarias para resolver un problema se conoce con el nombre de sintaxis. 2.3. Sintaxis de los algoritmos Todo mecanismo de comunicación está basado sobre unas reglas que permiten a los interlocutores poder entenderse entre sı́. Los lenguajes humanos, como el castellano, muchas de estas reglas son tácitas, por lo que no nos percatamos de su existencia, pero además, suelen ser ambiguas, por ejemplo la expresión: Pedro tiene 20 años puede ser cierta o no dependiendo de a cual Pedro nos estemos refiriendo en ese momento. Esto ocurre a pesar de que la expresión es sintácticamente correcta. Para evitar las ambigüedades, el lenguaje utilizado para diseñar algoritmos posee una sintaxis explı́cita y definida de tal forma que evita cualquier interpretación que no sea la interpretación definida en el lenguaje. A continuación describiremos los componentes de lenguaje utilizado para escribir algoritmos, con sus respectivas sintaxis; ası́ como la forma correcta de combinar estos componentes. 2.3.1. Identificadores Los identificadores se usan para darle nombre a las cosas en el algoritmo. Un identificador está formado por una letra o el caracter underscore ” ”seguido o no por una secuencia de letras, dı́gitos y/o caracteres underscore. Ası́ son identificadores válidos A345x , 234 , mI nomBrE y Peso 2 1 . Hay que destacar que el único sı́mbolo especial que puede formar parte de un identificador es el underscore ” ”, que puede ser utilizado para sustituir al espacio en blanco entre las palabras en los identificadores. También es importante mencionar que los identificadores no pueden comenzar con un dı́gito. 2.2. Aspectos Básicos de los Algoritmos Página: 10 de 31 2.3.2. Palabras reservadas Existen una serie de secuencias válidas como identificadores que no pueden ser usadas con tal fin debido a que tienen una función preestablecida. A estas secuencias se les da el nombre de palabras reservadas. Entre las palabras reservadas tenemos a todos identificadores predefinidos de constantes (Pi, . . . ), funciones (sin, cos, ln, exp, . . . ) y procedimientos (obtener, devolver, . . . ). También son palabras reservadas las secuencias utilizadas en las estructuras de programación (si, sino, segun, mientras, repita, desde, . . . ). 2.3.3. Sı́mbolo especiales El conjunto de caracteres consta de 256 elementos2 , algunos de los cuales por tener un significado especial en los algoritmos y en los lenguajes de programación se denominan sı́mbolos especiales. Entre los sı́mbolos especiales3 tenemos a los operadores aritméticos + - * / ÷ %, y lógicos ¬ ∧ ∨; los sı́mbolos relacionales = < > 6= ≥ ≤ , y de agrupación { } ( ) [ ] ; los signos de puntuación . , ; : ! ? y las comillas ’ "‘. Por esto los sı́mbolos especiales no se pueden utilizar en los identificadores y su uso está definido por la reglas sintácticas y semanticas del seudolenguaje utilizado para diseñar los algoritmos y en los lenguajes de programación. Existe una norma en casi todos los lenguajes de proposito general en cuanto al uso del punto como indicador de decimales en los números reales y también como instanciador de campos en registros y atributos en clases. En cuanto a la coma, tambien existe un acuerdo en utilizarla como separados de elementos en listas. 2.3.4. Tipos de Datos Los datos en el computador son almacenados como secuencias binarias, es decir secuencias de ceros y unos. Para saber como interpretar en el algoritmo y en los programas tales secuencias a cada dato y a cada expresión se le asocia un tipo de dato. Los datos son valores de determinado tipo; se asignan a variables, se asocian a constantes, resultan de la evaluación de expresiones. Los tipos básicos de datos se clasifican como: Entero: 260, -34 (*) Real: 3.713, -4.5E-3, 0.12 predef inidos Caracter ’m’, ’9’, ’@’ (*) simples Lógico Cierto,Falso (*) ( Escalar: (azul,rojo,verde) (*) construidos Rango: datos ’a’..’z’, 2..7 (*) n predef inidos Archivo: archivo de texto estructurados ( Arreglo: (1,4,20,12,3),(’a’,’x’,’f’) construidos Cadena: ’tarea’, ’x+y’ (*): 2 3 tipo de dato ordinal. Los 256 caracteres están reunidos en la tabla ASCII, apéndice A. La sintaxis y semantica de los operadores aritméticos, logicos y relacionales se desarrolla en la seccion 2.3.8. 2.3. Sintaxis de los algoritmos Página: 11 de 31 Datos ordinales son aquellos datos que pueden ordenarse realizando una asociación uno a uno con el conjunto (o un subconjunto) de los números enteros. 2.3.5. Constantes Numéricas enteras Numéricas punto flotante Cadenas de caracteres 2.3.6. Variables Las variables son utilizadas para almacenar datos que pueden ser modificados a medida que el algoritmo avanza. Para definir una variable hay que asignarle un identificador válido al cual llamaremos nombre de la variable. Además del identificador cada variable tiene asociado un tipo de dato, el cual no debe cambiar a lo largo del algoritmo. Lo que puede cambiar es el valor contenido en la variable, esta lo adquiere a través de una operación de lectura o una instrucción de asignación. Es importante mencionar que algunos lenguajes de programación inicializan las variables con algún valor determinado, pero asumir que esto va a ocurrir no se considera una buena práctica ya que es algo dependiente del lenguaje. Por esto siempre se debe asignarle el valor a una variable antes de que esta intervenga en una expresión. El nombre de la variable lo podemos interpretar como una forma de escribir la dirrección de memoria donde el computador almacena el dato asociado a esa variable. El tipo determina la cantidad de memoria necesaria para almacenar dicho dato y además permite interpretar el contenido de la memoria, una sucesión de unos y ceros, de forma adecuada. Por último, el valor es lo que se utiliza en las expresiones una vez haya sido interpretado según el tipo correspondiente a esa variable. 2.3.7. Subprogramas Cuando hay que realizar una misma tarea en diferentes partes del algoritmo es conveniente recurrir a los subprogramas. También se recurre a los subprograma como una forma de solucionar problemas grandes dividiendolos en problemas cada vez más pequeños. Existen dos tipos de subprogramas, los procedimientos y las funciones. Los procedimientos permiten estructurar el programa agrupando una serie de instrucciones bajo un nombre que se convierte en una nueva instruccion dentro del algoritmo. Un procedimiento está definido por un identificador válido seguido de la lista de parámetros o argumentos de entrada y salida encerrados entre paréntesis y separados por comas: Id(e1 , . . . , en ) donde, Id corresponde al identificador del procedimiento y ei la i-esima expresión correspondiente al argumento i. Hay que mencionar que la lista de parámetros puede estar vacia y que en el caso de los parámetros de salida las únicas expresiones permitidas son las variables. 2.3. Sintaxis de los algoritmos Página: 12 de 31 Las Funciones también agrupan instrucciones, pero a diferencia de los procedimientos no se crea una nueva instrucción sino una expresión. Es por esto que para definir una función, además de del identificador y la lista de parámetros, hay que definir el tipo de dato que devuelve la función. Como regla general, las funciones devuelven un único valor, por lo que en la lista de parámetros solamente hay expresiones que representan las entradas: Id(e1 , . . . , en ) ∈ tipo donde, tipo es el tipo de dato que retorna la función. Los subprogramas también tienen asociado el algoritmo que resuelve la tarea o problema para el cual fue creado. En el capı́tulo ?? se profundizará en este aspecto. 2.3.8. Expresiones Las expresiones son estructuras utilizadas en los algoritmos para calcular nuevos valores. Su estructura está compuesta por uno o más operandos separados por operadores. Operandos y operadores pueden ser agrupados para darle claridad a una expresión o para forzar un orden especı́fico de evaluación. Los operandos están conformados por expresiones (constantes, variables, funciones, o una combinación de ellos). Operadores Los operadores de pueden clasificar en unarios y binarios, según el número de operandos sobre los que actuan. También se pueden clasificar de acuerdo al tipo de datos sobre los cuales operan. De acuerdo a este criterio tenemos operadores aritméticos, que operan sobre valores numéricos; operadores relacionales, que comparan dos valores; y operadores lógicos que actúan sobre valores booleanos. La tabla 2.1 muestra los operadores aritméticos e indica su sintaxis, su semántica, los tipos de datos de los operandos y el tipo de dato del resultado de la operación. Sı́mbolo Sintaxis Operandos + A+B Enteros o R − A−B Enteros o R ∗ A∗B Enteros o R / A/B Enteros o R ÷ A÷B Enteros % A %B Enteros Expresión Tipo Mayor Tipo Mayor Tipo Mayor R Entero Entero Semántica Suma A más B Resta A menos B Multiplica A por B Divide A entre B Divide A entre B A módulo B Tabla 2.1: Sintaxis y semántica de los operadores aritméticos. En la primera columna se muestra el sı́mbolo especial utilizado como operador. La segunda columna muestra la sintaxis, A y B identifican a los operandos de cada expresión. La tercera indica que tipo de datos son válidos como operandos. En la cuarta columna se indica el tipo de dato resultante al efectuar la operación. Tipo Mayor se refiere al tipo de mayor rango de los dos tipos de los operandos. Por último, la quinta columna muestra la semántica del operador. La tabla 2.2 muestra la sintaxis y semántica de los operadores relacionales. Es importante destacar que los operandos que acompañan a los operadores relacionales deben ser de tipos compatibles, es decir que deben poder compararse para establecer el resultado de la operación. 2.3. Sintaxis de los algoritmos Página: 13 de 31 Sı́mbolo Sintaxis Semántica + A=B Verdadero si A es igual que a B − A 6= B Verdadero si A es distinto que B ∗ A>B Verdadero si A es mayor que B / A<B Verdadero si A es menor que B ÷ A≥B Verdadero si A es mayor o igual que a B % A≤B Verdadero si A es menor o igual que a B Tabla 2.2: Sintaxis y semántica de los operadores relacionales. Por ejemplo, es sintácticamente válido comparar números enteros con números reales, como en la expresión 14 >3.56. Pero no tiene sentido y es un error sintáctico comparar un caracter o una cadena de caracteres con un número. Las cadenas de caracteres se comparan alfabéticamente, como se ordenan en las guias telefónicas, y según el orden de la tabla ASCII4 los operadores relacionales = y 6= fallan muchas veces al utilizarlos con valores reales. Funciones Existe un conjunto de funciones predefinidas que podemos utilizar en los algoritmos y que todo lenguaje de programación de propósito general también las tiene. Entre las más importante tenemos: 4 En el Apéndice A está la tabla ASCII. 2.3. Sintaxis de los algoritmos Página: 14 de 31 Descripción f(x) Potencias: 2 Cuadrática x √ Radical x Trigonométricas: Seno sin(x) Coseno cos(x) Arco tangente tan−1 (x) Exponenciales y Logarı́tmicas: Exponencial ex Logaritmo ln(x) Ordenamiento: Siguiente siguiente(x) Anterior anterior(x) Conversión: Truncamiento truncar(x) Redondeo redondear(x) Ordinal ordinal(x) Caracter caracter(x) Impar impar(x) Otras: Valor Absoluto |x| Parte Entera |[x]| Parte Decimal f rac(x) 2.4. Notación x f(x) sqr(x) sqrt(x) Numérico Numérico + R R sin(x) Numérico cos(x) Numérico arctan(x) Numérico R R R exp(x) ln(x) Numérico R Numérico ⊕ R succ(x) pred(x) Ordinal Ordinal Conserva el tipo Conserva el tipo trunc(x) round(x) ord(x) chr(x) odd(x) Numérico Numérico Ordinal N Z Z Z Numérico ch L abs(x) int(x) frac(x) Numérico Numérico Numérico Conserva el tipo R R Evaluación de expresiones Al evaluar la expresión: 2 − 6/2 ∗ 3 − 1 ¿Cuál es el resultado correcto? −7, −1, −8. El problema con este ejemplo es consecuencia de la ambigüedad en la forma como evaluamos las expresiones en la vida cotidiana. En los algoritmos la evaluación de expresiones se efectúa según una reglas, llamadas precedencia de operadores, que asignan prioridades relativas entre ellos evitando la ambigüedad. La tabla 2.3 muestra la prioridad de evaluación de cada uno de los operadores. Prioridad 1 2 3 4 5 Tipo Paréntesis Unarios y funciones Multiplicativos Aditivos Relacionales Operadores () ¬ − sin cos ln . . . ∗/ ÷ %∧ +−∨ =6=<>≤≥ Tabla 2.3: Precedencia de operadores. 1 donde los tipos de datos básicos son: Entero (Z), Real (R)), Caracter (Ch), Cadena (Cadena), Lógico (L). 2.4. Evaluación de expresiones Página: 15 de 31 El resultado de la evaluación de una expresión debe ser: almacenado en la memoria del computador, mediante una instrucción de asignación; mostrado en pantalla, utilizando una llamada al procedimiento devolver; o almacenado en la memoria secundaria utilizando los subprogramas para el manejo de las operaciones de entrada y salida. 2.5. Metodologı́a General Para diseñar un algoritmo se debe, en primer lugar, analizar el problema que se pretende solucionar, para ası́ comprenderlo y poder definirlo en términos de datos de entrada y salida que se espera obtener del algoritmo. Se propone una metodologı́a general para atacar el problema de diseñar una solución algorı́tmica la cual divide el problema en 5 secciones: Análisis de entrada: Se describen los datos de entrada especificando el tipo y de ser posible el rango. Los datos se asocian con las variables que se utilizarán para almacenarlos. Por ejemplo para un algoritmo donde los datos de entrada son el nombre, la edad y el peso de una persona, tendrı́amos: Análisis de entrada nombre Cadena Nombre de la Persona edad ∈ N ; ∈ {0, . . . , 120} Edad en años peso ∈ R; > 0 Peso en Kg donde nombre, edad y peso son los identificadores de las variables utilizadas para almacenar los datos de entrada. Análisis de salido: Se describe la información que el algoritmo debe dar como salida, especificando el tipo de dato. Por ejemplo, si el algoritmo calcula el punto de intersección de dos rectas, esta sección mostrarı́a: Análisis de salida x,y ∈ R coordenadas del punto de intersección Proceso: En esta sección se hace una descripción general de como se atacará el problema. La descripción debe ser los suficientemente detallada como para que otra persona pueda entender a groso modo la solución planteada pero sin entrar en los detalles. Para ello, además de escribir, se puede hacer uso de dibujos, formulas o cualquier otro medio que ayude a entender la forma como se va a solucionar el problema. Consideremos el problema de calcular el promedio de una serie de datos: Proceso Como de antemano no se conoce la cantidad de datos de la serie, los datos (x) se van leyendo uno a uno, incrementando un contador (n) y sumandolos en un acumulador (acum). Luego de leer cada dato se le pregunta al usuario si ya no hay más datos en la serie. Una vez introducidos todos los datos se calcula el promedio utilizando la siguiente ecuación, acum promedio = n Por último se muestra el resultado. 2.5. Metodologı́a General Página: 16 de 31 En los casos en que el problema sea muy complejo y la solución requiera atacarlo por partes, la descripción de dichas partes se hará en esta sección. Algoritmo: Siguiendo los lineamientos dados en la sección Proceso, escribimos el algoritmo en esta sección. Como ya se mencionó, el algoritmo es una secuencia de pasos simples que tienen una sintaxis no ambigua por lo que sus reglas son muy estrictas. A pesar de no haber estudiado aún los diferentes tipos de instrucciones que se utilizan en los algoritmos, el siguiente ejemplo nos ilustra como se ve esta sección Algoritmo obtener(a,b,c) disc ← b*b - 4*a*c devolver("Las raices son:") si ( disc >= 0 ) x1 ← (-b + sqrt(disc))/(2*a) x2 ← (-b - sqrt(disc))/(2*a) devolver("x1 = ",x1) devolver("x2 = ",x2) sino r ← -b/(2*a) i ← sqrt(-disc)/(2*a) devolver("x1 = ",r,"+",i,"i") devolver("x1 = ",r,",i,"i") Análisis de variables: Es la última sección y en ella se describen todas las variables que se utilizaron en el algoritmo. Por ejemplo para el caso anterior tenemos: Análisis de variables a,b, c, disc, x1, x2, r, i 2.6. ∈ R Problemas Diseño Algorı́tmico. Realice el análisis de entrada, el análisis de salida y el proceso para los siguientes problemas cotidianos. 1. Preparar una torta 2. Utilizar un teléfono público 3. Multiplicar dos números de 4 dı́gitos 4. Inscribirse en el semestre 5. Utilizar el transporte público 6. Dividir dos números Transcripción de fórmulas. Sean a, b, c, x, y, z variables, escriba las siguientes expresiones utilizando notación para algoritmos: 2.6. Problemas Página: 17 de 31 1. t (2n+1)2 π 2 a2 +b − 4t2 2 (2n+1)2 (1+ 4li b (2n+1)2 π 2 a2 ) xm−1 (2n−m−1)a(ax2 +bx+c)n−1 e 2. − 3. [(a+b)5 − (3c+2x )] 5+3yz √ √ 4. c ax (cos(bx)−sin(bx)) a2 +b2 +e + 2a (a − 3b + 2z ) [3c−2x9 ] −1 |2y|+3 5. Sean a, b, l, t ∈ R, n ∈ Z t (2n+1)2 π 2 a2 − +b 4t2 e 4l2 b (2n+1)2 (1+ ) (2n+1)2 π 2 a2 m+1 6. x 1 ln(x) − m+1 m+1 7. (a+b)3c(a+b) (a+b)5 − (a+b)d(a+b) √ (a+b) 8. 9. 10. 11. (a − 3b + 2z) √ x + y 3 + e|a| − √ r b a√ √a ! b 3c−2x9 −1 |2y|+3 b2 c+d xn+1 y n−1 − i cos(a+b) r b a ln √ l b a √ l b −1 cos a √a sin−1 b Identificación de expresiones. Escriba las siguientes expresiones utilizando notación matemática. 1. a/sqrt(b)*abs(r*sqrt(b)/a)/ln(r*sqrt(b)/a) 2. -exp(a*x)/exp((n-1)*ln(x))/(n-1)+a/(n-1)*4/a*sqr(a)/sqrt(a) 3. a/raiz(b)*sinh(l*raiz(b)/a)/cosh(l*raiz(b)/a) 4. x/p/p + 1/a/(p*(p+q*exp(a*x))) - 1/p/a*1/p*ln(p+q*exp(a/x*x/x)) 5. exp(sqrt(sqrt(a/b/d*c)+3)) + ln(x+y/ln(z)) 2.6. Problemas Página: 18 de 31 Capı́tulo 3 Sentencias o instrucciones Simples Las instrucciones simples son aquellas que realizan una única acción y de ellas no depende directamente la ejecución o no de otras instrucciones. Pueden ser de dos tipos: asignación y llamada a procedimiento. 3.1. Asignación La asignación es la instrucción que permite almacenar un valor en una variable, es decir, el resultado de evaluar una expresión es almacenado en el espacio de memoria reservado a una variable. Su sintaxis es la siguiente: Id variable ← expresión Hay que destacar que el tipo de dato resultante de la evaluación de la expresión debe ser compatible con el tipo de dato de la variable, esto es, que el resultado de la expresión pueda ser almacenado e interpretado correctamente como el valor contenido en la variable. La tabla 3.1 muestra las posibles combinaciones de tipos en las asignaciones. Además de la compatibilidad, Variable N Z R L Ch Expresión N N, Z N , Z, R L Ch Tabla 3.1: Compatibilidad de los tipos de datos en la asignación. es importante garantizar, ya en el momento de la implementación del código del programa, que el resultado de la expresión no desborde la capacidad del tipo de dato de la variable, por ejemplo, el tipo de dato byte del lenguaje Pascal, utilizado para almacenar números naturales, utiliza 8 bits para almecenar el valor, por lo que solamente se le pueden asignar valores entre 0 y 255 ( 28 = 256 valores diferentes), de lo contrario ocurrirá un desbordamiento de la capacidad de almacenamiento de la variable. Por último, al asignarle un valor a una variable se pierde irremediablemente el valor que tenı́a asignado anteriormente, por ejemplo, en el segmento de algoritmo siguiente: Página: 19 de 31 .. . a ← b+c a ← 34 .. . El resultado de la suma de b+c que se almacenó en a en la primera asignación, es sobreescrito por el valor 34 en la segunda asignación de la variable a, y por lo tanto se pierde. 3.1.1. Casos Relevantes A continuación se presentan algunos usos frecuentes que se le dan a la instrucción de asignación: Incremento y Decremento Muchas veces en un algoritmo se necesita asignarle un nuevo valor a una variable, pero este nuevo valor está relacionado con el valor que la variable tiene en el momento en el que se realiza la asignación, por ejemplo, trascurrido un año, hay que incrementar en uno la edad de cierta persona. La forma de realizar estas tipo de operaciones es la siguiente: .. . edad ← edad+1 .. . note que, como primero se evalua la expresión y luego se procede a asignar a la variable edad el resultado de la evaluación, el valor de la edad con esta instrucción se incrementa en uno. Estas operaciones se pueden utilizar con cualquier otro tipo de operadores y utilizando expresiones más complejas, pero hay que tener en cuenta que el orden en que se ejecuta la instrucción es: primero se evalua la expresión según las normas de precedencia y luego se efectua la asignación del resultado de la evaluación a la variable. Intercambio (swap) Otra operación que frecuentemente se utiliza en los algoritmos y en la que interviene la asignación es la de intercambio de los valores contenidos en dos variables. a continuación se presentan tres alternativas para realizar el intercambio caso 1 .. . caso 2 .. . caso 3 .. . x ← y y ← x NO FUNCIONA .. . y ← x x ← y NO FUNCIONA .. . aux ← x x ← y y ← aux .. . En el caso 1, en la primera asignación a la variable x se le asigna el valor contenido en la variable y y en consecuencia el valor previo que contenia x se pierde. Ası́, en la segunda asignación el valor de y no se altera, ya que el valor previo de x se ha perdido. Lo mismo ocurre en el caso 2, con la salvedad de que el valor de x no se altera y el de y se pierde. Este es un problema equivalente al de intercambiar el contenido de dos botellas y para resolverlo necesitamos una tercera variable (botella) en la que se almacena temporalmente el 3.1. Asignación Página: 20 de 31 contenido de una de las dos variables (botellas) a intercambiar. En el caso 3 a esta variable la hemos llamado aux, y es ella la que almacena temporalmente el valor contenido en x mientras a x se le asigna el valor de y, para que finalmente se le asigne a y el valor original de x que está almacenado en aux. 3.2. Llamada a procedimiento Su sintaxis es la siguiente: Id procedimiento(lista parámetros) 3.2.1. Casos Relevantes Instrucciones de Entrada y Salida estas instrucciones le permiten al usuario interactuar con algoritmo, a continuación se presentan algunas de estas instrucciones: obtener(v1 ,...,vn ) Asigna a las variables v1 ,...,vn los valores dados a través del teclado. devolver(e1 ,...,en ) Muestra los valores e1 ,...,en de las expresiones en la pantalla. 3.3. Problemas Identificación de variables y ejecución en frio de algoritmos 1. Para a, inicial de su primer apellido, b y c, los dos últimos dı́gitos de su cédula. Identifique los tipos posibles de cada una de las variables que intervienen en el siguiente algoritmo y determine el valor de cada una en cada paso del algoritmo. A: obtener a,b,c d ← a b ← ord((sqr(b) - 100*(c+1))>0)* 5 e ← b % ord(a) f ← ch(ord(a)+1) = d c ← e/b 2. Tomando a x, y y z como las iniciales de su primer apellido, segundo apellido y primer nombre; Identifique los tipos posibles de cada una de las variables que intervienen en el siguiente algoritmo y determine el valor de cada una en cada paso del algoritmo. Si hay errores identifı́quelos A: obtener a,b,c a ← ord(x) b ← ord(y) 3.2. Llamada a procedimiento Página: 21 de 31 c ← ord(z) s ← 1/2*(a+b+c) nombre ← sqrt(s*(s-a)*(s-b)*(s-c)) f ← ch(ord(x)+1) 6= s p ← s %(a+b+c) 3. Bajo cuales condiciones las siguientes instrucciones son válidas. Si no son válidas ¿Qué correcciones hay que hacerles para convertirlas en expresiones válidas? X x Y ← C y = CON a ← B% c X-5 ← Y X ← y + 43. B ← C.3 + C.6 x → sqrt(16) 5 ← x 4. Calcular el valor de cada expresión, en caso de que sea válida indicar si este es real o entero. Si la expresión no es válida explicar porque. 10/3+5*2 10 ÷ 3 + 5 % 2 12.5 + (2.5/(6.2/3.1)) -4*(-5+6) 13 % 5/3 5. Indicar los valores de cada una de cada uno de los identificadores. N a b c a r ← ← ← ← ← ← 4; 5; a*N a% n c; a + b; 6. Si A es real y B es entero, mostrar lo que se verı́a en pantalla con cada una de las siguientes instrucciones si A sea igual a 5 y B a 2. devolver(’A=’,A,’B=’,B) devolver(’suma=’A+B) devolver(A % B) (B - A) 7. Bajo cuales condiciones las siguientes instrucciones en son válidas. Si no son válidas ¿Qué correcciones hay que hacerles para convertirlas en expresiones válidas? X*5 → Y Pi ← 2 3.3. Problemas Página: 22 de 31 2sin(x) ← C t → 9,2 + 2.X + sin X ← y / 43. x ← abs(16) E ← nombre % q axb ← 10 3.14156 ← Pi 8. Calcular el valor de cada expresión. En caso de que la expresión sea válida indicar si el resultado es real o entero. Si la expresión no es válida explicar porque. 7*3+4/2/(2*2) 12 % 5 ÷ (6/2) 10 - 3 + (6/2/3) (-1*-10) % 2 13 ÷ 8/4 9. Indicar los valores de cada uno de los identificadores. X ← 7; Expo ← 5; Nuevo ← X/expo+expo resultado ← Expo % X Expo ← resultado * x; salida ← Expo / resultado; 10. Si X es real y Y es entero, mostrar lo que se verı́a en pantalla con cada una de las siguientes instrucciones cuando X sea igual a -4 y Y a 6. devolver(’X+’,Y,’X/’,X) devolver(’resta=’X/Y) devolver(Y MOD TRUNC(X)) devolver(X + Y) ———————– Diseño algorı́tmico Recuerde que el diseño algorı́tmico debe incluir el análisis de entrada y salida, el proceso, el algoritmo y el análisis de variables; para cada uno de los programas. 1. Calcule el área y el volumen de un cilindro de radio R y altura H (en centı́metros) sabiendo que las formulas son: A = 2πR2 + 2πRH V = πR2 H 2. Dados los puntos medios de los tres lados de un triángulo, calcule las coordenadas de los tres vertices del mismo. de ellos. 3. Conocidas las coordenadas de tres puntos, calcule el punto que equidista de ellos. 3.3. Problemas Página: 23 de 31 4. Dado el intervalo (a, b) determinar si un número dado pertenece o no al intervalo, la forma de indicar si pertenece al intervalo es retornar el numero dado y si no pertenece se retorna el numero cero (0) 5. Las reglas para determinar los años bisiestos se basan en un decreto del papa Gregorio XIII el cual se adoptó en Gran Bretaña y sus colonias en los años posteriores a 1752: • Cada cuatro años se tiene un año bisiesto • Los años de inicio de siglo no son bisiestos (1800, 1900, ....) excepto si inician un periodo de cuatro siglos (2000, 2400, ...) Realizar el diseño algorı́tmico de un programa que permita ubicar los años bisiestos que abarcan los 16 años precedentes al año indicado (además debe retornar el año indicado sólo si es bisiesto). Ejemplo: Para las entradas 1630, 1752 no debe arrojar resultados Para las entrada 1767 debe proporcionar la salida 1764, 1760, 1756 Para las entrada 1910 debe proporcionar la salida 1908, 1904, 1896 Para las entrada 1995 debe proporcionar la salida 1992, 1988, 1984, 1980 Para las entrada 2000 debe proporcionar la salida 2000, 1996, 1992, 1988, 1984 6. Para facilitar el balance de caja una compañı́a decidió calcular el monto a pagar por el consumo registrado siguiendo el siguiente esquema: • Sólo se aceptan pagos con tarjeta de crédito, cheque o efectivo. • Para los pagos realizados con tarjeta de crédito al monto consumido se le incrementa el 10 %. • Para los pagos en cheque el monto consumido no sufre variación. • Para los pagos en efectivo el monto consumido debe ser “redondeado” a favor del cliente para que pueda realizarse un pago exacto, sabiendo que la mı́nima unidad monetaria válida es el medio (25 centimos). Realizar un diseño algorı́tmico que permita a la compañı́a determinar el monto a cancelar por el cliente si se conoce el monto consumido y la forma de pago. 7. En la final de un torneo del tiro al blanco cada participante tiene tres oportunidades de disparo. Realice el diseño algor—ii ´ tmico para encontrar la distancia promedio con que las balas se acercan al centro de la diana en los tres intentos y calcule el puntaje final que ha acumulado el participante luego de sus tres disparos. El puntaje de cada disparo es relativo a la distancia del punto de impacto de la bala con respecto al centro de la diana según la tabla: distancia puntaje [0, 1) 40 [1, 2) 30 [2, 3) 20 [3, 4) 10 8. Calcule el área del triángulo que se forma entre las rectas: y = m1 ∗ x y = −m2 ∗ x + b y el eje de las x. Suponga que m1 , m2 y b son valores positivos. 3.3. Problemas Página: 24 de 31 9. Calcule el área de un triángulo dadas las coordenadas de los tres vertices del mismo. 10. Utilizando instrucciones simples, realice el diseño algorı́tmico de dos programas que permitan, el primero, transformar el valor de un ángulo dado en grados, minutos y segundos en radianes; y el segundo, realizar el cálculo inverso. 3.3. Problemas Página: 25 de 31 Capı́tulo 4 Estructuras de Selección Hasta este punto hemos utilizado al computador como una calculadora sumamente costosa. Ahora a esta calculadora le daremos algo de “inteligencia” para que pueda escoger si va a ejecutar o no un conjunto de instrucciones de nuestros algoritmo. Las estructuras que permiten decidir si un grupo de instrucciones será ejecutado o no se llaman estructuras de selección. 4.1. Estructuras de Selección Simple Esta estructura permite decidir se se van a ejecutar o no el conjunto de instrucciones asociadas a ella. Su sintaxis es la siguiente: si (exp logica) | instrucciones asociadas donde, si es la palabra reservada que utilizamos para iniciar la estructura de selección; exp logica es una expresión lógica, es decir una expresión que puede tomar el valor de verdadero o falso; y las instrucciones asociadas puede ser una o varias instrucciones cuya ejecución está condicionada por el valor que tome exp logica. Un algoritmo al llegar a una estructura de selección simple lo primero que hace es evaluar la expresión lógica siguiendo las normas para la evaluación de expresiones discutidas en la sección (2.4). Si al evaluar la expresión lógica su resultado es verdadero entonces el algoritmo ejecutará todas las instrucciones asociadas a la estructura. En caso de que al evaluar la expresión lógica, el resultado sea falso no se ejecutará ninguna de las instrucciones asociadas a la estructura de selección. Ejemplo Encontrar el mayor de cuatro números sumar o restar dos vectores 4.2. Problemas 1. Dados cuatro numeros, muéstrelos en pantalla primero ordenados de menor a mayor y luego de mayor a menor. 2. Las raı́ces del polinomio cúbico P (x) = x3 + a1 x2 + a2 x + a3 Página: 26 de 31 se obtienen como 1 x 1 = S + T − 3 a1 √ x2 = − 12 (S + T ) − 31 a1 + 12 3(S − T )i √ x3 = − 21 (S + T ) − 31 a1 − 12 3(S − T )i donde Q= S= 3a2 − a21 9 q R+ √ R= Q3 + R2 T = 9a1 a2 − 27a3 − 2a31 54 q R− √ Q3 + R2 Para a1 , a2 y a3 reales, con discriminante D = Q3 + R2 se sabe que: a) una de las raı́ces es real y dos son complejas conjugadas si D > 0 b) todas las raı́ces son reales y al menos dos iguales si D = 0 c) todas las raı́ces son reales y distintas si D < 01 3. Dado un dı́gito decimal (1 − 9), escriba su correspondiente valor ordinal. Ejemplo: Si el número es 2, la salida debe ser Segundo. 4. Dadas dos rectas en el plano: R1: y = m1 x + b1 , R2: y = m2 x + b2 Determine si las rectas son: Perpendiculares, Paralelas o Cortantes. Además, si no son paralelas, debe mostrar el punto de intersección. 5. Dado un punto en el plano (X,Y) determine si el ángulo que forma el vector que va desde el origen al punto dado (con respecto al eje de las ordenadas) es agudo, obtuso o recto. 6. Dados la hora expresada como HORA:MINUTOS:SEGUNDOS (cada valor es un entero), mostrar la hora un segundo después. 7. Dados el radio y las coordenadas del centro de una esfera,y las coordenadas de un punto en el espacio. Determine si el punto está dentro de la esfera, fuera o sobre la esfera. 8. Dadas las partes enteras e imaginarias de dos números complejos y una operación a aplicar (suma, resta, multiplicación o división). Muestre el resultado de la operación. 9. Dado cuatro notas y sus respectivos porcentajes, calcule la nota definitiva e indique si el alumno reprobó, eximió o aprobó. La escala de las notas es de 0-20, la nota mı́nima aprobatoria es 10 y se exime con una nota igual o mayor a 16 puntos. 10. Dado un polinomio de segundo grado: ax2 + bx + c, Escriba las raı́ces del polinomio. 1 Para D < 0 se puede simplificar el cálculo: √ x1 = 2√−Q cos( 13 θ) x2 = 2√−Q cos( 13 θ + 120o ) , x3 = 2 −Q cos( 13 θ + 240o ) √ cos 4.2. Problemas −1 −1 (x) = tan −R cos(θ) = p −Q3 1 − x2 x ! Página: 27 de 31 Bibliografı́a [1] J. Galve, J. González, A. Sánchez, J. Velázquez Algorı́tmica Addison-Wesley Iberoamericana Madrid 1993 [2] Borland Turbo Pascal. User’s Guide and Reference Guide. Versión 5.0 Borland International Scotts Valley 1990 [3] Crawley, J. W., McArthur ,W. G. Pascal, Programación Estructurada Prentice Hall 1990 [4] Dale, N. y Weems ,C. Pascal McGraw-Hill Madrid 1987. [5] Joyanes, L. Fundamentos de Programación McGraw-Hill Madrid 1988 [6] Joyanes, L. Problemas de Metodologı́a de la Programación McGraw-Hill Madrid 1989 [7] Koffman, A. Pascal Introduccion al Lenguaje y Resolución de Problemas con Programación Estructurada Addison-Wesley Iberoamericana 1988 [8] Konvalina, J., Wilema , S. Programación con Pascal McGraw-Hill Madrid 1989 [9] Schneider, G. M. , Weingart, S. W., Perlman, D. M. An Introduction to Programming and Problem Solving with Pascal John Wiley and Sons New York 1982 [10] Silva, J. G. y Redondo, M. El libro del MS-DOS. Redondo-Silva Editores Mérida 1988 [11] Tremblay, J. P. y Bunt, R. Introducción a la Ciencia de los Computadores. Enfoque Algorı́tmico. McGraw-Hill 1982 BIBLIOGRAFÍA Página: 28 de 31 Apéndice A Tabla ASCII 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Nulo Brk Bell BS Tab LF NP Ret ¶ Esc 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 Esp ! ” # $ % & ( ) * + . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 a b c d e f g h i j k l m n o p q r s t u v w x y z { } Del 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 Ç ü é â ä à ȧ ç ê ë è ı̈ ı̂ ı̀ Ä Ȧ É æ Æ ô ö ò ü ù ÿ Ö Ü 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 á ı́ ó ú ñ Ñ a o ¿ ¬ 1/2 1/4 ¡ a k 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 ⊥ > ` 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 α β Γ Π Σ σ µ τ Φ Θ Ω ∞ φ ∈ ∩ ≡ ± ≥ ≤ ÷ ≈ 2 Página: 29 de 31 Apéndice B Algunas identidades matemáticas Potencias: 1 xy ≡ xy xz x−y ≡ xy+z xyz ≡ (xy )z xy ≡ e(y∗ln(x)) , x>0 Trigonométricas: sen2 (x) + cos2 (x) ≡ 1 sen(x ± y) ≡ sen(x)cos(y) ± cos(x)sen(y) cos(x ± y) ≡ cos(x)cos(y) ∓ sen(x)sen(y) sen(x) tan(x) ≡ , x 6= (2n + 1)π/2, n ∈ Z cos(x) 1 sec(x) ≡ , x 6= (2n + 1)π/2, n ∈ Z cos(x) 1 csc(x) ≡ , x 6= nπ, n ∈ Z sen(x) sen−1 (x) + cos−1 (x) ≡ π/2 x −1 −1 √ sen (x) ≡ tan , |x| < 1 1 − x2 ! √ 1 − x2 cos−1 (x) ≡ tan−1 , |x| < 1 x ctan−1 (x) ≡ tan−1 (1/x), sec −1 −1 csc 2 (x) ≡ cos −1 (x) ≡ sen (1/x), −1 (1/x), x 6= 0 |x| ≥ 1, x 6= 0 |x| ≥ 1, x 6= 0 2 cosh (x) − senh (x) ≡ 1 1 x senh(x) ≡ (e − e−x ) 2 1 x cosh(x) ≡ (e + e−x ) 2 senh(x) tanh(x) ≡ , x 6= 0 cosh(x) Página: 30 de 31 ctanh(x) ≡ sech(x) ≡ csch(x) ≡ cosh(x) senh(x) 1 cosh(x) 1 , senh(x) x 6= 0 Logarı́tmicas: ln(x) ≡ loge (x), loga (x) logb (x) ≡ , loga (b) x>0 x, b > 0 blogb (x) ≡ logb (bx ) ≡ x, y logb (x ) ≡ y logb (x), x>0 x>0 logb (xy) ≡ logb (x) + logb (y) x, y > 0 logb (x/y) ≡ logb (x) − logb (y) x, y > 0 Página: 31 de 31