Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


LIBRO DE PYTHON, Apuntes de Ingeniería Química

Asignatura: INTRODUCCION A LA COMPUTACION, Profesor: ARANTZA CASILLAS, Carrera: Ingeniero Químico, Universidad: UPV-EHU

Tipo: Apuntes

2010/2011
En oferta
30 Puntos
Discount

Oferta a tiempo limitado


Subido el 06/09/2011

miki69-1
miki69-1 🇪🇸

4.1

(83)

22 documentos

1 / 399

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Introducci´on a la programaci´on
con Python
Andr´es Marzal Isabel Gracia
Departamento de Lenguajes y Sistemas Inform´aticos
Universitat Jaume I
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 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.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51
pf52
pf53
pf54
pf55
pf56
pf57
pf58
pf59
pf5a
pf5b
pf5c
pf5d
pf5e
pf5f
pf60
pf61
pf62
pf63
pf64
Discount

En oferta

Vista previa parcial del texto

¡Descarga LIBRO DE PYTHON y más Apuntes en PDF de Ingeniería Química solo en Docsity!

Introducci´on a la programaci´on

con Python

Andr´es Marzal Isabel Gracia

Departamento de Lenguajes y Sistemas Inform´aticos

Universitat Jaume I

© 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.

Prefacio

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

´INDICE GENERAL 2003/09/22-16:

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.

