Está en la página 1de 20

TEMA 5: Expresiones y Sentencias 5.1 Expresiones Son el mtodo fundamental que tiene el programador de expresar computaciones.

. Las expresiones estn compuestas de operadores, operandos, parntesis y llamadas a funciones. Los operadores pueden ser: Unarios: Cuando tan solo tienen un operando. Son operadores prefijos. Binarios: 2 Operandos. Son operadores infijos. Ternarios: 3 operandos. Operadores posfijos en C : a++ 5.1.1 Orden de la evaluacin de los operadores. El orden en que se evalan los operandos viene dado por unas reglas: Reglas de procedencia Reglas de asociatividad Uso de parntesis Precedencia El orden de evaluacin de una expresin puede depender del orden de evaluacin de los operadores: a+b *c Las reglas de evaluacin de los operadores reciben una jerarqua. Esta jerarqua suele ser: Exponenciacin Producto / Divisin Suma / Resta Esto coincide en la mayora de los lenguajes de programacin porque viene de la jerarqua de operadores usada en la matemtica. Muchos lenguajes de programacin permiten el uso del + y del - adems de cmo operadores binarios como operadores unarios. El + se usara como operador de identidad y el - provocara un cambio de signo. Asociatividad Las reglas de asociatividad definen el orden en que deben evaluarse operandos de igual precedencia que aparezcan de manera consecutiva en una expresin: a + b - c -c + h. Puede ser de 2 tipos: Asociatividad por la izquierda: Se evaluan los operadores de izquierda a derecha. Asociatividad por la derecha: Se evalan los operadores de derecha a izquierda. La mayora de los lenguajes de programacin implementan una asociatividad de izquierda en la mayora de sus operadores. Al operador de exponenciacin se le suele aplicar asociatividad por la 1

derecha: a ** b ** c Parntesis Los parntesis alteran las reglas anteriores (de precedencia y asociatividad). Se evala el primer lugar la subexpresin que aparece entre parntesis. 5.1.2 Efectos laterales Si se producen efectos laterales podemos encontrarnos con esta situacin: F(a)+f(a) <> 2 * f(a) Se provoca un efecto lateral en una funcin si cambia el valor de uno de sus parmetros o de una variable global. A + f(a) si f contiene un efecto lateral sobre la variable variar el valor de la expresin si calculamos 1 f(a) y luego sumamos a que si se coge a y le suma f(a). Ej: C Int a=5; Int f1() { a=17; return 3; } void f2() { a=a+f(1); } void main() { f2(); } Si evaluamos los operandos de izquierda a derecha a = a + f1() = 5 + 3 = 8 Si evaluamos los operandos de derecha a izquierda a = a + f1() = 17 + 3 = 20 Una posible Solucin: Fijar el orden de evaluacin. Problema: Algunas tcnicas que emplean los compiladores en la optimizacin del cdigo necesitan que se altere el orden de los operandos con lo que perdemos el orden de evaluacin. 2

Pascal y Ada no fijan el orden de evaluacin de los operandos. Adems, como se permiten efectos laterales, el mismo programa compilado por dos compiladores diferentes puede dar diferente resultado. C sin embargo exige el orden de evaluacin de los operandos de izquierda a derecha. 5.1.3 Expresin condicional Hay lenguajes que incluyen formas de expresiones muy diferentes como por ejemplo la expresin condicional: ADA: Q:=if x /= 0 then 1/x else 0 C incorpora un operador ternario: Q= x!=0 ? 1/x : 0 5.1.4 Sobrecarga de operadores En muchos lenguajes el operador + se usa para sumar enteros, sumar nmeros reales, concatenar strings etc. Se dice entonces que el operador + est sobrecargado (se realiza un uso mltiple). Ada permite definir al usuario operadores sobrecargados (C++ tambin) Ej: Producto escalar Escalar * vector de enteros Definiramos una funcin que hiciera el producto escalar y le daramos como nombre el smbolo *. Cmo decide el compilador que instruccin o funcin hay que usar?, Porque para las lneas de cdigo 3.5 + 2.7 y 3 + 2 debemos emplear instrucciones mquina diferentes. Pues el compilador ve el tipo de los operadores que acompaan al operando. El hecho de que un lenguaje permita definir operadores sobrecargados aumenta la legibilidad del programa por lo que esta caracterstica resulta muy til. Si A, B, C y D son matrices, en caso de que se permita sobrecargar operadores haramos A * B + C * D. Si no se permitiera deberamos usar una sentencia de cdigo muy parecida a la siguiente: SumaMat(MultMatriz(A, B), MultMatriz(C, D)) 5.1.5 Conversin de tipos Las conversiones de tipo que podemos realizar pueden ser: Por ampliacin: El tipo destino puede incluir una aproximacin o al menos una aproximacin para todos los valores del tipo original. C:int float 3 3.0 Por reduccin: El tipo destino no puede incluir todos los valores del tipo original. Ejemplo: C: double Float Se hace un redondeo Las conversiones pueden realizarse de manera implcita (coaccin) de manera explcita.

