




























































































Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Asignatura: INTRODUCCION A LA COMPUTACION, Profesor: ARANTZA CASILLAS, Carrera: Ingeniero Químico, Universidad: UPV-EHU
Tipo: Apuntes
1 / 399
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!





























































































En oferta
© c 2003 de Andr´es Marzal Var´o e Isabel Gracia Luengo. Reservados todos los derechos. Esta ((Edici´on Internet)) se puede reproducir con fines autodidactas o para su uso en centros p´ublicos de ense˜nanza, exclusivamente. En el segundo caso, ´unicamente se car- gar´an al estudiante los costes de reproducci´on. La reproducci´on total o parcial con ´animo de lucro o con cualquier finalidad comercial est´a estrictamente prohibida sin el permiso escrito de los autores.
Estos libros de texto desarrollan el temario de la asignatura ((Metodolog´ıa y tecnolog´ıa de la programaci´on)) de las titulaciones de Ingenier´ıa Inform´atica e Ingenier´ıa T´ecnica en Inform´atica de Gesti´on de la Universitat Jaume I. En ella se pretende ense˜nar a programar y, a diferencia de lo que es usual en cursos introductorios a la programaci´on, se propone el aprendizaje con dos lenguajes de programaci´on: Python y C. ¿Por qu´e dos lenguajes de programaci´on? Python y C son bien diferentes. El primero es un lenguaje de muy alto nivel que permite expresar algoritmos de forma casi directa (ha llegado a considerarse ((pseudoc´odigo ejecutable))) y hemos comprobado que se trata de un lenguaje particularmente adecuado para la ense˜nanza de la programaci´on. El lenguaje C exige una gran atenci´on a multitud de detalles que dificultan la implementaci´on de algoritmos a un estudiante que se enfrenta por primera vez al desarrollo de programas. No obstante, C sigue siendo un lenguaje de programaci´on de referencia y debe formar parte del curr´ıculum de todo inform´atico; y no s´olo por su extendido uso en el mundo profesional: su proximidad al computador nos permite controlar con gran precisi´on el consumo de recursos computacionales. Aprender Python antes que C permite estudiar las estructuras de control y de datos b´asicas con un alto nivel de abstracci´on y, as´ı, entender mejor qu´e supone, exactamente, la mayor complejidad de la programaci´on en C y hasta qu´e punto es mayor el grado de control que nos otorga. Por ejemplo, una vez se han estudiado listas en Python, su implementaci´on en C permite al estudiante no perder de vista el objetivo ´ultimo: construir una entidad con cierto nivel de abstracci´on usando unas herramientas concretas (los punteros). De ese modo se evita una desafortunada confusi´on entre estructuras din´amicas y punteros que es frecuente cuando ´estas se estudian ´unicamente a la luz de un lenguaje como C. En cierto modo, pues, Python y C se complementan en el aprendizaje y ofrecen una visi´on m´as rica y completa de la programaci´on. Las similitudes y diferencias entre ambos permiten al estudiante inferir m´as f´acilmente qu´e es fundamental y qu´e accesorio o accidental al dise˜nar programas en un lenguaje de programaci´on cualquiera. ¿Y por qu´e otro libro de texto introductorio a la programaci´on? Ciertamente hay muchos libros que ense˜nan a programar desde cero. Este texto se diferencia de ellos tanto en el hecho de estudiar dos lenguajes como en la forma en que se exponen y desarrollan los conocimientos. Hemos procurado adoptar siempre el punto de vista del estudiante y presentar los conceptos y estrategias para dise˜nar programas b´asicos paso a paso, incrementalmente. La experiencia docente nos ha ido mostrando toda una serie l´ıneas de razonamiento inapropiadas, errores y vicios en los que caen muchos estudiantes. El texto trata de exponer, con mayor o menor fortuna, esos razonamientos, errores y vicios para que el estudiante los tenga presentes y procure evitarlos. As´ı, en el desarrollo de algunos programas llegamos a ofrecer versiones err´oneas para, acto seguido, estudiar sus defectos y mostrar una versi´on corregida. Los apuntes est´an repletos de cuadros que pretenden profundizar en aspectos marginales, llamar la atenci´on sobre alg´un extremo, ofrecer algunas pinceladas de historia o, sencillamente, desviarse de lo central al tema con alguna digresi´on que podr´ıa resultar motivadora para el estudiante. Hemos de recalcar que este libro pretende ense˜nar a programar y no es un manual exhaustivo sobre el lenguaje de programaci´on Python. Son particularmente rese˜nables dos omisiones: los diccionarios y las clases. No forman parte de esta edici´on (aunque pensamos incluirlos en la siguiente como material de estudio opcional) porque hemos preferido centrarnos en aquellos aspectos que tanto Python como C presentan en com´un. Queremos aprovechar para dar un consejo a los estudiantes que no nos cansamos de repetir: es imposible aprender a programar limit´andose a leer unos apuntes o a seguir pasivamente una explicaci´on en clase, especialmente si el per´ıodo de estudio se concentra en una o dos semanas. Programar al nivel propio de un curso introductorio no es particularmente dif´ıcil, pero consti- tuye una actividad intelectual radicalmente nueva para los estudiantes. Es necesario darse una
oportunidad para ir asentando los conocimientos y las estrategias de dise˜no de programas (y as´ı, superar el curso). Esa oportunidad requiere tiempo para madurar... y trabajo, mucho trabajo; por eso el texto ofrece m´as de cuatrocientos ochenta ejercicios. S´olo tras haberse enfrentado a buena parte de ellos se estar´a preparado para demostrar que se ha aprendido lo necesario. Hay centenares de diferencias entre la primera edici´on y esta segunda. No s´olo hemos corre- gido erratas (y errores), hemos a˜nadido tambi´en nuevos ejemplos, modificado otros, preparado nuevos ejercicios, reubicado ejercicios a lugares donde parec´ıan m´as oportunos, etc. Los progra- mas se presentan con una tipograf´ıa que, creemos, facilita notablemente la lectura. El documento PDF ofrece, adem´as, la posibilidad de descargar c´omodamente el texto de los programas (que se pueden descargar de http://marmota.act.uji.es/MTP). Esperamos que esta posibilidad se traduzca en un mayor ´animo del estudiante para experimentar con los programas.
Hemos tratado de seguir una serie de convenios tipogr´aficos a lo largo del texto. Los programas, por ejemplo, se muestran con fondo gris, as´ı:
1 print ’! Hola, mundo!’
Por regla general, las l´ıneas del programa aparecen numeradas a mano izquierda. Esta nu- meraci´on tiene por objeto facilitar la referencia a puntos concretos del programa y no debe reproducirse en el fichero de texto si se copia el texto del programa. Cuando se quiere destacar el nombre del fichero en el que reside un programa, se dispone este en una barra encima del c´odigo:
hola mundo.py 1 print ’! Hola, mundo!’ Si se trabaja con la versi´on electr´onica del libro en formato PDF (disponible en la p´agina web http://marmota.act.uji.es/MTP) es posible acceder c´omodamente al texto de los pro- gramas. Para ello, basta con desempaquetar el fichero programas.tgz (o programas.zip) en el mismo directorio en el que est´e ubicado el documento PDF. Los programas accesibles tienen un icono que representa un documento escrito en la esquina superior izquierda. Junto al icono aparece el nombre real del fichero: como ofrecemos varias versiones de un mismo programa, nos hemos visto obligados a seguir un esquema de numeraci´on que modifica el propio nombre del fichero. La primera versi´on de un fichero llamado hola mundo.py es hola mundo 1.py, la segunda hola mundo 2.py, y as´ı sucesivamente.
hola mundo 1.py hola mundo.py 1 print ’! Hola,’, ’mundo!’ Si, aunque haya varias versiones, no aparece un n´umero al final del nombre del fichero descar- gable, se entiende que esa es la versi´on definitiva. hola mundo.py hola mundo.py 1 print ’! Hola, mundo!’
Al pinchar en el icono, se abre un fichero de texto con el navegador web o editor de textos que se indique en las preferencias del visualizador de documentos PDF. Cuando el programa contiene alg´un error grave, aparecen un par de rayos flanqueando al nombre del programa:
E hola mundo.py E 1 rint ’! Hola, mundo!’
Algunos programas no est´an completos y, por ello, presentan alguna deficiencia. No obstante, hemos optado por no marcarlos como err´oneos cuando ´estos evolucionaban en el curso de la exposici´on. La informaci´on que se muestra por pantalla aparece siempre recuadrada. El resultado de ejecutar hola mundo.py se mostrar´a as´ı: !Hola, mundo!
En ocasiones mostraremos las ´ordenes que deben ejecutarse en un int´erprete de ´ordenes Unix. El prompt del int´erprete se representar´a con un s´ımbolo de d´olar:
—¿Qu´e sabes de este asunto?— pregunt´o el Rey a Alicia. —Nada— dijo Alicia. —¿Absolutamente nada?— insisti´o el Rey. —Absolutamente nada— dijo Alicia. —Esto es importante— dijo el Rey, volvi´endose hacia los jurados.
Lewis Carroll, Alicia en el pa´ıs de la maravillas.
El objetivo de este curso es ense˜narte a programar, esto es, a dise˜nar algoritmos y expresarlos como programas escritos en un lenguaje de programaci´on para poder ejecutarlos en un compu- tador. Seis t´erminos t´ecnicos en el primer p´arrafo. No est´a mal. Vayamos paso a paso: empezaremos por presentar en qu´e consiste, b´asicamente, un computador.
El diccionario de la Real Academia define computador electr´onico como ((M´aquina electr´onica, anal´ogica o digital, dotada de una memoria de gran capacidad y de m´etodos de tratamiento de la informaci´on, capaz de resolver problemas matem´aticos y l´ogicos mediante la utilizaci´on autom´atica de programas inform´aticos.))
La propia definici´on nos da indicaciones acerca de algunos elementos b´asicos del computador:
la memoria,
y alg´un dispositivo capaz de efectuar c´alculos matem´aticos y l´ogicos.
La memoria es un gran almac´en de informaci´on. En la memoria almacenamos todo tipo de datos: valores num´ericos, textos, im´agenes, etc. El dispositivo encargado de efectuar operaciones matem´aticas y l´ogicas, que recibe el nombre de Unidad Aritm´etico-L´ogica (UAL), es como una calculadora capaz de trabajar con esos datos y producir, a partir de ellos, nuevos datos (el resultado de las operaciones). Otro dispositivo se encarga de transportar la informaci´on de la memoria a la UAL, de controlar a la UAL para que efect´ue las operaciones pertinentes y de depositar los resultados en la memoria: la Unidad de Control. El conjunto que forman la Unidad de Control y la UAL se conoce por Unidad Central de Proceso (o CPU, del ingl´es ((Central Processing Unit))).
Podemos imaginar la memoria como un armario enorme con cajones numerados y la CPU como una persona que, equipada con una calculadora (la UAL), es capaz de buscar operandos en la memoria, efectuar c´alculos con ellos y dejar los resultados en la memoria.
©c 2003 Andr´es Marzal e Isabel Gracia 1 Introducci´on
· 2 ¿Cu´antos bits se necesitan para representar los n´umeros del 0 al 18, ambos inclusive?
............................................................................................. El sistema posicional es especialmente adecuado para efectuar ciertas operaciones aritm´eticas. Tomemos por caso la suma. Hay una ((tabla de sumar)) en binario que te mostramos a conti- nuaci´on:
sumandos suma acarreo 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1
El acarreo no nulo indica que un d´ıgito no es suficiente para expresar la suma de dos bits y que debe a˜nadirse el valor uno al bit que ocupa una posici´on m´as a la izquierda. Para ilustrar la sencillez de la adici´on en el sistema posicional, hagamos una suma de dos n´umeros de 8 bits usando esta tabla. En este ejemplo sumamos los valores 11 y 3 en su representaci´on binaria:
00001011
Empezamos por los bits menos significativos. Seg´un la tabla, la suma 1 y 1 da 0 con acarreo 1 :
Acarreo 1 00001011
El segundo d´ıgito empezando por derecha toma el valor que resulta de sumar a 1 y 1 el acarreo que arrastramos. O sea, 1 y 1 es 0 con acarreo 1 , pero al sumar el acarreo que arrastramos de la anterior suma de bits, el resultado final es 1 con acarreo 1 :
Acarreo 1 1 00001011
Ya te habr´as hecho una idea de la sencillez del m´etodo. De hecho, ya lo conoces bien, pues el sistema de numeraci´on que aprendiste en la escuela es tambi´en posicional, s´olo que usando diez d´ıgitos diferentes en lugar de dos, as´ı que el procedimiento de suma es esencialmente id´entico. He aqu´ı el resultado final, que es la secuencia de bits 00001110 , o sea, el valor 14:
Acarreo 1 1 00001011
La circuiter´ıa electr´onica necesaria para implementar un sumador que act´ue como el descrito es extremadamente sencilla.
......................................... ejercicios......................................... · 3 Calcula las siguientes sumas de n´umeros codificados con 8 bits en el sistema posicional:
a) 01111111 + 00000001 b) 01010101 + 10101010 c) 00000011 + 00000001
............................................................................................. Debes tener en cuenta que la suma de dos n´umeros de 8 bits puede proporcionar una cantidad que requiere 9 bits. Suma, por ejemplo, las cantidades 255 (en binario de 8 bits es 11111111 ) y 1 (que en binario es 00000001 ):
Acarreo 1 1 1 1 1 1 1 11111111
1.2 Codificaci´on de la informaci´on 2003/09/22-16:
El resultado es la cantidad 256, que en binario se expresa con 9 bits, no con 8. Decimos en este caso que la suma ha producido un desbordamiento. Esta anomal´ıa debe ser tenida en cuenta cuando se usa o programa un ordenador. Hasta el momento hemos visto c´omo codificar valores positivos. ¿Podemos representar tam- bi´en cantidades negativas? La respuesta es s´ı. Consideremos brevemente tres formas de hacerlo. La primera es muy intuitiva: consiste en utilizar el bit m´as significativo para codificar el signo; si vale 0 , por ejemplo, el n´umero expresado con los restantes bits es positivo (con la representa- ci´on posicional que ya conoces), y si vale 1 , es negativo. Por ejemplo, el valor de 00000010 es 2 y el de 10000010 es −2. Efectuar sumas con valores positivos y negativos resulta relativamen- te complicado si codificamos as´ı el signo de un n´umero. Esta mayor complicaci´on se traslada tambi´en a la circuiter´ıa necesaria. Mala cosa. Una forma alternativa de codificar cantidades positivas y negativas es el denominado ((comple- mento a uno)). Consiste en lo siguiente: se toma la representaci´on posicional de un n´umero (que debe poder expresarse con 7 bits) y se invierten todos sus bits si es negativo. La suma de n´umeros codificados as´ı es relativamente sencilla: se efect´ua la suma convencional y, si no se ha producido un desbordamiento, el resultado es el valor que se deseaba calcular; pero si se produce un desbordamiento, la soluci´on se obtiene sumando el valor 1 al resultado de la suma (sin tener en cuenta ya el bit desbordado). Ve´amoslo con un ejemplo. Sumemos el valor 3 al valor −2 en complemento a uno:
Acarreo 1 1 1 1 1 1 1 00000011
La primera suma ha producido un desbordamiento. El resultado correcto resulta de sumar una unidad a los 8 primeros bits. La codificaci´on en complemento a uno tiene algunas desventajas. Una de ellas es que hay dos formas de codificar el valor 0 (con 8 bits, por ejemplo, tanto 00000000 como 11111111 representan el valor 0) y, por tanto, s´olo podemos representar 255 valores ([− 127 , 127]), en lugar de 256. Pero el principal inconveniente es la lentitud con que se realizan operaciones como la suma: cuando se produce un desbordamiento se han de efectuar dos adiciones, es decir, se ha de invertir el doble de tiempo. Una codificaci´on alternativa (y que es la utilizada en los ordenadores) es la denominada ((complemento a dos)). Para cambiar el signo a un n´umero hemos de invertir todos sus bits y sumar 1 al resultado. Esta codificaci´on, que parece poco natural, tiene las ventajas de que s´olo hay una forma de representar el valor nulo (el rango de valores representados es [− 128 , 127]) y, principalmente, de que una sola operaci´on de suma basta para obtener el resultado correcto de una adici´on. Repitamos el ejemplo anterior. Sumemos 3 y −2, pero en complemento a dos:
Acarreo 1 1 1 1 1 1 00000011
Si ignoramos el bit desbordado, el resultado es correcto.
......................................... ejercicios......................................... · 4 Codifica en complemento a dos de 8 bits los siguientes valores:
a) 4 b) − 4 c) 0 d) 127 e) 1 f) − 1
· 5 Efect´ua las siguientes sumas y restas en complemento a dos de 8 bits:
a) 4 + 4 b) −4 + 3 c) 127 − 128 d) 128 − 127 e) 1 − 1 f) 1 − 2
.............................................................................................
1.3 Programas y lenguajes de programaci´on 2003/09/22-16:
El c´odigo de m´aquina codifica las secuencias de instrucciones como sucesiones de unos y ce- ros que siguen ciertas reglas. Cada familia de ordenadores dispone de su propio repertorio de instrucciones, es decir, de su propio c´odigo de m´aquina. Un programa que, por ejemplo, calcula la media de tres n´umeros almacenados en las posi- ciones de memoria 10, 11 y 12, respectivamente, y deja el resultado en la posici´on de memoria 13, podr´ıa tener el siguiente aspecto expresado de forma comprensible para nosotros:
Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´on 13 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´on 13 3 Dividir contenido de direcci´on 13 por 3 y dejar resultado en direcci´on 13 4 Detener
En realidad, el contenido de cada direcci´on estar´ıa codificado como una serie de unos y ceros, as´ı que el aspecto real de un programa como el descrito arriba podr´ıa ser ´este:
Unidad de Control Unidad Aritm´etico-L´ogica
Unidad Central de Proceso (CPU)
Memoria 1 2 3 4 .. .
La CPU es un ingenioso sistema de circuitos electr´onicos capaz de interpretar el significado de cada una de esas secuencias de bits y llevar a cabo las acciones que codifican. Cuando la CPU ejecuta el programa empieza por la instrucci´on contenida en la primera de sus posiciones de memoria. Una vez ha ejecutado una instrucci´on, pasa a la siguiente, y sigue as´ı hasta encontrar una instrucci´on que detenga la ejecuci´on del programa. Supongamos que en las direcciones de memoria 10, 11 y 12 se han almacenado los valores 5, 10 y 6, respectivamente. Representamos as´ı la memoria:
Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´on 13 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´on 13 3 Dividir contenido de direcci´on 13 por 3 y dejar resultado en direcci´on 13 4 Detener .. .
.. . 10 5 11 10 12 6 .. .
.. .
Naturalmente, los valores de las posiciones 10, 11 y 12 estar´an codificados en binario, aunque hemos optado por representarlos en base 10 en aras de una mayor claridad. La ejecuci´on del programa procede del siguiente modo. En primer lugar, se ejecuta la ins- trucci´on de la direcci´on 1, que dice que tomemos el contenido de la direcci´on 10 (el valor 5), lo sumemos al de la direcci´on 11 (el valor 10) y dejemos el resultado (el valor 15) en la direcci´on de memoria 13. Tras ejecutar esta primera instrucci´on, la memoria queda as´ı:
Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´on 13 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´on 13 3 Dividir contenido de direcci´on 13 por 3 y dejar resultado en direcci´on 13 4 Detener .. .
.. . 10 5 11 10 12 6 13 15 .. .
.. .
©c 2003 Andr´es Marzal e Isabel Gracia 1 Introducci´on
A continuaci´on, se ejecuta la instrucci´on de la direcci´on 2, que ordena que se tome el contenido de la direcci´on 13 (el valor 15), se sume al contenido de la direcci´on 12 (el valor 6) y se deposite el resultado (el valor 21) en la direcci´on 13. La memoria pasa a quedar en este estado.
Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´on 13 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´on 13 3 Dividir contenido de direcci´on 13 por 3 y dejar resultado en direcci´on 13 4 Detener .. .
.. . 10 5 11 10 12 6 13 21 .. .
.. .
Ahora, la tercera instrucci´on dice que hemos de tomar el valor de la direcci´on 13 (el valor 21), dividirlo por 3 y depositar el resultado (el valor 7) en la direcci´on 13. Este es el estado en que queda la memoria tras ejecutar la tercera instrucci´on:
Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´on 13 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´on 13 3 Dividir contenido de direcci´on 13 por 3 y dejar resultado en direcci´on 13 4 Detener .. .
.. . 10 5 11 10 12 6 13 7 .. .
.. .
Y finalmente, la CPU detiene la ejecuci´on del programa, pues se encuentra con la instrucci´on Detener en la direcci´on 4.
......................................... ejercicios......................................... · 6 Ejecuta paso a paso el mismo programa con los valores 2, −2 y 0 en las posiciones de memoria 10, 11 y 12, respectivamente.
· 7 Dise˜na un programa que calcule la media de cinco n´umeros depositados en las posiciones de memoria que van de la 10 a la 14 y que deje el resultado en la direcci´on de memoria 15. Recuerda que la media ¯x de cinco n´umeros x 1 , x 2 , x 3 , x 4 y x 5 es
¯x =
i=1 xi 5
x 1 + x 2 + x 3 + x 4 + x 5 5
· 8 Dise˜na un programa que calcule la varianza de cinco n´umeros depositados en las posiciones de memoria que van de la 10 a la 14 y que deje el resultado en la direcci´on de memoria 15. La varianza, que se denota con σ^2 , es
σ^2 =
i=1(xi^ −^ ¯x)
2 5
donde ¯x es la media de los cinco valores. Sup´on que existe una instrucci´on ((Multiplicar el contenido de direcci´on a por el contenido de direcci´on b y dejar el resultado en direcci´on c)).
............................................................................................. ¿Qu´e instrucciones podemos usar para confeccionar programas? Ya hemos dicho que el orde- nador s´olo sabe ejecutar instrucciones muy sencillas. En nuestro ejemplo, s´olo hemos utilizado tres instrucciones distintas:
una instrucci´on de suma de la forma ((Sumar contenido de direcciones p y q y dejar resultado en direcci´on r));
una instrucci´on de divisi´on de la forma ((Dividir contenido de direcci´on p por q y dejar resultado en direcci´on r));
©c 2003 Andr´es Marzal e Isabel Gracia 1 Introducci´on
¡Hola, mundo! Nos gustar´ıa mostrarte el aspecto de los programas escritos en lenguajes ensambladores rea- les con un par de ejemplos. Es una tradici´on ilustrar los diferentes lenguajes de programaci´on con un programa sencillo que se limita a mostrar por pantalla el mensaje ((Hello, World!)) (((¡Hola, mundo!))), as´ı que la seguiremos. He aqu´ı ese programa escrito en los lenguajes ensambladores de dos CPU distintas: a mano izquierda, el de los procesadores 80x86 de Intel (cuyo ´ultimo representante por el momento es el Pentium 4) y a mano derecha, el de los procesadores de la familia Motorola 68000 (que es el procesador de los primeros ordenadores Apple Macintosh).
.data msg: .string "Hello, World!\n" len: .long. - msg .text .globl _start _start: push $len push $msg push $ movl $0x4, %eax call _syscall addl $12, %esp push $ movl $0x1, %eax call _syscall _syscall: int $0x ret
start: move.l #msg,-(a7) move.w #9,-(a7) trap # addq.l #6,a move.w #1,-(a7) trap # addq.l #2,a clr -(a7) trap # msg: dc.b "Hello, World!",10,13,
Como puedes ver, ambos programas presentan un aspecto muy diferente. Por otra parte, los dos son bastante largos (entre 10 y 20 l´ıneas) y de dif´ıcil comprensi´on.
escribir los programas una sola vez y ejecutarlos en diferentes ordenadores tras efectuar las co- rrespondientes traducciones a cada c´odigo de m´aquina con diferentes programas ensambladores. Si bien la idea es en principio interesante, presenta serios inconvenientes:
Un lenguaje ensamblador universal no puede tener en cuenta c´omo se dise˜nar´an ordena- dores en un futuro y qu´e tipo de instrucciones soportar´an, as´ı que posiblemente quede obsoleto en poco tiempo.
Programar en lenguaje ensamblador (incluso en ese supuesto lenguaje ensamblador uni- versal) es complicad´ısimo por los numerosos detalles que deben tenerse en cuenta.
Adem´as, puestos a dise˜nar un lenguaje de programaci´on general, ¿por qu´e no utilizar un len- guaje natural, es decir un lenguaje como el castellano o el ingl´es? Programar un computador consistir´ıa, simplemente, en escribir (¡o pronunciar frente a un micr´ofono!) un texto en el que indic´asemos qu´e deseamos que haga el ordenador usando el mismo lenguaje con que nos comu- nicamos con otras personas. Un programa inform´atico podr´ıa encargarse de traducir nuestras frases al c´odigo de m´aquina, del mismo modo que un programa ensamblador traduce lenguaje ensamblador a c´odigo de m´aquina. Es una idea atractiva, pero que queda lejos de lo que sabemos hacer por varias razones:
La complejidad intr´ınseca de las construcciones de los lenguajes naturales dificulta enor- memente el an´alisis sint´actico de las frases, es decir, comprender su estructura y c´omo se relacionan entre s´ı los diferentes elementos que las constituyen.
El an´alisis sem´antico, es decir, la comprensi´on del significado de las frases, es a´un m´as com- plicado. Las ambig¨uedades e imprecisiones del lenguaje natural hacen que sus frases pre- senten, f´acilmente, diversos significados, aun cuando las podamos analizar sint´acticamente. (¿Cu´antos significados tiene la frase ((Trabaja en un banco.))?) Sin una buena comprensi´on del significado no es posible efectuar una traducci´on aceptable.
1.3 Programas y lenguajes de programaci´on 2003/09/22-16:
Hay una soluci´on intermedia: podemos dise˜nar lenguajes de programaci´on que, sin ser tan poten- tes y expresivos como los lenguajes naturales, eliminen buena parte de la complejidad propia de los lenguajes ensambladores y est´en bien adaptados al tipo de problemas que podemos resolver con los computadores: los denominados lenguajes de programaci´on de alto nivel. El calificati- vo ((de alto nivel)) se˜nala su independencia de un ordenador concreto. Por contraposici´on, los c´odigos de m´aquina y los lenguajes ensambladores se denominan lenguajes de programaci´on de bajo nivel. He aqu´ı el programa que calcula la media de tres n´umeros en un lenguaje de alto nivel t´ıpico (Python):
a = 5 b = 10 c = 6 media = (a + b + c) / 3
Las tres primeras l´ıneas definen los tres valores y la cuarta calcula la media. Como puedes ver, resulta mucho m´as legible que un programa en c´odigo de m´aquina o en un lenguaje ensamblador. Para cada lenguaje de alto nivel y para cada CPU se puede escribir un programa que se encargue de traducir las instrucciones del lenguaje de alto nivel a instrucciones de c´odigo de m´aquina, con lo que se consigue la deseada independencia de los programas con respecto a los diferentes sistemas computadores. S´olo habr´a que escribir una versi´on del programa en un lenguaje de programaci´on de alto nivel y la traducci´on de ese programa al c´odigo de m´aquina de cada CPU se realizar´a autom´aticamente.
Hemos dicho que los lenguajes de alto nivel se traducen autom´aticamente a c´odigo de m´aquina, s´ı, pero has de saber que hay dos tipos diferentes de traductores dependiendo de su modo de funcionamiento: compiladores e int´erpretes. Un compilador lee completamente un programa en un lenguaje de alto nivel y lo traduce en su integridad a un programa de c´odigo de m´aquina equivalente. El programa de c´odigo de m´aquina resultante se puede ejecutar cuantas veces se desee, sin necesidad de volver a traducir el programa original. Un int´erprete act´ua de un modo distinto: lee un programa escrito en un lenguaje de alto nivel instrucci´on a instrucci´on y, para cada una de ellas, efect´ua una traducci´on a las instrucciones de c´odigo de m´aquina equivalentes y las ejecuta inmediatamente. No hay un proceso de traducci´on separado por completo del de ejecuci´on. Cada vez que ejecutamos el programa con un int´erprete, se repite el proceso de traducci´on y ejecuci´on, ya que ambos son simult´aneos.
Compiladores e int´erpretes... de idiomas Puede resultarte de ayuda establecer una analog´ıa entre compiladores e int´erpretes de len- guajes de programaci´on y traductores e int´erpretes de idiomas. Un compilador act´ua como un traductor que recibe un libro escrito en un idioma deter- minado (lenguaje de alto nivel) y escribe un nuevo libro que, con la mayor fidelidad posible, contiene una traducci´on del texto original a otro idioma (c´odigo de m´aquina). El proceso de traducci´on (compilaci´on) tiene lugar una sola vez y podemos leer el libro (ejecutar el programa) en el idioma destino (c´odigo de m´aquina) cuantas veces queramos. Un int´erprete de programas act´ua como su hom´onimo en el caso de los idiomas. Sup´on que se imparte una conferencia en ingl´es en diferentes ciudades y un int´erprete ofrece su traducci´on simult´anea al castellano. Cada vez que la conferencia es pronunciada, el int´erprete debe realizar nuevamente la traducci´on. Es m´as, la traducci´on se produce sobre la marcha, frase a frase, y no de un tir´on al final de la conferencia. Del mismo modo act´ua un int´erprete de un lenguaje de programaci´on: traduce cada vez que ejecutamos el programa y adem´as lo hace instrucci´on a instrucci´on.
Por regla general, los int´erpretes ejecutar´an los programas m´as lentamente, pues al tiempo de ejecuci´on del c´odigo de m´aquina se suma el que consume la traducci´on simult´anea. Adem´as, un compilador puede examinar el programa de alto nivel abarcando m´as de una instrucci´on