• No se han encontrado resultados

JERARQUIA DE OPERADORES EN C-SHARP.

N/A
N/A
Protected

Academic year: 2022

Share "JERARQUIA DE OPERADORES EN C-SHARP."

Copied!
10
0
0

Texto completo

(1)

JERARQUIA DE OPERADORES EN C-SHARP.

Tabla de prioridades de operadores.

Lo que sigue es la lista de operadores de C, ordenados según su prioridad. En caso de que una expresión contenga más de un operador de igual prioridad, la evaluación se realizará según el orden que se indica en la columna central. Por ejemplo, si se encuentran dos operadores de desplazamiento (>> y <<), la evaluación se hará de izquierda a derecha. Pero si se encuentran dos

operadores de suma con asignación (+=), entonces la evaluación se realizará de derecha a izquierda (se evalúa primero la expresión situada más a la derecha).

Grupo de operadores Orden de

evaluación Comentarios

() [] -> . de izquierda a derecha

Este es el grupo de operadores con mayor prioridad.

! ~ ++ -- + - (tipo) * &

sizeof

de derecha a izquierda

La refundición de tipos y sizeofson operadores unarios.

* / % de izquierda

a derecha

El símbolo "%" denota el operador módulo, que produce el resto entero obtenido al dividir el primer operando por el segundo.

+ - de izquierda

a derecha

Los operadores aditivos tienen

menor prioridad que los

multiplicativos.

<< >> de izquierda a derecha

Estos son los operadores de desplazamiento bit a bit (q.v.)

< <= > >= de izquierda a derecha

== != de izquierda

a derecha

& de izquierda

a derecha

Este operador y los dos siguientes realizan operaciones lógicas bit a bit, considerando bits individuales de sus operandos.

^ de izquierda

a derecha

| de izquierda

(2)

a derecha

&& de izquierda a derecha

Este operador y el siguiente producen resultados lógicos, pero no consideran bits individuales sino el valor global del operando.

|| de izquierda

a derecha

?: de derecha a

izquierda

= += -= *= /= %= &=

^= |= <<= >>=

de derecha a izquierda

, de izquierda

a derecha

Este es el operador de menor prioridad en C. Sirve para separar una colección de expresiones, que se irán evaluando de izquierda a derecha. El resultado es el producido por la expresión situada en último lugar (más a la derecha), y tiene por tanto el tipo y valor de esta última expresión. Se emplea a veces en expresiones de control; un ejemplo sería la cláusula de iniciación de un foro la cláusula de mantenimiento de iteración de un while.

Uso de paréntesis.

Cuando el compilador genera el código que se emplea para evaluar una expresión, hace uso de la información textual de que dispone, pero no

"reconoce" la expresión, como puede hacerlo un ser humano. Las unicas reglas que se aplican son las de prioridad de operadores expuestas en la tabla

anterior. Sin embargo, C nos permite especificar sin ambigüedad el orden de evaluación deseado; esto se hace empleando paréntesis. Los paréntesis que estén anidados con más profundidad serán los primeros en evaluarse. Veáse un ejemplo.

La idea es bien sencilla: el operador paréntesis fuerza la evaluación de su contenido, elevando su prioridad con respecto a todos los demás operadores, salvo el propio operador paréntesis en el caso de que se encuentre más

profundamente anidado. Los paréntesis no estropean nada, y aseguran que el compilador entienda exactamente lo mismo que el programador. Cuando en una expresión aparecen dos o más subexpresiones entre paréntesis de igual

(3)

prioridad, se realiza la evaluación de izquierda a derecha. Véase un ejemplo.

Operador de asignación: Distinción entre = y ==.

Es muy frecuente cometer el error consistente en confundir dos operadores distintos pero de aspecto similar:

• El operador de asignación,

"="

• Y el operador de comparación,

"=="

Estos dos operadores, binarios ambos, admiten como operandos dos expresiones, y producen un resultado. Este resultado es completamente distinto:

