Tema 2. Variables, ámbitos y comprobación de tipos

Lenguajes de Programación E.S. Ingeniería Informática Tema 2. Variables, ámbitos y comprobación de tipos 1. Variables 1.1. Nombre 1.2. Dirección 1.3

0 downloads 27 Views 415KB Size

Recommend Stories


Variables. Tipos de variables
Variables Los individuos, grupos, instituciones, los objetos culturales como textos en sentido amplio, poseen diversas características que pueden expr

TEMA 2: VARIABLES MACROECONÓMICAS
TEMA 2: VARIABLES MACROECONÓMICAS Blanchard, Amighini and Giavazzi, Macroeconomics: A European Perspective, 1st Edition, © Pearson Education Limited

Tema 2. Tema 2: Métodos de control (I): tipos y condicionantes. CONTROL NO RACIONAL LUCHA INTEGRADA
Tema 2 2.1. Introducción. Tema 2: Métodos de control (I): tipos y condicionantes. CONTROL NO RACIONAL HERRAMIENTAS: •PLAN DE MUESTREO. •UMBRALES DE

TIPOS DE VARIABLES EN UN EXPERIMENTO
El texto siguiente está sacado de un capítulo del libro cuya referencia bibliográfica es la siguiente: Buendía, L.; Colás, P. y Hernández, F. (2001):

Story Transcript

Lenguajes de Programación

E.S. Ingeniería Informática

Tema 2. Variables, ámbitos y comprobación de tipos 1. Variables 1.1. Nombre 1.2. Dirección 1.3. Tipo 1.4. Valor

2. Ligadura(binding) 2.1. Ligadura de tipos • Ligadura estática de tipos • Ligadura dinámica de tipos 2.2. Ligadura de espacio y tiempo de vida • Variables estáticas • Variables dinámicas de pila • Variables dinámicas de montón (explícitas e implícitas)

3. Tipos 3.1. Comprobación de tipos 3.2. Disciplina de tipos 3.3. Compatibilidad de tipos

4. Ámbito 4.1. Ámbito estático 4.2. Ámbito dinámico 4.3. Entorno de referencia

5. Constantes 6. Inicialización de variables 6.1. Variables no inicializadas

Departamento de Informática

1

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

Bibliografía Básica Bal, H.E., Grune, D., Programming Languages Essentials, Addison-Wesley, 1994. Págs. 36-37. Sebesta, R.W., Concepts of Programming Languages, 4 ed, Addison-Wesley, 1999. Págs. 155194.

Complementaria Dershem, H.L., Jipping, M.J., Programming Languages: Structures and Models, 2 ed, PWS Publishing Company, 1995. Págs. 52-63, 74-80. Fischer, A.E., Grodzinsky, F.S., The Anatomy of Programming Languages, Prentice-Hall, 1993. Págs. 163-196.

Ejercicios 1º Razona sobre la veracidad de las siguientes frases que hacen referencia a los lenguajes imperativos. a) “Todas las variables disponen de un nombre o identificador.” b) “Cada identificador en un programa tiene siempre asociada una sola dirección de memoria.” c) “Es posible tener varios identificadores que hacen referencia a la misma dirección de memoria.” d) “La vinculación dinámica de tipos consiste en asociar tipos a variables a través de convenciones sintácticas (por ejemplo, en algunos lenguajes estas convenciones hacen referencia a la letra por la que comienza o el símbolo en el que acaba el nombre de la variable)”. e) “Las variables de tipo apuntador a otros objetos son siempre variables dinámicas de montón”. f) “En todos los lenguajes imperativos, todas las variables locales declaradas en subprogramas son variables dinámicas de pila”. g) “No hay ninguna diferencia entre subtipo y tipo derivado de un tipo existente”. h) “Pascal es un lenguaje con disciplina de tipos”. i) “En Pascal, las variables creadas mediante la utilización de new se caracterizan porque el espacio que se les vincula se toma de la pila de ejecución”. j) “Si un lenguaje de programación hace una evaluación dinámica del ámbito, entonces es imposible realizar una comprobación de tipos estática de las referencias no locales”. 2º ¿Qué entendemos por ligadura estática de tipos? ¿Mediante qué distintas formas realizan los lenguajes de programación la ligadura estática de tipos? (Menciona al menos un lenguaje para cada una de las formas.) ¿Qué ventajas aporta la ligadura estática de tipos sobre la dinámica? 3º La ligadura dinámica de tipos está muy relacionada con las variables dinámicas de montón del tipo implícitas. Explica esta relación.

Departamento de Informática

2

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

