Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Computador
EE-150
9.4
Lenguajes de maquina
En los primeros días de las computadoras, los únicos
lenguajes de programación disponibles eran los lenguajes de
máquina. Cada computadora tenía su propio lenguaje de
máquina, que estaba hecho de flujos de 0 y 1. En el Capítulo
5 mostramos que en una computadora hipotética primitiva,
necesitamos usar once líneas de código para leer dos enteros,
sumarlos e imprimir el resultado. Estas líneas de código,
cuando se escriben en lenguaje de máquina, forman once
líneas de código binario, cada una de 16 bits, como se
muestra en la Tabla 9.1.
i
El único lenguaje entendido por una computadora es
el lenguaje de máquina.
9.5
9.6
Lenguajes ensambladores
La siguiente evolución en la programación vino con la idea
de reemplazar el código binario para instrucciones y
direcciones con símbolos o mnemónicos. Debido a que
usaban símbolos, estos lenguajes se conocían primero como
lenguajes simbólicos. El conjunto de estos lenguajes
mnemónicos fue referido más tarde como lenguajes
ensambladores. El lenguaje ensamblador de nuestra
computadora hipotética para reemplazar el lenguaje de
máquina en la Tabla 9.2 se muestra en el Programa 9.1.
i
El único lenguaje entendido por una computadora es
el lenguaje de máquina.
9.7
9.8
Lenguajes de alto nivel
Aunque los lenguajes de ensamblaje mejoraron en gran
medida la eficiencia de la programación, aún requerían que
los programadores se concentraran en el hardware que
estaban usando. Trabajar con lenguajes simbólicos también
fue muy tedioso, porque cada instrucción de máquina tenía
que ser codificada individualmente. El deseo de mejorar la
eficiencia del programador y cambiar el enfoque de la
computadora al problema que se está resolviendo llevó al
desarrollo de lenguajes de alto nivel.
A lo largo de los años, se desarrollaron varios
lenguajes, sobre todo BASIC, COBOL, Pascal, Ada, C, C++
y Java. El programa 9.1 muestra el código para agregar dos
enteros como aparecería en el lenguaje C ++.
9.9
9.10
9-2 TRADUCCIÓN
9.11
Compilación
Un compilador normalmente traduce todo el programa
fuente en un programa objeto.
Interpretación
Algunos lenguajes de computadora utilizan un intérprete
para traducir el programa fuente al programa objeto. La
interpretación se refiere al proceso de traducir cada línea del
programa fuente a la línea correspondiente del programa
objeto y ejecutar la línea. Sin embargo, debemos ser
conscientes de dos tendencias en la interpretación: la que
usan algunos lenguajes antes de Java y la interpretación que
usa Java.
9.12
Proceso de traducción
La compilación y la interpretación difieren en que la primera
traduce todo el código fuente antes de ejecutarlo, mientras
que la segunda traduce y ejecuta el código fuente una línea a
la vez. Sin embargo, ambos métodos siguen el mismo
proceso de traducción que se muestra en la Figura 9.1.
9.13
9-3 PARADIGMAS DE PROGRAMACIÓN
9.14
Figura 9.2 Categorías de los lenguajes de programación
9.15
El paradigma procedimental
En el paradigma de procedimiento (o paradigma imperativo)
podemos pensar en un programa como un agente activo que
manipula objetos pasivos. Encontramos muchos objetos
pasivos en nuestra vida diaria: una piedra, un libro, una
lámpara, etc. Un objeto pasivo no puede iniciar una acción por
sí mismo, pero puede recibir acciones de agentes activos.
Un programa en un paradigma de procedimiento es un
agente activo que utiliza objetos pasivos a los que nos
referimos como datos o elementos de datos. Para manipular
una parte de los datos, el agente activo (programa) emite una
acción, conocida como un procedimiento. Por ejemplo, piense
en un programa que imprime el contenido de un archivo. El
archivo es un objeto pasivo. Para imprimir el archivo, el
programa utiliza un procedimiento, que llamamos imprimir.
9.16
Figura 9.3 El concepto de paradigma procedimental
9.17
Un programa en este paradigma consta de tres partes: una parte
para la creación de objetos, un conjunto de llamadas a
procedimientos y un conjunto de códigos para cada
procedimiento. Algunos procedimientos ya han sido definidos
en el propio lenguaje. Al combinar este código, el programador
puede crear nuevos procedimientos.
9.18
Figura 9.4 Los componentes de un programa procedimental
Algunos lenguajes de procedimiento
Pascal
C
Ada
9.19
El paradigma orientado a objetos.
El paradigma orientado a objetos trata con objetos activos en
lugar de objetos pasivos. Encontramos muchos objetos
activos en nuestra vida diaria: un vehículo, una puerta
automática, un lavaplatos, etc. La acción a realizar en estos
objetos se incluye en el objeto: los objetos solo necesitan
recibir el estímulo apropiado desde el exterior para realizar
una de las acciones.
Un archivo en un paradigma orientado a objetos se
puede empaquetar con todos los procedimientos, llamados
métodos en el paradigma orientado a objetos, que debe
realizar el archivo: imprimir, copiar, eliminar, etc. El
programa en este paradigma simplemente envía la solicitud
correspondiente al objeto.
9.20
Figura 9.5 El concepto de paradigma orientado a objetos.
9.21
Clases
Como muestra la Figura 9.5, los objetos del mismo tipo (los
archivos, por ejemplo) necesitan un conjunto de métodos que
muestren cómo reacciona un objeto de este tipo a los
estímulos desde fuera de los "territorios" del objeto. Para
crear estos métodos, se usa una unidad llamada clase (ver
Apéndice F).
9.23
Herencia
En el paradigma orientado a objetos, como en la naturaleza,
un objeto puede heredar de otro objeto. Este concepto se
llama herencia. Cuando se define una clase general, podemos
definir una clase más específica que hereda algunas de las
características de la clase general, pero también tiene algunas
características nuevas. Por ejemplo, cuando se define un
objeto del tipo FormasGeometricas, podemos definir una
clase llamada Rectangulos. Los rectángulos son formas
geométricas con características adicionales..
9.24
Polimorfismo
Polimorfismo significa "muchas formas". El polimorfismo
en el paradigma orientado a objetos significa que podemos
definir varias operaciones con el mismo nombre que pueden
hacer cosas diferentes en clases relacionadas. Por ejemplo,
supongamos que definimos dos clases, Rectángulos y
Círculos, ambos heredados de la clase FormasGeométricas.
Definimos dos operaciones denominadas área, una en
Rectángulos y otra en Círculos, que calculan el área de un
rectángulo o un círculo. Las dos operaciones tienen el mismo
nombre.
9.25
Algunos lenguajes orientados a objetos
C++
Java
9.26
El paradigma funcional
En el paradigma funcional un programa es considerado una
función matemática. En este contexto, una función es una
caja negra que mapea una lista de entradas a una lista de
salidas.
Scheme
9.29
El paradigma declarativo
Un paradigma declarativo utiliza el principio de
razonamiento lógico para responder consultas. Se basa en la
lógica formal definida por los matemáticos griegos y más
tarde desarrollada en el Cálculo de Predicados de primer
orden.
El razonamiento lógico se basa en la deducción. Se
dan algunas afirmaciones (hechos) que se suponen
verdaderas, y la máquina de inferencia usa reglas sólidas de
razonamiento lógico para deducir nuevas afirmaciones
(hechos). Por ejemplo, la famosa regla de deducción en
lógica es:
9.30
Usando esta regla y los dos hechos siguientes,
9.31
Prolog
Uno de los lenguajes declarativos famosos es Prolog
(PROgramming in LOGic), desarrollado por A. Colmerauer
en Francia en 1972. Un programa en Prolog se compone de
hechos y reglas. Por ejemplo, los hechos anteriores sobre los
seres humanos se pueden afirmar como:
9.33
Identificadores
Una característica presente en todos los idiomas de
procedimiento, así como en otros idiomas, es el
identificador—es decir, el nombre de los objetos. Los
identificadores nos permiten nombrar objetos en el
programa. Por ejemplo, cada pieza de datos en una
computadora se almacena en una dirección única. Si no
hubiera identificadores para representar simbólicamente las
ubicaciones de los datos, tendríamos que conocer y utilizar
las direcciones de datos para manipularlos. En su lugar,
simplemente damos nombres de datos y dejamos que el
compilador haga un seguimiento de dónde se encuentran
físicamente.
9.34
Tipos de datos
Un tipo de datos define un conjunto de valores y un
conjunto de operaciones que se pueden aplicar a esos
valores. El conjunto de valores para cada tipo se conoce
como el dominio para el tipo. La mayoría de los idiomas
definen dos categorías de tipos de datos: tipos simples y
tipos compuestos.
9.35
Variables
Variables son nombres para ubicaciones de memoria. Como
se discutió en el Capítulo 5, cada ubicación de memoria en
una computadora tiene una dirección. Aunque la
computadora utiliza internamente las direcciones, es muy
incómodo para el programador usar direcciones. Un
programador puede usar una variable, tal como nota, para
almacenar el valor entero de una calificación recibida en una
prueba. Desde que una variable contiene un elemento de
datos, también tiene un tipo.
9.36
Literales
Un literal es un valor predeterminado usado en un programa.
Por ejemplo, si necesitamos calcular el área del círculo cuando
el valor del radio se almacena en la variable r, podemos usar la
expresión 3.14 × r2, en la cual el valor aproximado de π (pi) se
usa como un literal. En la mayoría de los lenguajes de
programación podemos tener literales enteros, reales, de
caracteres y booleanos. En la mayoría de los idiomas, también
podemos tener literales de cadena. Para distinguir los literales
de caracteres y cadenas de los nombres de variables y otros
objetos, la mayoría de los idiomas requieren que los literales de
caracteres se incluyan entre comillas simples, como 'A', y que
las cadenas se incluyan entre comillas dobles, como "Ana".
9.37
Constantes
El uso de literales no se considera una buena práctica de
programación a menos que estemos seguros de que el valor
del literal no cambiará con el tiempo (como el valor de π en
geometría). Sin embargo, la mayoría de los literales pueden
cambiar de valor con el tiempo.
Por esta razón, la mayoría de los lenguajes de
programación definen constantes. Una constante, al igual
que una variable, es una ubicación con nombre que puede
almacenar un valor, pero el valor no se puede cambiar
después de que se haya definido al comienzo del programa.
Sin embargo, si queremos usar el programa más adelante,
podemos cambiar solo una línea al comienzo del programa,
el valor de la constante
9.38
Entradas y salidas
Casi todos los programas necesitan leer y/o escribir datos.
Estas operaciones pueden ser bastante complejas,
especialmente cuando leemos y escribimos archivos grandes.
La mayoría de los lenguajes de programación utilizan una
función predefinida para entrada y salida.
9.39
Expresiones
Una expresión es una secuencia de operandos y operadores
que se reduce a un solo valor. Por ejemplo, la siguiente es
una expresión con un valor de 13:
9.40
La Tabla 9.3 muestra algunos operadores aritméticos
utilizados en C, C ++ y Java.
9.41
Los operadores relacionales comparan datos para ver si un
valor es mayor, menor o igual que otro valor. El resultado de
aplicar operadores relacionales es un valor booleano
(verdadero o falso). C, C++ y Java utilizan seis operadores
relacionales, como se muestra en la Tabla 9.4:
9.42
Los operadores lógicos combinan valores booleanos
(verdadero o falso) para obtener un nuevo valor. El lenguaje
C utiliza tres operadores lógicos, como se muestra en la
Tabla 9.5:
9.43
Sentencias
Una sentencia hace que una acción sea realizada por el
programa. Se traduce directamente en una o más
instrucciones de computadora ejecutables. Por ejemplo, C,
C++ y Java definen muchos tipos de sentencias.
9.49
Ejemplo 9.1
Suponga que un subprograma es responsable de llevar a cabo la
tarea de impresión del programa principal. Cada vez que el
programa principal desea imprimir un valor, lo envía al
subprograma a imprimir. El programa principal tiene su propia
variable X, el subprograma tiene su propia variable A. Lo que se
envía desde el programa principal al subprograma es el valor de
la variable X.
Ejemplo 9.3
Una analogía de pasar por valor en la vida real es cuando un
amigo quiere pedir prestado y leer un libro valioso que usted
escribió. Dado que el libro es precioso, posiblemente agotado,
usted hace una copia del libro y se lo pasa a su amigo. Cualquier
daño a la copia por lo tanto no afecta al original.
9.51
Ejemplo 9.4
Supongamos que el programa principal tiene dos variables X e Y
que necesitan intercambiar sus valores. El programa principal
pasa el valor de X e Y al subprograma, que se almacena en dos
variables A y B. El subprograma de intercambio utiliza una
variable local T (temporal) e intercambia los dos valores en A y
B, pero los valores originales en X e Y siguen siendo los mismos:
no se intercambian.
9.53
Ejemplo 9.5
Si utilizamos el mismo subprograma de intercambio pero
permitimos que las variables se pasen por referencia, los dos
valores en X e Y se intercambian realmente.
9.55