Convenios tipogr´aficos

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:

    1. Introducci´on Indice general
    • 1.1. Computadores
    • 1.2. Codificaci´on de la informaci´on
    • 1.3. Programas y lenguajes de programaci´on
      • 1.3.1. C´odigo de m´aquina
      • 1.3.2. Lenguaje ensamblador
      • 1.3.3. ¿Un programa diferente para cada ordenador?
      • 1.3.4. Lenguajes de programaci´on de alto nivel
      • 1.3.5. Compiladores e int´erpretes
      • 1.3.6. Python
      • 1.3.7. C
    • 1.4. M´as all´a de los programas: algoritmos
    1. Una calculadora avanzada
    • 2.1. Sesiones interactivas
      • 2.1.1. Los operadores aritm´eticos
      • 2.1.2. Errores de tecleo y excepciones
    • 2.2. Tipos de datos
      • 2.2.1. Enteros y flotantes
      • 2.2.2. Valores l´ogicos
    • 2.3. Operadores l´ogicos y de comparaci´on
    • 2.4. Variables y asignaciones
      • 2.4.1. Asignaciones con operador
      • 2.4.2. Variables no inicializadas
    • 2.5. El tipo de datos cadena
    • 2.6. Funciones predefinidas
    • 2.7. Funciones definidas en m´odulos
      • 2.7.1. El m´odulo math
      • 2.7.2. Otros m´odulos de inter´es
    • 2.8. M´etodos
    1. Programas
    • 3.1. El entorno PythonG
    • 3.2. Ejecuci´on de programas desde la l´ınea de ´ordenes Unix
    • 3.3. Entrada/salida
      • 3.3.1. Lectura de datos de teclado
      • 3.3.2. M´as sobre la sentencia print
      • 3.3.3. Salida con formato
    • 3.4. Legibilidad de los programas
      • 3.4.1. Algunas claves para aumentar la legibilidad
      • 3.4.2. Comentarios
    • 3.5. Gr´aficos
  • ´INDICE GENERAL 2003/09/22-16:
      1. Estructuras de control
      • 4.1. Sentencias condicionales
        • 4.1.1. Un programa de ejemplo: resoluci´on de ecuaciones de primer grado
        • 4.1.2. La sentencia condicional if
        • 4.1.3. Trazas con PythonG: el depurador
        • 4.1.4. Sentencias condicionales anidadas
        • 4.1.5. Otro ejemplo: resoluci´on de ecuaciones de segundo grado
        • 4.1.6. En caso contrario (else)
        • 4.1.7. Una estrategia de dise˜no: refinamientos sucesivos
        • 4.1.8. Un nuevo refinamiento del programa de ejemplo
        • 4.1.9. Otro ejemplo: m´aximo de una serie de n´umeros
        • 4.1.10. Evaluaci´on con cortocircuitos
        • 4.1.11. Un ´ultimo problema: men´us de usuario
        • 4.1.12. Una forma compacta para estructuras condicionales m´ultiples (elif )
      • 4.2. Sentencias iterativas
        • 4.2.1. La sentencia while
        • 4.2.2. Un problema de ejemplo: c´alculo de sumatorios
        • 4.2.3. Otro programa de ejemplo: requisitos en la entrada
        • 4.2.4. Mejorando el programa de los men´us
        • 4.2.5. El bucle for-in
        • 4.2.6. for-in como forma compacta de ciertos while
        • 4.2.7. N´umeros primos
        • 4.2.8. Rotura de bucles: break
        • 4.2.9. Anidamiento de estructuras
      • 4.3. Captura y tratamiento de excepciones
      • 4.4. Algunos ejemplos gr´aficos
        • 4.4.1. Un graficador de funciones
        • 4.4.2. Una animaci´on: simulaci´on gravitacional
        • 4.4.3. Un programa interactivo: un videojuego
      • 4.5. Una reflexi´on final
      1. Tipos estructurados: secuencias
      • 5.1. Cadenas
        • 5.1.1. Lo que ya sabemos
        • 5.1.2. Escapes
        • 5.1.3. Longitud de una cadena
        • 5.1.4. Indexaci´on
        • 5.1.5. Recorrido de cadenas
        • 5.1.6. Un ejemplo: un contador de palabras
        • 5.1.7. Otro ejemplo: un programa de conversi´on de binario a decimal
        • 5.1.8. A vueltas con las cadenas: inversi´on de una cadena
        • 5.1.9. Subcadenas: el operador de corte
        • 5.1.10. Una aplicaci´on: correo electr´onico personalizado
        • 5.1.11. Referencias a cadenas
      • 5.2. Listas
        • 5.2.1. Cosas que, sin darnos cuenta, ya sabemos sobre las listas
        • 5.2.2. Comparaci´on de listas
        • 5.2.3. El operador is
        • 5.2.4. Modificaci´on de elementos de listas
        • 5.2.5. Mutabilidad, inmutabilidad y representaci´on de la informaci´on en memoria
        • 5.2.6. Adici´on de elementos a una lista
        • 5.2.7. Lectura de listas por teclado
        • 5.2.8. Borrado de elementos de una lista
        • 5.2.9. Pertenencia de un elemento a una lista
        • 5.2.10. Ordenaci´on de una lista
      • 5.3. De cadenas a listas y viceversa
      • 5.4. Matrices
        • 5.4.1. Sobre la creaci´on de matrices
        • 5.4.2. Lectura de matrices
      • 5.4.3. ¿Qu´e dimensi´on tiene una matriz? ©c 2003 Andr´es Marzal e Isabel Gracia 0 ´INDICE GENERAL
      • 5.4.4. Operaciones con matrices
      • 5.4.5. El juego de la vida
    • 5.5. Una reflexi´on final
    1. Funciones
    • 6.1. Uso de funciones
    • 6.2. Definici´on de funciones
      • 6.2.1. Definici´on y uso de funciones con un solo par´ametro
      • 6.2.2. Definici´on y uso de funciones con varios par´ametros
      • 6.2.3. Definici´on y uso de funciones sin par´ametros
      • 6.2.4. Procedimientos: funciones sin devoluci´on de valor
      • 6.2.5. Funciones que devuelven varios valores mediante una lista
    • 6.3. Un ejemplo: Memori´on
    • 6.4. Variables locales y variables globales
    • 6.5. El mecanismo de las llamadas a funci´on
      • 6.5.1. La pila de llamadas a funci´on y el paso de par´ametros
      • 6.5.2. Paso del resultado de expresiones como argumentos
      • 6.5.3. M´as sobre el paso de par´ametros
      • 6.5.4. Acceso a variables globales desde funciones
    • 6.6. Ejemplos
      • 6.6.1. Integraci´on num´erica
      • 6.6.2. Aproximaci´on de la exponencial de un n´umero real
      • 6.6.3. C´alculo de n´umeros combinatorios
      • 6.6.4. El m´etodo de la bisecci´on
    • 6.7. Dise˜no de programas con funciones
      • 6.7.1. Ahorro de tecleo
      • 6.7.2. Mejora de la legibilidad
        • descendente y ascendente 6.7.3. Algunos consejos para decidir qu´e deber´ıa definirse como funci´on: an´alisis
    • 6.8. Recursi´on
      • 6.8.1. C´alculo recursivo del factorial
      • 6.8.2. C´alculo recursivo del n´umero de bits necesarios para representar un n´umero
      • 6.8.3. Los n´umeros de Fibonacci
      • 6.8.4. El algoritmo de Euclides
      • 6.8.5. Las torres de Hanoi
      • 6.8.6. Recursi´on indirecta
      • 6.8.7. Gr´aficos fractales: copos de nieve de von Koch
    • 6.9. M´odulos
      • 6.9.1. Un m´odulo muy sencillo: m´ınimo y m´aximo
      • 6.9.2. Un m´odulo m´as interesante: gravedad
      • 6.9.3. Otro m´odulo: c´alculo vectorial
      • 6.9.4. Un m´odulo para trabajar con polinomios
      • 6.9.5. Un m´odulo con utilidades estad´ısticas
      • 6.9.6. Un m´odulo para c´alculo matricial
    1. Tipos estructurados: registros
    • 7.1. Asociando datos relacionados
      • 7.1.1. Lo que sabemos hacer
      • 7.1.2. pero sabemos hacerlo mejor
    • 7.2. Registros
      • 7.2.1. Definici´on de nuevos tipos de dato
      • 7.2.2. Referencias a registros
      • 7.2.3. Copia de registros
    • 7.3. Algunos ejemplos
      • 7.3.1. Gesti´on de calificaciones de estudiantes
      • 7.3.2. Fechas
      • 7.3.3. Anidamiento de registros
      • 7.3.4. Gesti´on de un videoclub
  • ´INDICE GENERAL 2003/09/22-16: - videoclub 7.3.5. Algunas reflexiones sobre c´omo desarrollamos la aplicaci´on de gesti´on del
      1. Ficheros
      • 8.1. Generalidades sobre ficheros
        • 8.1.1. Sistemas de ficheros: directorios y ficheros
        • 8.1.2. Rutas
        • 8.1.3. Montaje de unidades
      • 8.2. Ficheros de texto
        • 8.2.1. El protocolo de trabajo con ficheros: abrir, leer/escribir, cerrar
        • 8.2.2. Lectura de ficheros de texto l´ınea a l´ınea
        • 8.2.3. Lectura car´acter a car´acter
        • 8.2.4. Otra forma de leer l´ınea a l´ınea
        • 8.2.5. Escritura de ficheros de texto
        • 8.2.6. A˜nadir texto a un fichero
        • 8.2.7. Cosas que no se pueden hacer con ficheros de texto
        • 8.2.8. Un par de ficheros especiales: el teclado y la pantalla
      • 8.3. Una aplicaci´on
      • 8.4. Texto con formato
    • A. Tablas ASCII e IsoLatin1 (ISO-8859-1)
    • B. Funciones predefinidas en PythonG y accesibles con modulepythong
      • B.1. Control de la ventana gr´afica
      • B.2. Creaci´on de objetos gr´aficos
      • B.3. Borrado de elementos
      • B.4. Desplazamiento de elementos
      • B.5. Interacci´on con teclado y rat´on
      • B.6. Etiquetas
    • C. El m´odulo record
  • ´INDICE GENERAL 2003/09/22-16:

Cap´ıtulo 1

Introducci´on

—¿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.

1.1. Computadores

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

  • 00000011

Empezamos por los bits menos significativos. Seg´un la tabla, la suma 1 y 1 da 0 con acarreo 1 :

Acarreo 1 00001011

  • 00000011 0

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

  • 00000011 10

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

  • 00000011 00001110

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

  • 00000001 ( 1 ) 00000000

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

  • 11111101 ( 1 ) 00000000 ↓ 00000000
  • 00000001 00000001

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

  • 11111110 ( 1 ) 00000001

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:

1.3.1. C´odigo de m´aquina

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:

1.3.4. Lenguajes de programaci´on de alto nivel

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.

1.3.5. Compiladores e int´erpretes

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