4º Distingue entre: a) Ligadura estática de tipos, disciplina de tipos y ligadura dinámica de tipos. b) Coacción, error de tipos y comprobación de tipos. c) Compatibilidad de tipos nominal y compatibilidad de tipos estructural. 5º En Haskell no es necesario declarar explícitamente el tipo de los objetos que se definen y, sin embargo, es un lenguaje con disciplina de tipos. ¿Cómo explicas esto? Aunque, como decimos, no es necesario, existen algunas razones por las que puede ser adecuado escribir las declaraciones. ¿Cuáles son esas razones? 6º ¿En qué categorías se clasifican las variables atendiendo a la manera en que se produce la ligadura de espacio? Explica brevemente cómo se realiza dicha ligadura en cada uno de los tipos. 7º Cuando, en tiempo de ejecución, se entra en un bloque, las variables locales ya no contienen los valores que almacenaban la última vez que fue ejecutado dicho bloque. ¿Por qué ocurre esto? 8º Dado el siguiente esqueleto de programa escrito en C, dibuja un rectángulo alrededor de cada uno de sus bloques, etiquétalos con las letras A, B, C, etc. y responde a las siguientes preguntas. int x, y, z; fun1() { int j, k, l; { int m, n, x; … } } fun3() { int y, z, k; … } main() { … }

a) b) c) d) e) f)

Menciona un bloque que esté anidado dentro de otro bloque. ¿En qué ámbitos son accesibles a la vez las variables globales x, y, z? ¿Qué variables son accesibles desde la función main? ¿Son k de fun1 y k de fun3 la misma variable? Razona la respuesta. ¿Son las variables globales y y z accesibles desde fun3? Razona la respuesta. ¿En qué bloques j hace referencia a una variable local? ¿En qué bloques j es una variable no local? g) ¿En que bloque o bloques pueden usarse a la vez m y k?

Departamento de Informática

3

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

9º Indica qué valor de x se imprime en el procedimiento sub1 suponiendo tanto ámbito estático como ámbito dinámico. program pregunta_9; var x: integer; procedure sub1; begin writeln(‘x = ‘, x); end; procedure sub2; var x: integer; begin x := 10; sub1 end; begin {de pregunta_9} x := 5; sub2; end. {de pregunta_9}

10º ¿Qué es el ámbito de una variable de programa? Define el término bloque. En el siguiente esqueleto de programa indica cuáles son los entornos de referencia en los puntos A y B, tanto para el caso de ámbito estático como para el de ámbito dinámico. program pregunta_10; var a,b,c: integer;

begin … {B} p3 end; {de p2}

procedure p1; var b: integer; begin … {A} end; {de p1}

procedure p4; var b: integer; begin … p2 end; {de p4}

procedure p2; var b,c: integer; procedure p3; var a: integer; begin … p1 end; {de p3}

Departamento de Informática

begin … p4; end. {de pregunta_10}

4

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

Tema 2. Variables, ámbito y comprobación de tipos 1. Variables ♦ Variable: (nombre, dirección, valor, tipo, tiempo de vida, ámbito)

1.1. Nombre ♦ Nombre o identificador: cadena de caracteres empleada para reconocer alguna entidad del programa ♦ Los nombres de variables son los identificadores más numerosos en los programas, aunque no todas las variables tienen nombre ♦ Subprogramas, parámetros formales y otras entidades de programa también poseen nombre o identificador ♦ Cuestiones relativas al diseño de nombres: 1. ¿Cuál es la longitud máxima de un identificador? 2. ¿Pueden emplearse caracteres conectores? 3. ¿Se distinguen mayúsculas de minúsculas? 4. ¿Las palabras especiales son palabras reservadas o palabras clave? ♦ ¿Cuál es la longitud máxima de un identificador? •

Algunos lenguajes limitan el número de caracteres (31 en C), mientras que otros, como Ada, no lo hacen

♦ ¿Pueden emplearse caracteres conectores? •

El conector más empleado es _

Departamento de Informática

5

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ ¿Se distinguen mayúsculas de minúsculas? •





Lenguajes como C, C++, Modula-2 o Java distinguen el uso de mayúsculas y minúsculas en los identificadores Ej. de tres nombres distintos en C: suma, Suma, SUMA ⇒ problemas de legibilidad (nombres que parecen muy similares denotan entidades distintas). Solución: utilizar solamente minúsculas En Java (o Modula-2) muchos nombre predefinidos incluyen mayúsculas y minúsculas. Ej.: nombre del método para convertir una cadena de caracteres en un valor entero → parseInt (ParseInt o parseint son incorrectos) ⇒ problema para escribir los programas (hay que recordar la forma en que se escriben estos nombre predefinidos)