• El operador de asignación, "=", produce como resultado el valor calculado para la expresión situada a su derecha. Por ejemplo, en valor de la expresión a = 7; es, precisamente, 7.

• Por su parte, el operador de comparación, "==", produce como resultado un valor lógico (verdadero o falso) que es verdadero si los dos operandos tienen igual valor, y falso en caso contrario. Por ejemplo,a ==

7; producirá el valor lógico verdadero (un valor numérico no nulo) si el valor de a es precisamente siete, y el valor lógico falso (un cero) si el valor de a no es siete.

Como puede apreciarse, las expresiones a = 7; y a == 7; producen resultados completamente distintos... pero existe un grave peligro. En efecto, ¿qué ocurre si se evalúa el resultado de estas expresiones desde el punto de vista lógico?

Esto es, qué resultados obtendremos si se utiliza el resultado de estas expresiones como variable de control en una sentencia if():

if( a == 7)

printf("a vale 7");

else

printf("a no vale 7);

if (a = 7)

printf("a vale 7");

else

printf("a no vale 7);

Como puede observarse, en la primera expresión el resultado será siempre correcto: a == 7 solo es no nulo si a vale 7. Pero en la segunda, el resultado de evaluar a = 7 será siempre 7. Luego pasan dos cosas:

(4)

• a siempre recibirá el valor 7, lo cual no se desea en absoluto y es un error lógico

• Además, siempre se imprimirá en pantalla "a vale 7", que puede no ser cierto; esto ocurre porque 7 es no nulo y por tanto se toma como un valor lógico verdadero.

Como decíamos, esta es una fuente de errores muy común. El compilador no puede detectarlos, porque tanto a = 7 como a == 7 son expresiones

completamente correctas. Afortunadamente, basta invertir el orden de la expresión para que el compilador detecte un error:

if( 7 == a)

printf("a vale 7");

else

printf("a no vale 7);

if (7 = a)

printf("a vale 7");

else

printf("a no vale 7);

La expresión 7 == a es válida; se tienen dos operandos para el operador de comparación. Pero la expresión 7 = a es sintácticamente incorrecta, porque 7 no es un nombre válido de variable. El compilador señala un error. Por tanto, para evitar este tipo de errores, debemos adoptar la costumbre de situar siempre las constantes a la izquierda cuando se utilice el operador "==". De este modo, si olvidamos un "=", el compilador detecta el error.

Asignaciones múltiples

Como se ha indicado, el resultado de una asignación es el valor de la expresión situada a la derecha. Esto permite escribir expresiones de la forma

a = b = c;

en donde primero se evalúa c; a continuación se asigna c a b, y por último se asigna b a a. Véase el oportuno Ejemplo.

Ejercicio.- Verificar las reglas de prioridad de operadores, empleando paréntesis para efectuar un cálculo elemental. Comprobar los resultados obtenidos tanto al emplear paréntesis como al no hacer uso de ellos.

#include <stdio.h>

void main(void) {

int cociente, a, b, c, d;

printf ("Paréntesis y prioridad de operadores\n\n");

cociente = 0;

a = 10; b = 4; c = 5; d = 1;

(5)

cociente = (a*b)/(c+d);

printf("Empleando paréntesis,cociente vale %d\n",cociente);

cociente = 0; a = 10; b = 4; c = 5; d = 1;

cociente = a*b/c+d;

printf("Sin emplear paréntesis,cociente vale %d\n",cociente);

} /*

Resultados:

Paréntesis y prioridad de operadores Empleando paréntesis,cociente vale 6 Sin emplear paréntesis,cociente vale 9

*/

Comentario.- El primer caso no tiene dificultad; los paréntesis hacen de igual prioridad los dos lados del rvalue y se evalúa la expresión de izquierda a derecha (véase el siguiente ejercicio). En el segundo caso, el operador de multiplicación y el de división tienen igual prioridad, y el operador suma tiene menor prioridad que los anteriores. Por tanto, se evalúan primero las

subexpresiones relativas a operadores de mayor prioridad. Dado que la prioridad de * y / es la misma, se evalúa de izquierda a derecha, luego se calculaa*b. Acto seguido se divide el resultado por c. Por último, a*b/c se suma con d.

Ejercicio.- Estudiar la evaluación de expresiones a igualdad de prioridades, en el caso de paréntesis. Comprobar que la evaluación se efectúa de izquierda a derecha.

#include <stdio.h>

void main(void) {

int num, cociente, a, b, c, d;

printf ("Evaluación de expresiones\n\n");

a = 10; b = 4; c = 5; d = 1; num = 0;

cociente = (num = a*b)/(num + c + d);

printf("Cociente vale %d\n", cociente);

printf("\n\nTerminación normal del programa.\n");

} /*

Salida obtenida:

Evaluación de expresiones Cociente vale 0

Terminación normal del programa.

*/

(6)

Comentario.- El resultado es 0, luego se evalúa de izquierda a derecha. Si fuera de derecha a izquierda,el denominador haría uso del valor nulo de num, y el resultado no sería cero sino 6.

Ejemplo.- Comprobar los resultados de una confusión entre el operador "=" y el operador "==".

#include <stdio.h>

void main(void) {

int a, b, c;

printf ("Confusión del operador = con el operador ==\n\n");

a = 1; b = 2; c = 3;

a = b == c;

printf("El resultado de comparar b = %d y c = %d es a = %d\n\n", b, c, a);

a = b = c;

printf("El resultado de ASIGNAR c = %d a b = %d a a es a =

%d\n\n", c, b, a);

printf("\n\nTerminación normal del programa.\n\n");

} /*

Confusión del operador = con el operador ==

El resultado de comparar b = 2 y c = 3 es a = 0 El resultado de ASIGNAR c = 3 a b = 3 a a es a = 3 Terminación normal del programa.

*/

Comentarios.- Obsérvese que 0 denota falso, y 3 denota verdadero. Por tanto, la asignación daría lugar a un valor incorrecto para a, que no sería detectado.

(7)

EJEMPLO DE ESTRUCTURA DE DATOS EN SWICHT DE C-SHARP.

switch (Referencia de C#)

La instrucción switch es una instrucción de control que selecciona una sección switch para ejecutarla desde una lista de candidatos.

Una instrucción switch incluye una o más secciones switch. Cada sección switch contiene una o más etiquetas caseseguidas de una o más instrucciones. En el ejemplo siguiente se muestra una instrucción switch simple con tres secciones switch. Cada sección switch tiene una etiqueta case, por ejemplo, case 1, y dos instrucciones.

C#

int caseSwitch = 1;

switch (caseSwitch) {

case 1:

Console.WriteLine("Case 1");

break;

case 2:

Console.WriteLine("Case 2");

break;

default:

Console.WriteLine("Default case");

break;

}

Comentarios

Cada etiqueta case especifica un valor constante. La instrucción switch transfiere el control a la sección switch cuya etiqueta case coincide con el valor de la expresión switch (caseSwitch en el ejemplo). Si ninguna etiqueta case contiene un valor coincidente, el control se transfiere a la sección default, si hay alguna. Si no hay ninguna seccióndefault, no se realiza ninguna acción y el control se transfiere fuera de la instrucción switch. En el ejemplo anterior, las instrucciones en la primera sección switch se ejecutan porque case 1 coincide con el valor de caseSwitch.

Una instrucción switch puede incluir cualquier número de secciones switch y cada sección puede tener una o más etiquetas case (como se muestra en el ejemplo

(8)

siguiente de etiquetas case de una cadena). Sin embargo, las etiquetas case pueden contener el mismo valor constante.

La ejecución de la lista de instrucciones en la sección switch seleccionada comienza con la primera instrucción y continúa a lo largo de la lista de instrucciones,

normalmente hasta que se alcance una instrucción de salto, comobreak, goto case, return o throw. En este punto, el control se transfiere fuera de la instrucción switch o a otra etiqueta case.

A diferencia de C++, C# no permite que la ejecución continúe de una sección switch a la siguiente. El código siguiente genera un error.

C#

switch (caseSwitch) {

// The following switch section causes an error.

case 1:

Console.WriteLine("Case 1...");

// Add a break or other jump statement here.

case 2:

Console.WriteLine("... and/or Case 2");

break;

}

C# requiere que el final de las secciones switch, incluida la última, sea inalcanzable. Es decir, a diferencia de otros lenguajes, el código puede no pasar explícitamente a la siguiente sección switch. Aunque este requisito se cumple normalmente mediante el uso de una instrucción break, la siguiente etiqueta case también es válida, porque asegura que no se pueda llegar al final de la lista de instrucciones.

C#

case 4:

while (true)

Console.WriteLine("Endless looping. . . .");

Ejemplo

En el ejemplo siguiente se muestran los requisitos y las capacidades de una instrucción switch.

C#

class Program {

static void Main(string[] args) {

int switchExpression = 3;

switch (switchExpression) {

// A switch section can have more than one case label.

case 0:

case 1:

Console.WriteLine("Case 0 or 1");

// Most switch sections contain a jump statement, such as

(9)

// a break, goto, or return. The end of the statement list

// must be unreachable.

break;

case 2:

Console.WriteLine("Case 2");

break;

// The following line causes a warning.

Console.WriteLine("Unreachable code");

// 7 - 4 in the following line evaluates to 3.

case 7 - 4:

Console.WriteLine("Case 3");

break;

// If the value of switchExpression is not 0, 1, 2, or 3, the // default case is executed.

default:

Console.WriteLine("Default case (optional)");

// You cannot "fall through" any switch section, including

// the last one.

break;

} } }

En el último ejemplo, la variable de cadena, str, y las etiquetas case de la cadena controlan el flujo de ejecución.

C#

class SwitchTest {

static void Main() {

Console.WriteLine("Coffee sizes: 1=small 2=medium 3=large");

Console.Write("Please enter your selection: ");

string str = Console.ReadLine();

int cost = 0;

// Notice the goto statements in cases 2 and 3. The base cost of 25

// cents is added to the additional cost for the medium and large sizes.

switch (str) {

case "1":

case "small":

cost += 25;

(10)

break;

case "2":

case "medium":

cost += 25;

goto case "1";

case "3":

case "large":

cost += 50;

goto case "1";

default:

Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");

break;

}

if (cost != 0) {

Console.WriteLine("Please insert {0} cents.", cost);

}

Console.WriteLine("Thank you for your business.");

} } /*

Sample Input: 2

Sample Output:

Coffee sizes: 1=small 2=medium 3=large Please enter your selection: 2

Please insert 50 cents.

Thank you for your business.

*/

OTRO EJEMPLO.

60 - Estructura condicional switch

La estructura condicional switch remplaza en algunos casos un conjunto de if.

La estructura del switch:

switch(variable) { case valor1:

Referencias

Documento similar

1. d) La instrucción ____________ dentro de una función se utiliza para pasar el valor de una expresión hacia la función que la invoca. e) La palabra reservada __________

Si después de la calibración, el valor obtenido en el laboratorio no coincide con el valor del display con una diferencia constante (ejemplo: a valores de la pantalla de 75.4,

• Los valores de cada case (caso) del switch pueden ser resultado de una expresión, en ese caso debe estar formada por ctes, por lo tanto no se puede utilizar nombres de variables. •

Por ejemplo, Case Is &lt;= 14 indicaría que si la expresión evaluada tiene un valor menor o igual a 14 se ejecutarán las instrucciones anexas.. Cuando varios casos son válidos, sólo

Cada bloque case se deberá separar del siguiente con una línea en blanco cuando englobe muchas líneas de código. Ejemplo: Uso de switch

• El bloque SELECT CASE ejecuta un bloque determinado de sentencias cuando el valor de la expresión caso coincide o pertenece al rango dado de su correspondiente selector de

Si el valor de selector es igual a una de las etiquetas case, por ejemplo, etiqueta i , entonces la ejecución comenzará con la primera sentencia de la secuencia