domingo, 1 de junio de 2014

Operadores y Expresiones

Introducción
Los programas de computadoras se apoyan esencialmente en la realización de numerosas operaciones aritméticas y matemáticas de diferente complejidad[1]. Los operadores más fundamentales que estaremos viendo serán:
ü Aritméticos, lógicos y relacionales
ü De manipulación de bits
ü Condicionales
ü Especiales
Antes de iniciar con este tema, debemos tener claro dos significados principales que son operador y operando. El primero es aquel que realiza una acción sobre uno o más datos; mientras que el segundo es sobre lo que opera el operador (los datos).
El primero operador del que vamos a hablar y uno de los más importantes, usado en casi todos los programas o en su mayoría es el operador de asignación.

Operador de ASIGNACIÓN

El operador de asignación se lo representa con el “=”, en donde, se asigna el valor de la expresión que se encuentra en la derecha a la variable situada a la izquierda del =. Por ejemplo:
nombre = ‘Luis’;
edad = 23;
El símbolo de = es asociativo por la derecha, esto quiere decir que permite realizar asignaciones múltiples. Por ejemplo
a= b = c = 45;
Lo anterior equivale a decir:
a = (b = (c = 45));
Dicho con otras palabras, esto quiere decir que a las variables a, b, y c se les asigna el valor de 45.
Además del operador de asignación (=), el lenguaje C proporciona cinco operadores de asignación adicionales como se puede ver a continuación:
Operador
Sentencia abreviada
Descripción
Equivalencia
=
*=

/=

%=
+=
–=
a = b
a *= b

a /= b

a %= b
a += b
a –= b
Asigna el valor de b a la variable a.
Multiplica a por b y asigna el resultado a la variable a.
Divide a entre b y asigna el resultado a la variable a.
Fija a al resto de a/b.
Suma b y a y asigna el resultado a la variable a.
Resta b de a y asigna el resultado a la variable a.

a = a * b;

a = a / b;

a = a % b;
a = a + b;
a = a – b;

Operadores Aritméticos

Los operadores aritméticos nos sirven para realizar operaciones aritméticas básicas, con la siguiente tabla podemos observar los operadores aritméticos que se utilizan en C:
Operador
Acción
+
-
*
/
%
++
– –
Suma
Resta
Multiplicación
División entera: cociente
División entera: residuo
Incremento
Decremento

Basándonos en la tabla anterior; los operadores correspondientes a la suma, resta y multiplicación se operan tal y cual lo hacemos en álgebra (los 3 primeros operadores) mientras que los 4 operadores restantes funcionan de distinta manera que a continuación se explicarán.
Ø División entera: cociente y residuo
Debemos tomar en cuenta que cuando nosotros realizamos una operación de división en algebra, obtenemos dos resultados, los cuales son el cociente y el residuo. En C podemos obtener ambos resultados con dos operadores, con el operador “ / ” obtenemos el cociente de la división; y mientras que con el operador “ % “ tendremos el residuo de la operación. Veamos un ejemplo un poco completo: si realizamos una operación de división la cual será: 13/5, y el resultado lo almacenamos en una variable de tipo int el resultado que veremos será el 2; pero si deseamos el resultado completo de la operación lo almacenamos en una variable tipo float en donde tendremos 2,6 como resultado.
Pero al utilizar el operador / solo obtenemos uno de los resultados que solemos tener en una división algebraica (el cual es el cociente). Para obtener el residuo utilizamos el operador % y el resultado de 13%5 será 3, con la siguiente imagen podremos comprender un poco mejor el uso de estos operadores:

Ø Incremento y decremento
Estos operadores de incremento y decremento (++ y --), son una de las características que incorpora C; la función de esto es sumar o restar 1 a su argumento cada vez que se aplican a una variable. Por ejemplo:
a++;
b--;
Es igual a decir:
a = a + 1;
b = b – 1;
Para la utilización de estos operadores debemos considerar que existen 2 tipos: prefijo y sufijo.
Prefijo; se da cuando el operador (++ o --) aparece antes del operando. Con esto, C primero realiza la operación y luego procede a realizar el proceso de asignación, por ejemplo:
x = 10;
y = ++x;
El resultado de lo anterior tendremos que en y se asigna el valor de 11.
Sufijo; este en cambio se da cuando el operador aparece después del operando. Quiere decir que primero utiliza el valor antes de realizar el incremento o decremento, por ejemplo:
x = 10;
y = x--;
Aquí, vamos a tener que en y se asigna el valor de 10, puesto que primero asigna el valor de la variable x (10), y posterior a eso en x se realiza la operación de decremento.