♦ ¿Las palabras especiales son palabras reservadas o palabras clave? •



Palabras especiales: indican acciones a realizar o se emplean para separar entidades sintácticas de los programas. Pueden ser: palabras clave o palabras reservadas Palabras clave: sólo son palabras especiales en determinados contextos Ej: Fortran REAL ALTURA INTEGER REAL REAL = 8.25







REAL INTEGER

Aunque tanto el compilador como los programadores distinguen un identificador de una palabra especial por su contexto, el uso de palabras clave puede conllevar problemas de legibilidad Palabras reservadas: palabra especial de un LP que no puede emplearse como identificador Nombres predefinidos: nombres que tienen un significado predefinido pero que puede ser cambiado (redefinido) por el usuario Ej: Ada (integer, float), Pascal (readln, writeln, trunc, round), C (printf, scanf)

Departamento de Informática

6

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

1.2. Dirección ♦ Direccion de una variable: dirección de memoria a la que está asociada ♦ Un mismo nombre puede tener asociados diferentes direcciones en lugares diferentes del programa (funciones f1 y f2 empleando la variable i) o en momentos diferentes durante la ejecución del programa (activaciones recursivas de un subprograma) ♦ La dirección de una variable se denomina l-valor → la aparición de una variable en la parte izquierda de una asignación denota su dirección

Alias ♦ Alias: cuando se usa más de un nombre de variable para referenciar la misma dirección ♦ Son un obstáculo a la legibilidad y verificación de programas. Ej: si A y B son alias ⇒ cualquier cambio en A también cambia B y viceversa ♦ Formas de crear alias: •

Registros variantes de Pascal y Ada o uniones de C y C++: −



Medio de ahorrar espacio: la misma dirección se usa para almacenar tipos diferentes en momentos diferentes Medio de evitar las reglas de tipos del lenguaje: permite manipular diferentes tipos de datos en la misma localización de memoria

Departamento de Informática

7

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •

E.S. Ingeniería Informática

En lenguajes con apuntadores, dos variables apuntador son alias cuando apuntan a la misma localización de memoria. En C y C++, si un apuntador hace referencia al espacio designado por un nombre de variable, este nombre y el apuntador son alias Ej: C int a, *pa; … pa = &a;

/* pa y a son alias */

… •

Empleando paso de parámetros por referencia a los subprogramas

1.3. Tipo ♦ Tipo de una variable: determina el rango de valores que puede tomar la variable y el conjunto de operaciones definidas para los valores del tipo Ej. integer: [-32768..32767], {+, -, *, /}

1.4. Valor ♦ Valor de una variable: contenido de la celda o celdas de memoria asociadas a las variables ♦ El valor de una variable se denomina r-valor → la aparición de una variable en la parte derecha de una asignación denota su valor (Para acceder a un r-valor primero debe determinarse su l-valor)

2. Ligadura (binding) ♦ Ligadura: asociación entre un atributo y una entidad ♦ El momento en el que se produce se denomina tiempo de ligadura. Ejemplos: •

Tiempo de compilación → la ligadura de una variable de un programa en Pascal a su tipo de datos

Departamento de Informática

8

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •





E.S. Ingeniería Informática

Tiempo de linkado → la ligadura de una llamada a un subprograma de biblioteca al código del subprograma Tiempo de carga → la ligadura de ciertas variables (ej: globales) a sus celdas de memoria (su dirección) Tiempo de ejecución → la ligadura de las variables locales (no estáticas) a sus celdas de memoria

♦ Ligadura estática: si ocurre antes del tiempo de ejecución y permanece inalterable durante la ejecución del programa ♦ Ligadura dinámica: si ocurre durante del tiempo de ejecución o puede cambiar en el transcurso de la ejecución del programa

2.1. Ligadura de tipos ♦ Antes de que una variable pueda ser referenciada en un programa debe haber sido ligada a un tipo de dato. Aspectos importantes: cuándo se liga el tipo y cómo se especifica

A. Ligadura estática de tipos ♦ Puede hacerse mediante: •



Declaración explícita: se utiliza una sentencia que declara una lista de identificadores como de un tipo determinado Declaración implícita: forma de asociar variables con tipos a través de convenciones sintácticas. La primera aparición del identificador constituye su declaración implícita − −

Ejemplos de LP: Fortran, Basic, Perl Problema: variables no declaradas explícitamente de manera accidental por el programador → toman un tipo por defecto

Departamento de Informática

9

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •

E.S. Ingeniería Informática

