Lenguajes de Programación - Departamento de Ciencias e

Anuncio
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Lenguajes de Programación
Expresiones
Ma. Laura Cobo
Universidad Nacional del Sur
Departamento de Ciencias e Ingeniería de la Computación
2016
Prof. Ma. Laura Cobo
Página 1
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Introducción
Las expresiones son una forma fundamental de especificar
computación en un lenguaje de programación.
Además de la forma de las mismas (sintaxis: BNF), su significado
(semántica) es crucial.
La semántica, esta gobernada por su forma de evaluación
Es necesario estar conscientes de los ordenes de evaluación
de operandos y operadores
La esencia de los lenguajes de programación imperativos es
dominada por el rol de las sentencias de asignación
2
Prof. Ma. Laura Cobo
Página 2
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Expresiones Aritméticas
Las expresiones constan de:
• Operadores
• Operandos
• Paréntesis
• Llamadas a función
Los operadores pueden ser:
• Unarios: tienen sólo un operando
• Binarios: tienen dos operandos
3
Prof. Ma. Laura Cobo
Página 3
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Expresiones Aritméticas
La mayoría de los lenguajes imperativos adoptan una notación
infija para los operadores, pero hay otras opciones:
• Prefija
Común
*(+(A,B),-(C,A))
Polaca
(*(+ A B) (- C A))
Polaca Cambridge * + A B – C A
• Posfija
Sufija
((A,B)+,(C,A)-)*
Inversa
AB+CA-*
• Infija
(A + B) * (C – A)
4
Prof. Ma. Laura Cobo
Página 4
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Expresiones Aritméticas
Aspectos de diseño:
• Reglas de precedencia de operadores
Control
• Reglas de asociatividad de operadores
• Orden de evaluación de los operandos
• Evaluación de efectos colaterales de un operador
• Sobrecarga de un operador
• Modo mixto de expresiones
• Errores en las expresiones
5
Prof. Ma. Laura Cobo
Página 5
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Reglas de precedencia - Asociatividad
Define el orden en el cual operadores adyacentes (con diferente
precedencia) son evaluados.
Los niveles de precedencia típicos son:
•
•
•
•
•
Paréntesis
Operadores unarios
** (potenciación)
*, /
+, -
Define como se resuelve el orden de evaluación frente a
operadores del mismo nivel de precedencia.
Regla típica: evaluación de izquierda a derecha
Las reglas de precedencia y asociatividad pueden modificarse
con el uso de paréntesis
Prof. Ma. Laura Cobo
6
Página 6
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación de operandos
1. Variables: cargar el valor desde memoria
2. Constantes: algunas veces son cargas desde la memoria,
otras veces la constante puede ser parte de las instrucciones
del lenguaje máquina
3. Expresiones parentizadas: se evalúan las expresiones de
acuerdo al modo de evaluación elegido
Si ninguno de los operandos u operadores tiene efectos colaterales,
entonces el orden de evaluación es irrelevante
7
Prof. Ma. Laura Cobo
Página 7
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Efectos colatelares potenciales
Efectos colaterales funcionales: cuando una función cambia un
parámetro de entrada-salida o una variable global.
a + fun(a)
Si fun es una función que no tiene efectos colaterales sobre la variable a entonces
el orden de evaluación los operandos no afecta el valor de la expresión. Caso
contrario el orden de evaluación determina el valor de la misma
Ejemplo en C:
int a =5;
int fun1()
{
a = 17;
return 3;
void fun2 ()
{
a = a + fun1();
void main()
{
fun2();
Prof. Ma. Laura Cobo
}
}
}
8
Página 8
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Soluciones a el problema de efectos colaterales
1. El diseñador del lenguaje de programación deshabilita los
efectos colaterales de las funciones
a. No hay parámetros de entrada-salida en las funciones
b. No hay referencias a variables globales en las funciones
• Ventaja: funciona como solución
• Desventaja: muy inflexible
2. Escribir la definición del lenguaje de manera que fije la
evaluación de los operandos
• Desventaja: limita las posibilidades de optimizar el código
9
Prof. Ma. Laura Cobo
Página 9
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Operadores sobrecargados
Tiene lugar, cuando se utiliza el mismo operador para más de un
propósito.
Características:
1. Pérdida de detección de errores por parte del compilador
2. Pérdida en la facilidad de lectura (readability)
3. Puede ser evitada con la introducción de nuevos símbolos
4. Lenguajes como C++ y Ada permiten al usuario declarar
operadores sobrecargados
• El usuario puede declarar operadores sin sentido
• La facilidad de lectura se ve lesionada aún cuando el
operador tenga sentido
10
Prof. Ma. Laura Cobo
Página 10
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Conversión de tipos
La conversión o bien limita el tipo o lo expande.
Una conversión limitante sucede cuando se convierte el tipo de un
objeto a un tipo que no puede incluir todos los valores del tipo
original. Por ejemplo transformar el tipo de un objeto float en int
Un conversión expansora sucede cuando se convierte el tipo de un
objeto a un tipo que puede incluir al menos aproximaciones al
tipo original. Por ejemplo transformar int a float
11
Prof. Ma. Laura Cobo
Página 11
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Conversión de tipos
Las conversiones de tipo pueden ser:
• Explicitas o implícitas
Un decisión de diseño de las expresiones es determinar si se van a
Expresiones que admiten
permitir expresiones mixtas
operadores de tipos diferentes
Las conversiones implícitas o coerciones es generalmente iniciada
por el compilador.
La mayoría de los lenguajes de programación provee coerciones
expansoras para sus expresiones
12
Prof. Ma. Laura Cobo
Página 12
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Conversión de tipos
Las conversiones de tipo explicitas pueden ser de tanto limitantes
como expansoras.
En lenguajes como C se realizan a través del cast.
(int) temperatura
En cambio en lenguajes como Ada la sintaxis es parecida a la de
las llamadas a función:
AVG := FLOAT(SUMA) / FLOAT (CONTADOR)
•
•
Errores en las expresiones
Causadas por limitaciones inherentes a la aritmética (por
ejemplo división por cero)
Causadas por limitaciones en la forma de computar la aritmética
(overflow-underflow de la representación)
13
Prof. Ma. Laura Cobo
Página 13
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Expresiones relacionales y booleanas
Expresiones relacionales
Usan operadores relacionales sobre operadores de diferentes
tipos.
El valor obtenido de cualquier expresión relacional es booleano
Los lenguajes utilizan diferentes símbolos para representar a los
operadores relacionales
Expresiones booleanas
En este caso tanto los operadores como los operandos son de
tipo booleano
Nuevamente los lenguajes utilizan símbolos diferentes para
representar los operadores booleanos tradicionales
14
Prof. Ma. Laura Cobo
Página 14
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Expresiones relacionales y booleanas
Curiosidades
C no provee el tipo booleano en forma explicita (utiliza en tipo int)
Además tiene permite escribir expresiones que no se computan de
la forma que se esperaría
a<b<c
La precedencia de los operados booleanos y relaciones en general es
la habitual (cómo en el caso aritmético)
15
Prof. Ma. Laura Cobo
Página 15
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación de expresiones
Nos resta ver las posibles forma de evaluar las expresiones
Los tipos fundamentales son:
1. Evaluación Estricta
2. Evaluación No Estricta
Evaluación Estricta: los argumentos de una función o los
operandos de la expresión son siempre completamente evaluados
antes de la aplicación de la función u operador.
Evaluación No Estricta: los argumentos de una función o los
operandos de la expresión no son evaluados a menos que sean
utilizados en el cuerpo de la función o sean necesarios para
determinar el valor de la expresión.
16
Prof. Ma. Laura Cobo
Página 16
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación estricta
La evaluación estricta es la tradicionalmente utilizada por los
lenguajes de programación.
Es también conocida como:
Evaluación de orden aplicativo (evalúa de izq. a der.)
Evaluación ansiosa
En este tipo de evaluación una expresión se evalúa al momento de
establecer la ligadura con una variable.
Los lenguajes imperativos la utilizan casi siempre (debido a que el
orden de ejecución esta definido implícitamente por la
organización del código)
17
Prof. Ma. Laura Cobo
Página 17
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación estricta
Ventajas:
Elimina la necesidad de planificar
El programador puede determinar el orden de ejecución
Desventajas:
Fuerza la evaluación de expresiones que pueden no ser
necesarias en tiempo de ejecución.
Puede demorar la evaluación de expresiones cuyo valor se
requiere en forma mas inmediata.
Fuerza al programador a organizar el código fuente para
garantizar una ejecución óptima.
18
Prof. Ma. Laura Cobo
Página 18
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación no estricta
Cuando se implementa se denomina evaluación de orden normal.
Características:
La evaluación se reduce por la izquierda
Las funciones se aplican antes de evaluar sus argumentos.
Se puede especializar en distintas versiones:
Evaluación perezosa: agrega la memorización de los
argumentos evaluados.
Evaluación corto-circuito (expresiones booleanas): se retorna
el valor de la expresión tan pronto como se pueda
determinar el valor de verdad sin ambigüedad
19
Prof. Ma. Laura Cobo
Página 19
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación de orden normal: Ejemplo
Ejemplo: Considere la siguiente llamada sumar(2+3)
sumar(x):
sumar(x):
yy==2+3
x * 2* 2
zz==2+3
+ 10
x + 10
El resultado, se obtiene sustituyendo x con la expresión 2+3. La
expresión 2+3 y no el valor 5, es pasado como el de valor de x en
la función.
20
Prof. Ma. Laura Cobo
Página 20
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación perezosa: Ejemplo
Ejemplo: Considere la siguiente llamada sumar(2+3)
sumar(x):
y = 2+3
x * 2* 2
z = x5 + 10
El resultado, se obtiene sustituyendo x con la expresión 2+3, en la
primera aparición de x dentro del cuerpo de sumar y por el valor
de la expresión, 5, en las futuras apariciones de x en el cuerpo de
la función.
21
Prof. Ma. Laura Cobo
Página 21
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación perezosa: Ejemplo
Ejemplo en ML
fun g(x,y,z) = if x<2 then y+3 else z+6
a=0: 0 ? b/a
Ejemplo en C
Es interesante notar que solo el valor de y o el valor de z son
requeridos para el cálculo del resultado, pero no ambos.
Ejemplo en Haskell
fibs = 0 : 1 : zipWith (+) fibs(tail fibs)
“:” agrega un elemento a la lista
Tail: retorna una lista sin su primer elemento
zipWith crea una nueva lista tomando el elemento a la cabeza de cada lista,
aplicando una función, + en este caso
Esta función calcula una lista con todos los números Fibonacci.
22
Prof. Ma. Laura Cobo
Página 22
Lenguajes de Programación
Departamento de Cs. e Ingeniería de la Computación
Universidad Nacional del Sur
Primer Cuatrimestre de 2016
Evaluación corto-circuito: Ejemplo
Ejemplo en C
int a = 0; int b = 4
if (a != b && myfun(b) )
{
do_something();
}
En este ejemplo, debido a la evaluación en corto-circuito, se
garantiza que la llamada a myfun(b) nunca suceda. Esto es porque
a se evalúa como falso
Otro ejemplo en C
int TieneTresCaracteresDeLongitud(const char *p)
{
return (p != NULL) && (strken(p) ==3);
}
Prof. Ma. Laura Cobo
23
Página 23
Descargar