Coaccin La coaccin consiste en tener por ejemplo el siguiente caso: 2 + 3.5; A esta expresin se le llama expresin en modo mixto. En este caso el compilador debe iniciar la conversin en uno de los dos operandos. Los lenguajes de programacin que permitan expresiones en modo mixto tendrn que definir algunas conversiones para estas conversiones implcitas. Es el propio compilador el que genera el cdigo necesario para esta conversin. C realiza coacciones de una manera muy amplia. Provoca que el que se pierdan los beneficios de la conversin de tipos. Ej: En C: void main() { int a,b,c; float d; .... a=b*d; {b se convierte en float, pero a sigue siendo int} } En este programa coacciona b con float; Producto de reales; Coacciona el resultado del producto a int (truncamiento). C no detecta este tipo de errores. Sin embargo Pascal detectara esto como un error de tipos. Conversin exlcita de tipos La conversin explcita de tipos esta permitida por la mayora de los lenguajes. Por ejemplo: ADA La conversin se realiza como si se llamara a una funcin. Float (A) //Donde a es lgicamente una variable. C: se hace un cast que es como se designa la conversin explcita de tipos en C. Se suele conocer tambin como molde. (float)a //donde a es una variable 5.1.6 Expresiones relacionales y booleanas En una expresin relacional intervienen 2 operandos y un operador relaccional. (<,>,>=, ...) El valor de la expresin relaccional es de tipo booleano (en C es un valor entero). Se trata de expresiones que contienen operadores sobrecargados que permiten comparar caracteres, nmeros de cualquier tipo ... Las expresiones booleanas incluyen: Variables booleanas Constantes Booleanas 4