Algoritmo de inferencia de tipos: determina los tipos de las variables que intervienen en las expresiones sin que sean declaradas de forma explícita por el programador o da un mensaje de error si no puede inferirse Ej: Haskell f x y | x == True = y * y | otherwise = y / 2

B. Ligadura dinámica de tipos ♦ El tipo no se especifica mediante una sentencia de declaración, sino cuando se le asigna un valor mediante una sentencia de asignación ⇒ se liga al tipo del valor, variable o expresión de la parte derecha de la asignación (APL, SNOBOL4) ♦ Ventaja: proporciona muchísima flexibilidad de programación Ej: APL lista ← 3.5 8.3 0.7 10.1 (tipo: lista de reales de long. 4) lista ← 15

(tipo: variable entera)

♦ Desventajas: •

No se detectan incorrecciones de tipo en las asignaciones. El tipo de la parte izquierda simplemente se cambia al de la derecha Ej: i, x almacenan valores de tipo entero y almacena un valor de tipo real si por error escribimos i ← y en lugar de i ← x ⇒ no se detecta el error, sino que el tipo de i se cambia a real. En lenguajes con ligadura estática de tipos (Pascal, Ada) el compilador detectaría el error. Aunque en otros (C), en muchas ocasiones el tipo de la parte derecha se convierte automáticamente al de la izquierda

Departamento de Informática

10

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •

E.S. Ingeniería Informática

El coste de implementación de la ligadura dinámica de atributos es mayor, sobre todo en tiempo de ejecución: − −



Comprobación de tipos Mantenimiento del descriptor asociado a cada variable en el que se almacena el tipo actual Cambio en el tamaño de la memoria asociada a la variable

2.2. Ligadura de espacio y tiempo de vida ♦ Proceso de asignación: ligar celdas de memoria, tomadas de zonas de memoria disponible, a variables ♦ Proceso de desasignación: desligar las celdas de memoria de la variable y devolver las celdas a las zonas de memoria disponible ♦ Tiempo de vida de una variable de programa: tiempo durante el cual la variable está ligada a una localización específica de memoria ⇒ tiempo entre asignación y desasignación de espacio ♦ Clasificación de las variables en cuatro categorías atendiendo a sus tiempos de vida y a la zona de memoria desde donde se realiza la asignación

A. Variables estáticas ♦ Se ligan a celdas de memoria antes de que comience la ejecución del programa y permanece ligada a las mismas celdas hasta que acaba la ejecución del programa ♦ Las variables globales son variables estáticas ♦ Puede ser conveniente declarar variables en subprogramas que retengan el valor entre ejecuciones diferentes → variables estáticas en subprogramas (ej. static en C)

Departamento de Informática

11

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Ventaja principal: eficiencia •



Todas pueden tener direccionamiento directo (otros tipos de variable necesitan direccionamiento indirecto que es más lento) No hay sobrecarga en tiempo de ejecución por asignación o desasignación de espacio

♦ Desventaja: reducida flexibilidad •

Si un LP no dispone de otro tipo de variables ⇒ no se soportan programas recursivos

B. Variables dinámicas de pila ♦ La ligadura de espacio se produce cuando se elabora la sentencia de declaración, exceptuando las que se ligan estáticamente ♦ Elaboración de una sentencia de declaración: proceso de asignación y ligadura de espacio indicada por la declaración que tiene lugar cuando la ejecución alcanza el código de dicha declaración ⇒ la elaboración se produce en tiempo de ejecución ♦ Ej: los procedimientos en Pascal tienen: •



Sección de declaración: se elabora justo antes de la ejecución del código, cuando se llama al procedimiento Sección de código

La asignación se produce en tiempo de elaboración y la desasignación al devolver el control al procedimiento que realiza la llamada ♦ El espacio se asigna en la pila de tiempo de ejecución ♦ Las variables locales (declaradas en subprogramas) son variables dinámicas de pila (a excepción de las declaradas como estáticas)

Departamento de Informática

12

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Ventajas: •



Todas las variables comparten el mismo espacio de memoria (la pila) Permiten recursión → permite almacenar una copia diferente de las variables locales para cada una de las llamadas recursivas

♦ Desventaja: •

Sobrecarga en tiempo de ejecución debido a la asignación y desasignación de espacio en la pila

C. Variables dinámicas de montón (heap) ♦ Montón (heap): colección de celdas de almacenamiento cuya estructura está muy desorganizada debido a la naturaleza imprevisible de su uso ♦ Dos clases: explícitas e implícitas

