PrograII Tema1
PrograII Tema1
PrograII Tema1
Programación II
(M. EN C. GEORGINA ESLAVA GARCÍA)
T EMA 1
Introducción a los lenguajes de programación
1.1. Concepto de un lenguaje de programación
El termino alfabeto denota cualquier conjunto finito de símbolos. Una cadena es una
secuencia finita de símbolos tomados de un alfabeto. Por lo tanto, un lenguaje es cualquier
conjunto de cadenas que cumple con ciertas reglas gramaticales.
Cualquier notación para describir algoritmos y estructuras de datos se puede calificar como
lenguaje de programación.
Los lenguajes de programación pueden ser de alto nivel, bajo nivel o lenguaje máquina.
1
Elaboró: M. en C. Georgina Eslava García
Los lenguajes de bajo nivel permiten hacer un uso extremadamente eficiente de la memoria y
optimizar la velocidad de ejecución del programa. Pero si el programa presenta un diseñado
incorrecto y tiene poca o nada documentación, puede convertirse en una pesadilla. El lenguaje
ensamblador es un ejemplo de lenguaje de bajo nivel.
Los lenguajes máquina se basan en una serie de unos y ceros para representar a los datos y al
conjunto de instrucciones de la CPU. El lenguaje máquina es el único que interpreta la
2
Elaboró: M. en C. Georgina Eslava García
computadora, éste utiliza el alfabeto binario que consta de los dos símbolos 0 y 1, denominados
bits; que corresponden aproximadamente a 0 y 5 voltios, respectivamente.
0011000110100001
1000100110011010
0011101010011100
0111010001110011
1110100100101100
Figura 1.3. Ejemplo de lenguaje máquina
1.2.1 Procedural
#include <stdio.h>
void saludo( ){
printf ("%s", "Hola mundo");
}
main( ){
int i;
i=2;
if (i==2) saludo ( );
}
Figura 1.3. Ejemplo de programa en lenguaje C.
3
Elaboró: M. en C. Georgina Eslava García
PROGRAM TRIVIAL
INTEGER i
i=2
IF (i .EQ. 2) CALL SALUDO( )
STOP
END
SUBROUTINE SALUDO
PRINT * , "HOLA MUNDO"
RETURN
END
Figura 1.4. Ejemplo de programa en lenguaje Fortran.
1.2.2 Lógicos
Un ejemplo de lenguaje que entra en este paradigma es Prolog, el cual no está orientado a la
programación para usos generales, sino que se orienta a resolver problemas usando el cálculo de
predicados. Veamos el siguiente código ejemplo en Prolog:
4
Elaboró: M. en C. Georgina Eslava García
---------------------------------------------------------------
Consulta en Prolog:
? le_gusta (juan, libros).
Yes
? le_gusta (juan, X).
X= libros;
X= maría;
X= pescado;
No
?_
Prolog trata de emular una plática usuario-máquina. Esta forma de programación es utilizada en
aplicaciones de inteligencia artificial, como sistemas expertos entre otros.
1.2.3 Funcionales
Como lenguajes representativos de este paradigma están Lisp, ML, Scheme, entre otros. Este tipo
de lenguajes están destinados al desarrollo en forma aplicativa.
Lisp fue creado por John McCarthy y un grupo del Massachussets Institute of Technology (MIT),
en 1960. El lenguaje se ha utilizado en la investigación en ciencias de la computación, sobre todo
en Inteligencia Artificial (robótica, procesamiento de lenguaje natural, prueba de teoremas, etc.).
En seguida se muestra un código ejemplo Lisp:
5
Elaboró: M. en C. Georgina Eslava García
En este caso las unidades de datos se consideran objetos activos. La característica principal de
los lenguajes orientados a objetos es la capacidad de representar definiciones de objetos a modo
de esqueletos que pueden usarse una y otra vez para construir múltiples objetos con las mismas
propiedades o modificarse para construir nuevos objetos con propiedades similares. Algunos
ejemplos de lenguajes de programación orientada a objetos son C++, Java, SmallTalk, Café.
Veamos el siguiente programa ejemplo en C++
#include<stdlib.h>
#include<iostream>
using namespace std;
class Cuadrado{
private:
float lado;
public:
Cuadrado(float l=50){
lado=l;
}
float area(){
return(lado*lado);
}
float perimetro(){
return(4*lado);
}
};
main(){
float la;
Cuadrado c1(120);
Cuadrado c2(13);
Cuadrado c3;
6
Elaboró: M. en C. Georgina Eslava García
Cuadrado c4(la);
import java.io.*;
import java.util.Scanner;
class CuadradoDef{
private double lado;
7
Elaboró: M. en C. Georgina Eslava García
1.2.5 Otros
• PARADIGMA RELACIONAL
Una base de datos es la colección de todos los datos operativos de una empresa o institución, de
acuerdo a un modelo específico, que son accesibles desde cualquier lugar físico y nivel de la
institución o empresa.
Un ejemplo de este tipo de lenguajes es SQL (Structure Query Language) que es el más utilizado
y, a pesar de no ser completamente funcional en el sentido de ser tan potente como un lenguaje
procedural, dota de operaciones suficientes a las aplicaciones de base de datos. Tiene muchas
deficiencias; la más seria de ellas es que nunca fue realmente diseñado de acuerdo con ambas
partes (álgebra y cálculo) y por lo tanto, está lleno de numerosas restricciones y reglas especiales.
8
Elaboró: M. en C. Georgina Eslava García
INSERT INTO AUTOR_LIBRO VALUES (10, 100), (20, 200), (30, 300), (10, 400), (20, 400);
SELECT * FROM AUTOR_LIBRO;
En este caso, tanto la estructura como la ejecución de los programas van determinados por los
sucesos que ocurran en el sistema, definidos por el usuario o que ellos mismos provoquen. En la
programación dirigida por eventos, al comenzar la ejecución del programa se llevarán a cabo las
inicializaciones y demás código inicial y a continuación el programa quedará bloqueado hasta que
se produzca algún evento. Cuando alguno de los eventos esperados por el programa tenga lugar,
el programa pasará a ejecutar el código del correspondiente administrador de evento. Por
ejemplo, si el evento consiste en que el usuario ha hecho clic en el botón de play de un
reproductor de películas, se ejecutará el código del administrador de evento, que será el que haga
que la película se muestre por pantalla.
9
Elaboró: M. en C. Georgina Eslava García
El código que debe colocarse para el evento en cada objeto de la imagen anterior es:
10
Elaboró: M. en C. Georgina Eslava García
Cabe mencionar que en la actualidad existen más de 2500 lenguajes y existen otros paradigmas,
sin embargo, para efectos de este curso serán suficientes los antes mencionados.
Los compiladores y los interpretes son traductores que convierten a los códigos escritos en
lenguajes de alto nivel en lenguaje máquina. En seguida se establecerá la definición de ambos y
las diferencias entre ellos.
En forma general, definiremos a un compilador como un programa que lee un código escrito en un
lenguaje (conocido como código fuente) y lo traduce a un programa equivalente en otro lenguaje
reconocido por la computadora (llamado lenguaje objeto). Como parte importante de este proceso
de traducción, el compilador informa al usuario de la presencia de errores en el programa fuente.
11
Elaboró: M. en C. Georgina Eslava García
El intérprete en lugar de producir un programa objeto como resultado de una traducción realiza las
operaciones que indica el programa fuente. Para una proposición de asignación, por ejemplo, un
intérprete podría construir un árbol como como el que se muestra en la figura 1.12 e
inmediatamente ejecutar las operaciones de los nodos conforme recorre el árbol. En la raíz
descubriría que tiene que realizar una asignación, y llamaría a una rutina para evaluar la
expresión de la derecha y después almacenaría el valor resultante en la localidad de memoria
asociada con el identificador posición. En el hijo derecho de la raíz, la rutina descubriría que tiene
que calcular el valor de la expresión velocidad * 60. Después sumaría ese valor al valor de la
variable inicial.
Muchas veces los intérpretes se usan para ejecutar lenguajes de órdenes, pues cada operador
que se ejecuta en un lenguaje de órdenes suele ser una invocación de una rutina compleja, como
12
Elaboró: M. en C. Georgina Eslava García
un editor o un compilador. Del mismo modo, algunos lenguajes de alto nivel, como APL,
normalmente son interpretados porque hay muchas cosas sobre los datos, como el tamaño y la
forma de las matrices que no se pueden deducir en el momento de la compilación.
1.3.2.1. Preprocesador
Los preprocesadores producen la entrada para un compilador y puede realizar las funciones
siguientes:
necesite. Cada vez que aparece la abreviatura o macro llamada, el preprocesador la reemplaza
con la definición original.
#include <stdio.h>
#include <math.h>
#define PI 3.1416
char respuesta;
double areaCirculo(double r){
double area;
area=PI*pow(r,2);
return area;
}
Figura 1.14. Ejemplo de macro en lenguaje C
1.3.2.2. Compilador
14
Elaboró: M. en C. Georgina Eslava García
15
Elaboró: M. en C. Georgina Eslava García
En general hay un conjunto de cadenas en la entrada, para lo cual, se produce como salida
el componente léxico. Este conjunto de cadenas se describe mediante una regla llamada patrón
asociado al componente léxico. Se dice que el patrón concuerda con cada cadena del conjunto.
En la práctica los componentes léxicos suelen tener un solo atributo que es un apuntador a
la entrada en la tabla de símbolos donde se guarda la información sobre el componente léxico.
1. El identificador posición
2. El símbolo de asignación =
3. El identificador inicial
4. El signo de + (suma)
5. El identificador velocidad
6. El signo de * (multiplicación)
7. El número 60
Los espacios en blanco que separan los caracteres de estos componentes léxicos
normalmente se eliminan durante el análisis léxico.
En esta fase se agrupan los componentes léxicos del programa fuente en frases gramaticales que
el compilador utiliza para sintetizar la salida. Por lo general, las frases gramaticales del programa
fuente se representan mediante un árbol de análisis sintáctico como el que se ilustra en la figura
1.16.
16
Elaboró: M. en C. Georgina Eslava García
Figura 1.6. Árbol de análisis sintáctico para posición= inicial + velocidad * 60.
En la expresión inicial + velocidad * 60, la frase velocidad * 60 es una unidad lógica, porque
las convenciones usuales de las expresiones aritméticas indican que la multiplicación se hace
antes que la suma. Puesto que la expresión inicial + velocidad va seguida de un *, no se agrupa
en una sola frase independiente en la figura anterior.
Las reglas 1 y 2 son reglas no recursivas, en tanto que la regla 3 define expresiones en función de
operadores aplicados a otras expresiones. Así, por la regla 1, inicial y velocidad son expresiones.
Por la regla 2, 60 es una expresión, mientras que por la regla 3, primero podemos inferir que
velocidad * 60 es una expresión, y finalmente que inicial + velocidad * 60 también es una
expresión.
17
Elaboró: M. en C. Georgina Eslava García
La fase del análisis semántico consiste en revisar el programa fuente para tratar de encontrar
errores semánticos y reúne la información sobre los tipos para la fase posterior de generación de
código. En ella se utiliza la estructura jerárquica determinada por la fase de análisis sintáctico para
identificar los operadores y operandos de expresiones y proposiciones.
Por ejemplo, la instrucción id1 = id2 + id3 * 60 en código de tres direcciones queda de la siguiente
forma
Esta fase trata de mejorar el código intermedio, de modo que resulte un código de máquina
más rápido de ejecutar. En el ejemplo anterior, el compilador puede deducir que la conversión de
60 de entero a real se puede hacer en la misma línea, temp1= velocidad * 60.0, además temporal
3 se usa sólo una vez para transmitir su valor id1. Entonces resulta seguro sustituir id1 por temp3,
a partir de lo cual la última proposición no se necesita y se obtiene el código siguiente
18
Elaboró: M. en C. Georgina Eslava García
La fase final de un compilador es la generación de código objeto, que por lo general consiste
en código de máquina relocalizable o código ensamblador. Las posiciones de memoria se
seleccionan para cada una de las variables usadas por el programa. Después cada una de las
instrucciones intermedias se traducen a una secuencia de instrucciones máquina que ejecuta la
misma tarea. Un aspecto decisivo es la asignación de variables a registros.
MOVF AX , 60.0
MOVF BX, id3
MULF BX, AX
MOVF DX, id2
ADDF DX, BX
MOVF id1, DX
Una tabla de símbolos es una estructura de datos que contiene un registro por cada
identificador, con los campos para los atributos del identificador.
Cada fase puede encontrar errores. Sin embargo, después de detectar un error cada fase
debe tratar de alguna forma ese error, para poder continuar la compilación permitiendo la
detección de más errores en el programa fuente. Un compilador que se detiene cuando encuentra
el primer error no resulta tan útil como debiera.
1.3.2.3 Ensamblador
19
Elaboró: M. en C. Georgina Eslava García
Por lo general, un programa llamado cargador realiza las 2 funciones de carga y edición de
enlace. El proceso de carga consiste en tomar el código de máquina relocalizable, modificando las
direcciones relocalizables, y ubicar las instrucciones y datos modificados en las posiciones
apropiadas de la memoria.
El editor de enlace permite formar un solo programa a partir de varios archivos de código de
máquina relocalizable. Estos archivos pueden haber sido el resultado de varias compilaciones
distintas, y uno o varios de ellos pueden ser archivos de biblioteca de rutina proporcionadas por el
sistema y disponibles para cualquier programa que los necesite.
20