Expresiones relaccionales Operadores booleanos (y - and // o - or // no - not // o exclusivo - xor) Las expresiones booleanas devuelven un valor booleano. El orden de precedencia de los operadores booleanos es el siguiente: Not -> And->Or, Xot C no incluye el tipo booleano por eso representa este tipo con enteros en los cuales si el entero es 0 se supone que es falso y en caso contrario que es verdadero, o lo que es lo mismo: Se devuelve un valor distinto de 0 si el valor de la expresin booleana es cierto Se devuelve 0 si el valor de la expresin booleana es falso. Ojo!!!!!!!! Relacionado con las expresiones booleanas es el hecho de que a veces no se necesita evaluar todos los operandos para conocer el resultado de una expresin. A[1..10] If (i<=10) and (a[i]>0) then En este caso no sera necesario evaluar si a[i]>0 si se supiera que i es mayor que 10 Si durante la evaluacin de una expresin no se necesita seguir evaluando los otros operandos se dice que es evaluacin perezosa. Es altamente usada en lenguajes funcionales. En lenguajes de programacin imperativos solo expresiones con OR y AND son evaluadas as. A estos operadores se les denomina operadores de circuito corto. (A los operadores que se les hace una evaluacin perezosa se les denomina operadores de circuito corto) Los operadores de circuito corto unto con los efectos laterales pueden provocar situaciones poco deseables. Ejemplo en C: (a > b) || (b++ / 3) Esta expresin contiene un efecto lateral que solo se evaluar en caso de que no se cumpla la primera condicin a > b. Qu hacen los lenguajes de programacin al respecto? C permite evaluacin de circuito corto con los operadores booleanos. Pascal no permite evaluacin de circuito corto. No se pueden usar sentencias del siguiente tipo: A:array[1..10] of integer; If (i<=10) and (a[i]>0) then Porque se accede a una posicin no vlida de un array. Ada: and, or no son operaciones de circuito corto y or them y and them si son operaciones de circuito 5

corto. If (i<=10) and them (a[i]>0) them 5.2 Sentencia de Asignacin Tienen un papel predominante en los lenguajes imperativos. Por eso los lenguajes de programacin introducen el concepto de variable como que cambia en el tiempo. En cambio en los funcionales son parmetros de una funcin ( En C se hace referencia a una direccin mientras que en Haskell es una vbble matemtica). La secuencia de asignacin es un mecanismo que permite al usuario cambiar de manera dinmica la forma de vinculacin de valores a variables. Forma general: LE:=RE (<Expresion izquierda>:=<expresion derecha>) La evaluacin de la LE da como resultado una referencia y la evaluacin de la RE da como resultado un valor. Por tanto podemos entender la secuencia de asignacin como una operacin sobre el par (referencia, valor) Variantes Se basa simplemente en la observacin <destino><operador><otro operando>. Ej: i:=i+1; a[n * k +j +1] := a [n * k + j + 1] *2; Para simplificar las sentencias de este tipo algunos lenguajes de programacin incluyen los operadores de asignacin combinados. Por ejemplo en C += -= *= /=. Por lo que el ejemplo anterior quedara: a[n * k +j +1]*= 2; Estos operadores hacen ms fcil la tarea al programador y permiten que se genere cdigo de una manera muy eficiente sin necesidad de aplicar tcnicas de optimizacin. C incluye tambin operadores de asignacin unarios que permiten incrementar o decrementar el valor de un operando. Estos operadores tienen valor diferente si se escriben de una manera prefija (en la que se habla de preincremento) o postfija (en la que se habla de postincremento). Ej: A=1 B=++a //b=2 y a=2 a=1 b=a++; //a=2 y b=1 6

5.2.2 Asignacin de destinos mltiples Hay lenguajes de programacin que permiten indicar ms de una expresin izquierda o LE en una sentencia de asignacin con una sintaxis de la forma: L1,L2.L3,L4 .. Ln := E; Se evala la expresin y se asigna el mismo valor a las n localizaciones. C permite asignacin de destinos mltiples.A=b En C las asignaciones se evalan como expresiones. (dando como resultado un valor); Se puede hacer: a=b=c=d=expresin (En realidad el igual no es operador de destino mltiple) while((c=getchar())!=EOF) 5.2.3 Asignacin simultanea Se transfiere simultneamente ms de un valor: L1, L2 , ... , Ln:= E1 , E2, ... , En Para realizar una asignacin simltnea hay que: Evaluar los valores de las L expresiones Evaluar los Rvalores de cada Ei Se realiza la asignacin Ej: x,y:=y,x (Se intercambian los valores de x y de y -utiliza direccin de memoria ausiliar-) Errores samnticos; Podemos llegar a la siguiente situacin: A[i], a[j] : =3,5 Habra que plantearse cul tendra que ser el resultado de la asignacin si i=j 5.2.4 Asignacin de modo mixto Se produce cuando tenemos un valor de un tipo y la regerencia de otro: LE:=RE Pascal: coacciones por ampliacin A:=3 {Donde a es una variable real y 3 es una constante entera Se puede hacer} A:=8.75; {Donde a es variable entera y 8.75 una constante real no se puede hacer o de lo contrario obtendremos un error de tipo} A:=Trunc(8.75); A:=Round(8.75); 7

C: Por ampliacin Por reduccin A:=8.75; //Si A es una variable entera y 8.75 una constante real asignara a A 8, es decir, realiza un truncamiento. 5.3 Controlde Flujo Dos mecanismos lingsticos adicionales: Medio de seleccin: Poder seleccionar entre 2 o varios caminos de flujo alternativo Medio de ejecucin repetida: de una coleccin de sentencias Al conjunto de sentencia que proporcionan ambos medios se denominan sentencias de control. El conjunto idneo de sentencias de control depende de los objetivos de los diseadores del lenguaje. Si el diseador quiere disear un lenguaje pequeo y simple entonces tendremos un conjunto reducido de sentencias de control. Estructura de control: Hace referencia a la sentencia de control y al conjunto de sentencias cuya ejecucin controla la primera. 5.3.1 Composicin de sentencias Secuenciador: Indica que sentencia debe ser la prxima en ejecutarse. Ejemplo: Secuenciador i:=i+1 ; j:=j+1 Si el lenguaje no dispone de un Secuenciador explcito se mantiene el orden de escritura. Otro Secuenciador: Sentencia GOTO: Lo que hace es especificar una etiqueta que indica la siguiente computacin. El control de flujo se transfiere s la sentencia que lleva el GOTO. Hay lenguajes que permiten agrupar conjuntos de sentencias considerndolas como una sola (sentencia compuesta). Ejemplo: Begin S1; S2; Sentencia compuesta ..... Sn; End 8

Si la sentencia compuesta permite siempre aadir declaraciones al comienzo, se habla de bloque. Ejemplo: 5.3.2 Seleccin Una sentencia de seleccin proporciona el medio de eleccin entre 2 o mas caminos de ejecucin.La seleccin aparece en todos los lenguajes imperativos. La forma mas simple de seleccin es la sentencia IF. Se puede realizar una seleccin entre un numero de segmentos de cdigo basndose en el valor de una variable entera o de una variable enumerada. Sentencia case: Se evala la expresin y el valor resultante se busca en el conjunto de la lista de valores y se ejecuta la sentencia asociada a ese valor. Al final se devolvera el control a la siguiente sentencia que vaya despus del End. Qu ocurre si el valor resultante de la expresin no aparece en ninguna de las listas de valores? En pascal: El resultado es indefinido. Dependiendo del implementador del compilador se hace una cosa y otra; no se hace nada dar un error en tiempo de ejecucin Lo que se suele hacer es incluir la clusula otherwise/else que no esta definida en el Pascal estndar (se ejecutara la sentencia asociada). En c: Si el valor no aparece en la lista, no se hace nada.C incluye una clusula: default equivalente al otherwise de Pascal En Ada: en tiempo de compilacin se comprueba que aparecen en la lista de calores todos los valores posibles de la expresin. La clusula others para que no haga nada ( por ejemplo) Aparecen otros problemas referentes a la utilizacin de la sentencia caso: Restricciones Habituales: Las expresiones que forman parte de las listas de valores debe ser posibles esamblarlas en tiempo de compilacin. No se suele permitir que aparezca duplicado un valor en las listas de valores. En C: Solo se permite que aparezca un valor en cada lista de variables. De manera que para el usuario pueda definir una misma accin para distintos casos (valores): hay que utilizar de una manera explcita una transferencia de control: Break; 5.3.3 Repeticin Tenemos sentencias iterativas o repetitivas, que son aquellas que provocan que una sentencia o coleccin de sentencias seas ejecutadas 0,1 o mas veces En los lenguajes funcionales la repeticin se hace muy distinta a la de los lenguajes imperativos (se hace con recursividad); 9

En los lenguajes imperativos: 2 formas de repeticin: La repeticin se realiza sobre un conjunto precalculado (finito) Sentencia For La repeticin esta basada en la evaluacin de una condicin Sentencia While Bucles controlados por contador. Permiten la repeticin de una sentencia o un conjunto de sentencias un numero determinado de veces ( a priori). ara ello utilizan una variable de control que cuenta el numero de veces que se llevan hasta ese momento. Esta variable de control esta a disposicin de las sentencias que se repiten (saben en que iteracin esta). Es muy til para el recorrido de arrays (se conoce a priori el recorrido del array). Pascal: For variable:=valor_inicial to valor_final do Sentencia; Ada: For variable in [reverse] rango_discreto Loop ... End Loop El rango discreto va de 1 a n El reverse es opcional y equivale al downto de Pascal Hay lenguajes que incluyen sintaxis para que el programador pueda indicar el tamao del incremento. Ej: 1 to 10 by 2 -> 1,3,5,7,9 Qu sucede con la sentencia for de C ? for ([exp1]; [exp2];[exp3]) sentencia; donde: exp1: expresion de inicializacion,se evalua una sola vez al comienzo del bucle. exp2: expresion de control de bucle (se evalua al comienzo de cada ejecucion del cuerpo del bucle). exp3: se ejecuta siempre despues de ejecutar la ultima expresion del cuerpo del bucle. (Es como una sentencia while disfrazada).

10

Si hacemos : For (; exp ;) Sentencia; Equivale a: While (exp) Sentencia; Cuestiones relacionadas con la sentencia for. Quin declara la variable de control y cual es el ambito de esa variable? PASCAL,C: La variable de control la declara de manera explicita el programador.La declarar en el bloque donde est la sentencia for o en algun bloque anterior. El mbito de la variable de control ser el ambito del bloque. ADA: La variable de control del bucle se declara de manera implicita. El mbito de esa variable se restringe al cuerpo del bucle. Decide cual es el tipo de la variable a partir de la evaluacion del rango. Cul es el valor de la variable de control una vez finalizado el bucle? PASCAL ESTNDAR: el valor es indefinido (depende de la implementacion del compilador) C: el valor ser el valor que ha hecho falso la evaluacion de la expresion. ADA: no se puede hacer referencia al valor de esa variable. Puede modificarse el valor de la variable de control desde el interior del bucle? PASCAL,ADA:No C: Si Puede modificarse el rango sobre el que se mueve la variable de control desde el interior del bucle? C: S ,porque la evaluacion de la exp2 se produce en cada iteraccin. PASCAL,ADA: Si, lo que ocurre es que el rango se evalua 1 sola vez antes del comienzo de la 1 iteraccion. Se permite modificar pero esto no va a afectar al control del bucle. Bucles controlados de manera lgica. Permiten ejecutar una coleccin de sentencias de manera que el control se realiza mediante la evaluacion de una expresion booleana. Muchos lenguajes de programacion imperativa incluyen 2 tipos de bucle: Ej: 11

PASCAL: While expr do Begin Sentencia; End Se ejecutar mientras la evaluacion de la condicion sea cierta. Repeat Sentencia; Until expr; No es ortogonal porque si hay varias sentencias no hace falta poner Begin y End. Siempre se ejecuta como minimo 1 vez .Se sale cunado el valor de la expresion es cierta. C: While (expr) { Sentencia; } do { Sentencia; } while (expr) El lenguaje C si que es ortogonal porque utiliza en los dos casos las { } para el conjunto de sentencias. Nota: Forma diferente de sentencias de control que son deterministas. 5.3.4 SELECCI N E ITERACCION NO DETERMINISTA Dijkstra (1975) sugiri una alternativa a las sentencias de seleccin y bucle que hemos visto. La seleccin propuesta por Dijkstra es : If <expresion booleana 1> -> <sentencia 1> 12

[ ] <expresion booleana 2> -> <sentencia 2> [ ] <expresion booleana 3> -> <sentencia 3> [ ] ... [ ] <expresion booleana N> -> <sentencia N> fi Siempre se avaluan todas las expresiones booleanas de forma que si es cierta mas de una expresion,se elige ejecutar alguna de las sentencias asociadas. Si ninguna de las sentencias es cierta se produce un error en tiempo de ejcucin. Si la evaluacion tiene una sola sentencia cierta solo se ejecutar esa. Propone una solucion elegante cuando se puede llegar a una misma solucion por caminos diferentes. Ej: If x>=y -> max:=x [ ] y>= -> max:=x fi x=y sea cual sea la que se ejecuta el resultado va a ser el mismo. Propone ademas una estructura de bucle de caracteristicas similares: Do <expresion booleana 1> -> <sentencia 1> [ ] <expresion booleana 2> -> <sentencia 2> [ ] <expresion booleana 3> -> <sentencia 3> [ ] ... [ ] <expresion booleana N> -> <sentencia N> od Todas las expresiones booleanas se evaluan en cada iteraccion del bucle,si son ciertas maas de una expresion se elije ejecutar de forma aleatoria de una de ellas. El bucle finaliza cunado la evaluacion de todas las expresiones da como resultado falso. Ej: Q1,q2,q3,q4 =>q1<= q2<= q3<= q4 Ordena el contenido de las variables 13

Do q1<q2 -> temp:=q1;q1:=q2;q2:=temp; [ ] q2<q3 -> temp:=q2;q2:=q3;q3:=temp; [ ] q3<q4 -> temp:=q3;q3:=q4;q4:=temp; od Estas sentencias estn implementadas en lenguajes de tipo concurrente. 5.4 Control Global Varios tipos de estructuras de control no local (El control no hace referencia a un conjunto de sentencias dentro de un while o un if sino que son de tipo_____ ). 5.4.1 SENTENCIA GOTO Es una instruccin bastante antigua,sencilla y muy eficiente. Es la sentencia de bifurcacion incondicional y aparece en todos los lenguajes maquina. En los lenguajes de alto nivel su uso era considerado: Bsico: porque estaba entodos los lenguajes mquina. Necesario: porque no incluian ninguna estructura de control con tanta flexibilidad. Ademas esos primeros lenguajes no incluian el concepto de mbito. A finales de los 60 y comienzos de los 70 surgi la polmica sobre si se deba utilizar la sentencia goto,puesto que el uso de la sentencia goto de manera indiscriminada hacia los programas ilegibles,poco fiables y dificiles de mantener. Todos estos problemas lleban a dos situaciones: Modula-2 no incluye la sentencia goto. Se limita el posible uso de esa sentencia. Ej: Pascal restringe el uso de la sentencia goto: las etiquetas se declaran. las etiquetas no se pasan como parametro. las etiquetas no se modifican. las etiquetas no se almacenan. la etiqueta que acompaa al goto debe ser una constante. a dnde podemos saltar con un goto? Si el goto est dentro de una sentencia de control. While

14

Begin ... ... Goto End Si el destino es una sentencia de algn grupo que contiene la secuencia de sentencias donde se incluye el goto. Begin ... 1 ... While Begin ... Goto ... End ... 2 ... End Se podra hacer un goto 1 o goto 2. While Begin ... 1 ... 15

End While Begin ... Goto ... End No se podra hacer un goto 1 El objetivo tambien puede ser una secuencia de otro subprograma incluido en el mbito del que tiene el goto. Ej: Procedure sub1 Label 100 ... Procedure sub2 ... goto 1000 ... End ... 100 End Sin embargo,si esta sentencia estubiera dentro de un while,sera incorrecto porque la sentencia destino no puede estar dentro de un conjunto de sentencias. 5.4.2 MECANISMOS DE CONTROL DE BUCLE Bucle while: Proporciona un punto de comprobacin al comienzo del bucle.

16

Bucle Repeat-Until: El punto de comprobacin est al final del bucle. El elemento de comprobacin se puede poner en cualquier punto del cuerpo del bucle,pero estas sentencias destruyen la semantica de estas instrucciones. Estas sentencias como break o exit,permiten incluso salir de varios bucles anidados. En C: Break y continue (transfiere el control a la sentencia de comprobacin del bucle). Ej: While ( suma < 100) { get(valor); if (valor<0) continue break; suma+=valor; } Si utilizamos continue volvemos a evaluar la condicion del bucle y si usamos break salimos del bucle. Tema 5: Expresiones y sentencias LPR 1 15 While () { int i,j; } Bloque (en C y Ada) While condicin do Begin End Sentencia compuesta 17

Ada: If x<0 then Y:=-x; Else Y:=x; Endif; Facilita la asociacin de los else o las clusulas then C: If (x<0) Y =-x; [else y=x;] En c se asocia el else al ultimo if que no tiene else Ada: If suma=0 then If contador=0 resultado:=0 Else resultado:=1 endif indif Pascal: If suma=0 then Resultado:=0 Else (asociado al ultimo if) Resultado:=1;

18

Pascal Case expresin of Lista_constantes_1: Sentencia 1; .......................................... Lista_constantes_n: Sentencia n; End; Switch (ndice) { Case 1: i=x; Case 3: impar+=1; Suma_impar+=indice; Break; Case 4: . . . . Switch (ndice) { Case 1: Case 3: impar+=1; Suma_impar+=indice; Break; Case 2: Case 4: par+=1; Suma_par+=indice; Break;

19

Default sentencia

20

También podría gustarte