C.1. Explícitas ♦ Variables sin nombre cuyo almacenamiento se asigna y desasigna en tiempo de ejecución mediante la utilización por el programador de instrucciones específicas ♦ Sólo pueden ser referenciadas mediante apuntadores ♦ La creación/destrucción de variables puede hacerse mediante un operador (C++, Ada) o una función de biblioteca (C, Pascal)

Departamento de Informática

13

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Ejemplo: Pascal type pnodo = ^nodo; nodo

= record … end;

var nuevo_nodo: pnodo; … begin … { La ligadura del tipo es estática y la de espacio dinámica}

new(nuevo_nodo); … dispose(nuevo_nodo); … end;

♦ Uso: estructuras dinámicas (listas, árboles, grafos, …) ♦ Desventajas: • •

Dificultad para usarlas correctamente Coste en tiempo de ejecución en las operaciones de referencia, asignación y desasignación

C.2. Implícitas ♦ Se les liga espacio del montón sólo cuando se le asignan valores (de hecho, todos sus atributos se ligan cada vez que se produce una asignación) ♦ Ejemplo: variables de APL ♦ Ventaja: flexibilidad en la programación → permite escribir código muy genérico Departamento de Informática

14

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Desventajas: • •

Dejan de detectarse algunos errores de tipo Sobrecarga en tiempo de ejecución (asignación/desasignación de espacio y resto de atributos)

3. Tipos 3.1. Comprobación de tipos ♦ Generalización de los conceptos de operandos y operadores para incluir a subprogramas y sentencia de asignación: • •

Subprogramas → operadores cuyos operandos son sus parámetros Asignación → operador binario cuyos operandos son la variable a la que se asigna el valor y la expresión a evaluar

♦ Comprobación de tipos: actividad que nos asegura que los operandos de un operador son de tipos compatibles ♦ Tipos compatibles: un tipo legal para el operador o un tipo que atendiendo a determinadas reglas del lenguaje puede ser convertido implícitamente mediante código generado por el compilador en un tipo legal. Esta conversión automática se denomina coacción (coercion) ♦ Error de tipos: aplicación de un operador a un operando de tipo inapropiado ♦ Si todas las ligaduras de tipos a variables son estáticas ⇒ las comprobaciones de tipo pueden realizarse de forma estática ♦ Si hay ligadura dinámica de tipos a variables ⇒ debe realizarse una comprobación dinámica de tipos (más costosa que en tiempo de compilación)

Departamento de Informática

15

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ LP (Pascal, Ada, C) que permiten el almacenamiento en la misma celda de memoria de valores de tipos diferentes en momentos distintos de la ejecución (registros variantes y uniones) ⇒ la comprobación de tipos para estas clases de datos debe ser dinámica ⇒ requiere mantener durante la ejecución el tipo actual asociado a la celda de memoria ⇒ no todos los errores pueden detectarse con una comprobación estática de tipos

3.2. Disciplina de tipos (strong typing) ♦ Un lenguaje tiene disciplina de tipos si los errores de tipos se detectan siempre ⇒ es necesario determinar los tipos de todos los operandos, ya sea en tiempo de compilación o de ejecución ♦ Pascal •

Cercano a tener disciplina de tipos pero no realiza comprobación de tipos en los registros variantes (incluso puede omitirse la etiqueta discriminatoria en dichos registros)

♦ Ada •



Resuelve el problema de los registros variantes realizando comprobación dinámica de tipos (sólo en este caso) Tiene una función de biblioteca que permite extraer un valor de una variable de cualquier tipo (como una cadena de bits) y usarlo como un tipo diferente (no es una conversión de tipos) ⇒ se trata de una suspensión temporal de la comprobación de tipos

♦ C •

No tiene disciplina de tipos por: − −

No se realiza comprobación de tipos sobre las uniones Permite funciones con parámetros sobre los que no se realiza comprobación de tipos

Departamento de Informática

16

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Java •

Tiene disciplina de tipos (no hay uniones)

♦ ML y Haskell • •

Poseen disciplina de tipos Los tipos de los parámetros de las funciones (y de estas mismas) se conocen en tiempo de compilación (ya sea por declaración del usuario o por inferencia de tipos)

3.3. Compatibilidad de tipos ♦ Métodos: •

Compatibilidad de tipos nominal: dos variables tienen tipos compatibles si están ligadas al mismo nombre de tipo Ej: type T = array [1..10] of integer; var a, b: T; begin a := b;



Compatibilidad de tipos estructural: dos variables tienen tipos compatibles si sus tipos tienen la misma estructura Ej: type T = array [1..10] of integer; S = array [1..10] of integer; var a: S; b: T; begin a := b;

Departamento de Informática

17

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •

E.S. Ingeniería Informática