Operadores Relacionales

En C los operadores relaciones nos sirven para realizar comparaciones entre valore del mismo tipo, como enteros, punto flotante y caracteres. La siguiente tabla nos muestra los operadores relacionales en C:
Operador
Significado
Ejemplo
==
!=
> 
>=
< 
<=
Igual a
Distinto a
Mayor que
Mayor o igual que
Menor que
Menor o igual que
a == b
a != b
a > b
a >= b
a < b
a <= b

En C se representa a verdadero con cualquier valor distinto a 0, mientras que a falso se lo representa con el valor 0.
Cuando se comparan los caracteres, se utiliza los códigos numéricos del código ASCII, por ejemplo ‘a’ es distinto que ‘A’.

Operadores Lógicos

Además de los operadores matemáticos, C tiene también operadores lógicos. Estos operadores se utilizan con expresiones para devolver un valor verdadero o falso. A estos tipos de operadores también se los denominan como operadores booleanos (en honor a George Boole).
En C encontramos 3 operadores los cuales son: not o no (!), and o y (&&), or o o (||). A continuación podemos observar las tablas de verdad de los operadores:
p
Q
p  &&  q
p  ||  q
!p
0
0
1
1
0
1
0
1
0
0
0
1
0
1
1
1
1
1
0
0

Operadores de Manipulación de BITS

Los operadores de manipulación de bits ejecutan operaciones booleanas sobre cada uno de los bits de los operandos. Cada operador de manipulación de bits realiza una operación lógica bit a bit sobre los datos internos.
Las operaciones a nivel de bits no se las puede realizar sobre los siguientes tipos de datos: float, double, long double y void. Como los operadores a nivel de bits tenemos los siguientes:
Operador
Acción
&
|
^
~
>> 
<< 
AND
OR
OR exclusiva (XOR)
Complemento a 1 (NOT)
Desplazamiento de bits a la derecha
Desplazamiento de bits a la izquierda

Ø Operadores de asignación adicionales
De igual manera como pudimos ver con los operadores aritméticos, los operadores de asignación abreviados también están disponibles en estos operadores de manipulación de bits, con la siguiente tabla podemos entender de mejor manera:
Símbolo
Uso
Descripción
<<=
>>=
&=
^=
|=
a <<= b
a >>= b
a &= b
a ^= b
a |= b
Desplaza a a la izquieda b bits y asigna el resultado a a
Desplaza a a la derecha b bits y asigna el resultado a a
Asigna a a el valor a&b
Establece a a a^b
Establece a a a|b

Ø Operadores de desplazamiento de bits (<<, >>)
Equivale a la instrucción SHR y SHL. Este operador nos permite desplazar a la derecha (>>) o a la izquierda (<<) n posiciones de los bits del operando, por ejemplo:
int num = 25;         // 00011001 - Binario
int desp;
desp = num << 3;      // 11001000 - Binario

Ø Operadores de dirección
Son operadores que permiten manipular las direcciones de las variables y registros en general.
Operador
Acción
*
Lee o modifica el valor apuntado por la expresión. Se corresponde con un puntero y el resultado es el tipo apuntado.
&
Devuelve un puntero al objeto utilizado como operando, que debe ser un lvalue (variable dotada de una dirección de memoria). El resultado es un puntero de tipo idéntico al del operando.
.
Permite acceder a un miembro de un dato agregado (unión, estructura)
->
Accede a un miembro de un dato agregado (unión, estructura) apuntado por el operando de la izquierda.

Es importante recalcar la diferencia entre usar los operadores lógicos y a nivel de bits, && y &, || y |. Ambos operadores vienen a tener las mismas tablas de verdad, la diferencia está en que el primer operador (&& o ||) nos puede dar el resultado evaluando solo el primer operando, mientras que el segundo operador (& o |) evalúa ambos elementos de la expresión. Por ejemplo, suponiendo que tenemos a=0 y b=1:
a && b à evalúa solamente el valor de a que es 0 y automáticamente ya puede obtener el resultado (0)
a & b à evalúa en cambio ambos elementos, y posteriormente nos da el resultado (0)