Equivalencia de declaración: dos variables tienen tipos compatibles si uno de los tipos está definido con el nombre del otro Ej: type T = array [1..10] of integer; S = T; var a: S; b: T; begin a := b;

♦ La mayoría de LP utilizan combinaciones de estos tres métodos de compatibilidad ♦ Tipo anónimo: tipo asociado directamente con una variable mediante una declaración sin proporcionarle un nombre Ej. en Ada: a, b: array (1..10) of INTEGER; c: array (1..10) of INTEGER; → La interpretación es obvia usando compatibilidad de tipos estructural → ¿Compatibilidad nominal? Ej. Ada a, b y c son incompatibles ♦ Compatibilidad de tipos nominal: • •

Fácil de implementar pero muy restrictiva Ej. usando un lenguaje con interpretación estricta de la compatibilidad de tipos nominal:

Departamento de Informática

18

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

type tipo_indice = 1..100; var contador: integer; indice: tipo_indice; begin contador := indice; indice := contador; ♦ Compatibilidad de tipos estructural: •

Debe compararse la estructura de ambos tipos, pero: −







¿Son compatibles dos registros con la misma estructura pero con nombres de campos diferentes? ¿Son compatibles arrays del mismo tipo y con el mismo número de elementos pero con rangos de índices diferentes (0..9 / 1..10)? ¿Son compatibles tipos enumerados con el mismo número de componentes pero literales diferentes?

No acepta diferencias entre tipos con la misma estructura Ej: type longitud = real; tiempo = real; var l: longitud; t: tiempo; → l y t son compatibles (tienen la misma estructura), aunque quizás no deberían considerarse equivalentes: son abstracciones de diferentes categorías de valores del problema

Departamento de Informática

19

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

Subtipos y tipos derivados ♦ Subtipo: versión (posiblemente restringida en el rango) de un tipo existente con el que es compatible. Evita uno de los problemas de la compatibilidad de tipos nominal •

Ej. Ada: subtype Natural is Integer range 0.. Integer’Last; subtype Temperatura is Integer range -20..45; n: Natural; i: Integer; t: Temperatura; → Las siguientes asignaciones son posibles: n := i; i := n; t := i; → Se necesita una comprobación en tiempo de ejecución que asegure que el valor que se asigna está en el rango adecuado → Para la función: function "**" (i: Integer; n: Natural) return Integer; y la llamada j ** k; el compilador comprueba que j y k sean del tipo Integer (o de uno de sus subtipos). Durante la ejecución se asegura que el valor actual de k esté en el rango de Natural. Un lenguaje con compatibilidad de tipos nominal sólo aceptaría que j fuese del tipo Integer y n del tipo Natural.

♦ Tipo derivado: nuevo tipo basado en algún otro previamente definido con el que es incompatible, aunque sean estructuralmente idénticos. Heredan todas las propiedades de su tipo padre. (También pueden incluir restricciones sobre el rango)

Departamento de Informática

20

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •

E.S. Ingeniería Informática

Ej. Ada: type Longitud is new Float; type Tiempo is new Float; → Las variables de estos tipos son incompatibles entre ellas y con otras de tipo float (esta regla no se aplica a los literales como 12.5)

4. Ámbito ♦ Ámbito de una variable de programa: rango de sentencias en las que es visible la variable ♦ Una variable es visible en una sentencia si puede referenciarse en dicha sentencia ♦ Las reglas de ámbito de un lenguaje determinan cómo se asocian las referencias a variables declaradas fuera del subprograma o bloque que se está ejecutando con sus declaraciones ⇒ con sus atributos ♦ Una variable es local en una unidad de programa o bloque si está declarada en él. Las variables no locales de una unidad de programa o bloque son aquellas visibles en dicha unidad o bloque pero no declaradas en él

4.1. Ámbito estático ♦ Ámbito estático (introducido por ALGOL 60): método de ligadura de nombres a variables no locales que ocurre en tiempo de compilación ♦ En la mayoría de lenguajes con ámbito estático (C es una de las excepciones) pueden anidarse los subprogramas → cada subprograma crea su propio ámbito ⇒ el resultado es una jerarquía de ámbitos

Departamento de Informática

21

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ ¿Cómo se determinan los atributos de una variable en un lenguaje con ámbito estático? 1º. Se busca su declaración local, y si no se encuentra 2º. Se continúa la búsqueda en el bloque que lo declara, su padre estático. Si no se encuentra, 3º. Se continúa la búsqueda en la unidad que declara a esta última. Así hasta que se encuentra la declaración de la variable o se alcance la unidad de declaración mayor ⇒ error: utilización de una variable no declarada ♦ El padre estático de un subprograma y los padres estáticos de éste hasta el programa principal se denominan antepasados estáticos ♦ Ejemplo: procedure mayor; var x: integer; procedure sub1; begin … x … end; {de sub1} procedure sub2; var x: real; begin … end; {de sub2} begin … end. {de mayor} •

La referencia a la variable x en sub1 se corresponde con la declaración de x en mayor

♦ En lenguajes con ámbito estático, una declaración de una variable oculta cualquier declaración de otra variable con el mismo nombre en un ámbito que englobe al que incluye dicha declaración •

La referencia a la variable x en sub2 se corresponde con la declaración en sub2 ⇒ se oculta la declaración de x en mayor

Departamento de Informática

22

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •

E.S. Ingeniería Informática

Hay lenguajes que permiten hacer referencia a variables ocultas declaradas en antepasados estáticos Ej: Ada. Sintaxis: nombre_unidad_de_programa.nombre_variable mayor.x

♦ Algunos lenguajes (herederos de ALGOL 60) permiten definir nuevos ámbitos estáticos en mitad de código ejecutable ⇒ son variables locales a esa sección de código. Son variables dinámicas de pila ⇒ se les asigna espacio al comenzar la sección y se desasigna cuando se sale de ella ♦ Las secciones de código en la que pueden definirse variables locales se denominan bloques •







Ej. de bloque en Ada: … declare temp: Integer; begin temp := x; x := y; y := temp; end; … Los bloques son el origen de la expresión lenguajes estructurados en bloques Aunque a Pascal se le considera un lenguaje estructurado en bloques no dispone de bloques no procedurales En C, cualquier grupo de sentencia compuesta (secuencia de sentencias englobadas entre llaves) puede definir un nuevo ámbito. Ejemplo: if (lista[i] < lista[j]) { int temp;

}

temp := lista[i]; lista[i] := lista[j]; lista[j] := temp;

Departamento de Informática

23

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación •



E.S. Ingeniería Informática

Java permite que la definición de una variable aparezca en cualquier lugar de una función → el ámbito de la variable comienza en la sentencia de definición y acaba en el final del bloque que la incluye Los ámbitos definidos por bloques se tratan igual que los creados por subprogramas

Evaluación del ámbito estático ♦ Proporciona un método de acceso a variables no locales adecuado en la mayoría de los casos ♦ Problemas: •



Acceso a demasiados datos. Por ejemplo, todas las variables declaradas en el programa principal son visibles en todos los procedimientos, se desee o no Los cambios pueden ser complicados: principal

A

C D

B

E

1. Es necesario acceder a variables de D desde E. Soluciones: −



Mover E dentro de D ⇒ E deja de tener acceso al ámbito de B Mover las variables de D que necesita E a principal ⇒ puede accederse a ellas desde otros procedimientos. Además, supongamos que D y E necesitan la variable x. Si en A hay una variable con nombre x ⇒ oculta la variable x que necesita D y hemos movido a principal

Departamento de Informática

24

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

2. E necesita llamar al procedimiento D. Soluciones: −



Mover D dentro de principal ⇒ deja de tener acceso a las variables de A

Esta falta de flexibilidad provoca una tendencia en los programadores a usar más variables globales de las que necesitan

4.2. Ámbito dinámico ♦ Ámbito dinámico (APL, SNOBOL4): basado en la secuencia de llamadas a subprogramas y no en la relación sintáctica entre ellos ⇒ el ámbito sólo puede determinarse en tiempo de ejecución ♦ ¿Cómo se determinan los atributos de una variable en un lenguaje con ámbito dinámico? En tiempo de ejecución: 1º. Se busca su declaración local, y si no se encuentra 2º. Se continúa la búsqueda en su padre dinámico, el subprograma que realizó la llamada. Si no se encuentra, 3º. Se continúa la búsqueda en los antepasados dinámicos. Así hasta que se encuentra la declaración de la variable. Si no se encuentra la declaración en ningún antecesor dinámico ⇒ error en tiempo de ejecución

Departamento de Informática

25

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Ejemplo: procedure mayor; var x: integer; procedure sub1; begin … x … end; {de sub1} procedure sub2; var x: real; begin … end; {de sub2} begin … end. {de mayor} •



Secuencia de llamadas: mayor → sub2 → sub1 ⇒ la referencia a x en sub1 corresponde con la declaración de x en sub2 Secuencia de llamadas: mayor → sub1 ⇒ la referencia a x en sub1 corresponde con la declaración de x en mayor