Operador Condicional

El operador condicional, “?:, abrevia la sentencia de control if-else. Es un operador ternario que devuelve un resultado cuyo valor depende de la condición aprobada. El formato de este operador es el siguiente:
expresion_1 ? expresion_2 : expresion_3;
A continuación se mostrará un ejemplo:
(edad >= 21) ? cerveza = cantidad : cerveza = 0;
Para el ejemplo anterior, si el valor de edad es mayor o igual que 21, pues en la variable cerveza se asigna el valor de la variable cantidad, mientras que si edad es menor a 21, cerveza toma el valor de 0.

Operadores Especiales

Ø Operador ()
Este es el operador de llamada de funciones, los utilizamos para encerrar los argumentos de una función, o en otras palabras, para poner los parámetros que recibe una función. En los operadores aritméticos, se toma en cuenta a los () para la procedencia del cálculo de la expresión.
Ø Operador []
Este operador lo utilizamos para dimensionar los array y designar un elemento en un array.
Ø Operador sizeof
Utilizamos este operador para conocer la longitud en bytes de una variable. Con frecuencia algunos programas necesitan conocer el tamaño de un tipo de dato o variable. el formato del operador es:
sizeof( nombre_variable o tipo_dato o expresion );
Ø Operador coma (,)
Este operador nos permite combinar dos o más expresiones separadas por comas en una sola línea. Se evalúa primero la expresión de la izquierda y luego las restantes expresiones de izquierda a derecha.

Precedencia de Operadores

Descripción
Operadores
----------
Unarios
Multiplicativos
Aditivos
Desplazamiento
Relación
Relación
AND sobre bits
XOR sobre bits
OR sobre bits
AND lógico
OR lógico
Condicional
Asignación y abr.
Coma
() [] -> .
¡ ~ ++ -- (tipo) * & sizeof
* / %
+ -
<< >>
< <= > >=
== !=
&
^
|
&&
||
?:
= += -= *= /= %=
,

Evaluación de Expresiones

Una expresión está constituida por la combinación de operandos y operadores de acuerdo a la sintaxis correspondiente, y además una expresión siempre tiene un valor. La evaluación de las expresiones se realiza de acuerdo a la precedencia preestablecida. Por ejemplo:


Conversiones de Tipos

En la programación con mucha frecuencia se necesita convertir un valor de un tipo a otro sin cambiar el valor que representa. Estas conversiones pueden ser implícitas (se ejecutan automáticamente) o explícitas (quiere decir que son especificadas por el programador)
Ø Conversión implícita
En este tipo de conversiones los tipos fundamentales pueden ser mezclados libremente en asignaciones y expresiones. Ejemplo>
int i = 12;
double x = 4;
x = x + i;  // valor de i se convierte en double antes
// de la suma.
x = i / 5;  // primero hace la división entera i/5==2,
// 2 se convierte a tipo doble: 2.0
// y se asigna a x */
x = 4.0;
x = x / 5;  // convierte 5 a tipo double,
// hace una división real: 0.8
// y se asigna a x
Ø Conversión explícita
C fuerza la conversión explícita de tipos mediante el operador molde (cast). Ejemplo:
(float) i;            // convierte i a float
(int) 3.4;            // convierte 3.4 a entero, 3
(int*) malloc (2*16); // convierte el valor devuelto por
// malloc: void* a int*
// Es una conversión de punteros

Bibliografía y Net-grafía:

Evelio Granizo Montalvo. (1999). Lenguaje C Teoría y Ejercicios. Quito: Editorial ESPE.
Luis Joyanes Aguilar, Ignacio Zahonero Martinez. (1999). PROGRAMCACIÓN EN C. Metodología, algoritmo y estructura de datos. Madrid: Editorial McGraw-Hill.





[1] (Luis Joyanes Aguilar, Ignacio Zahonero Martinez, 1999) [pág. 115]

No hay comentarios:

Publicar un comentario