Evaluación del ámbito dinámico ♦ Una sentencia en un subprograma que contiene una referencia a una variable no local puede relacionarse con una variable diferente cada vez que se ejecuta ⇒ muchos tipos de problemas: •





Durante el tiempo que transcurre entre el comienzo y la finalización de la ejecución de un subprograma todas las variables locales del subprograma son visibles en los subprogramas a los que se llame. No hay forma de protegerlas de esta accesibilidad ⇒ programas menos fiables que con ámbito estático Imposibilidad de realizar una comprobación de tipos estática de las referencias no locales (es imposible determinar estáticamente su declaración) Los programas son más difíciles de leer y seguir por un lector humano

Departamento de Informática

26

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Ventaja: el subprograma hereda el contexto de sus llamadores → método de comunicación entre unidades de programa (menos seguro que otros métodos, como el paso de parámetros)

4.3. Entorno de referencia ♦ Entorno de referencia de una sentencia: colección de todos los identificadores visibles en dicha sentencia •



Lenguajes con ámbito estático: el entorno de referencia de una sentencia está compuesto por las variables declaradas en su ámbito local más todas las variables visibles de sus antepasados estáticos Lenguajes con ámbito dinámico: el entorno de referencia de una sentencia está compuesto por las variables declaradas localmente más todas las variables visibles del resto de subprogramas activos Ej.: principal → sub2 → sub1 procedure sub1; var a,b: integer; begin … {A} end; {de sub1} procedure sub2; var b,c: integer; begin … {B} sub1; end; {de sub2} procedure principal; var c,d: integer; begin … {C} sub2; end. {de principal} Punto Entorno de referencia A a y b de sub1, c de sub2, d de principal B b y c de sub2, d de principal C c y d de principal

Departamento de Informática

27

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

5. Constantes ♦ Constante: objeto al que se le liga un valor sólo en el momento en el que se le liga el espacio ⇒ su valor no puede cambiarse por asignación o por sentencia de entrada ♦ Ventajas: • •

Aumenta la fiabilidad y legibilidad de los programas El valor aparece en una sola línea de programa ⇒ más fácil su modificación

♦ Constantes manifiestas: constantes con ligadura estática de valores • •

Pascal: la declaración de una constante requiere un valor simple Modula-2: permite expresiones constantes (constantes ya declaradas, literales y operadores)

♦ Otros lenguajes (Ada, Java) permiten ligadura dinámica de valores a constantes ⇒ pueden aparecer variables •

Ada: num_elementos: constant Integer := 2 * i + j;

6. Inicialización de variables ♦ Inicialización: ligadura de un valor a una variable en el momento en el que también se le liga el almacenamiento ♦ Variables estáticas: inicialización sucede una sola vez antes del momento de la ejecución ♦ Variables con ligadura dinámica de espacio: la inicialización también es dinámica

Departamento de Informática

28

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Inicialización en algunos lenguajes: •

Pascal: No tiene sentencias de inicialización



C: en la sentencia de declaración puede indicarse un valor inicial Ej.: int i = 10;



Ada: la inicialización puede incluir nombres de otras constantes o variables visibles en el momento de la elaboración de la inicialización Ej.: contador: integer := num_elem + 1; num_elem puede ser el nombre de una variable o constante

Variables no inicializadas ♦ Las declaraciones sin inicialización crean variables no inicializadas: se les liga memoria pero su contenido es arbitrario y no puede ser interpretado como un valor del tipo del objeto declarado. El uso de un valor no incializado produce resultados impredecibles y debe evitarse ♦ Posibles aproximaciones que pueden utilizar los LP: •







Se ignora el problema y se considera responsabilidad del programador no emplear valores no inicializados. Poco elegante Todas las declaraciones inicializan el espacio asignado a un valor apropiado, definido para cada tipo básico. Por ej., punteros a null y valores numéricos a cero. Puede llevar a errores No existen declaraciones sin inicialización ⇒ el programador debe proporcionar un valor de inicialización adecuado para cada elemento declarado Existe un valor especial para cada tipo denominado omega, que representa la propiedad de ausencia de inicialización. Este valor se propaga en las expresiones (omega + 3 → omega). Permite al programador comprobar dinámicamente si una variable está o no inicializada

Departamento de Informática

29

Área de Lenguajes y Sistemas Informáticos

Lenguajes de Programación

E.S. Ingeniería Informática

♦ Ejemplos de algunos LP: • •



Pascal: ignora el problema Ada: inicializa apuntadores a null e ignora el problema para el resto de tipos C: inicializa las variables estáticas a una forma apropiada de cero. Ignora el problema para el resto de las variables

Departamento de Informática

30

Área de Lenguajes y Sistemas Informáticos

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.