CAPITULO 3: OPERADORES

1. INTRODUCCION
Si analizamos la sentencia siguiente:
var1 = var2 + var3;
estamos diciéndole al programa, por medio del operador +, que compute
la suma del valor de dos variables , y una vez realizado ésto asigne el resultado
a otra variable var1. Esta última operación (asignación) se indica mediante
otro operador, el signo =. El lenguaje C tiene una amplia variedad de
operadores, y todos ellos caen dentro de 6 categorias , a saber : aritméticos
, relacionales, lógicos, incremento y decremento, manejo de bits y asignacion.
Todos ellos se irán describiendo en los párrafos subsiguientes.
2. OPERADORES ARITMETICOS Tal como era de esperarse
los operadores aritméticos ,mostrados en la TABLA 4 , comprenden las cuatro
operaciones basicas , suma , resta , multiplicación y división , con un
agregado , el operador módulo .
TABLA 4 OPERADORES ARITMETICOS
SIMBOLO |
DESCRIPCION |
EJEMPLO |
ORDEN DE EVALUACION |
+ |
SUMA |
a + b |
3 |
- |
RESTA |
a - b |
3 |
* |
MULTIPLICACION |
a * b |
2 |
/ |
DIVISION |
a / b |
2 |
% |
MODULO |
a % b |
2 |
- |
SIGNO |
-a |
2 |
El operador módulo ( % ) se utiliza para calcular el resto del cociente
entre dos ENTEROS , y NO puede ser aplicado a variables del tipo float ó
double . Si bien la precedencia (orden en el que son ejecutados los operadores)
se analizará más adelante, en este capítulo, podemos adelantar algo sobre
el orden que se realizan las operaciones aritméticas.
En la TABLA 4, última columna, se da el orden de evaluación de un operador
dado. Cuanto más bajo sea dicho número mayor será su prioridad de ejecución.
Si en una operación existen varios operadores, primero se evaluarán los de
multiplicación , división y módulo y luego los de suma y resta . La precedencia
de los tres primeros es la misma , por lo que si hay varios de ellos, se
comenzará a evaluar a aquel que quede más a la izquierda . Lo mismo ocurre
con la suma y la resta .
Para evitar errores en los cálculos se pueden usar paréntesis , sin limitación
de anidamiento, los que fuerzan a realizar primero las operaciones incluidas
en ellos . Los paréntesis no disminuyen la velocidad a la que se ejecuta
el programa sino que tan sólo obligan al compilador a realizar las operaciones
en un orden dado dado, por lo que es una buena costumbre utilizarlos ampliamente
.
Los paréntesis tienen un orden de precedencia 0, es decir que antes que nada se evalúa lo que ellos encierran .
Se puede observar que no existen operadores de potenciación, radicación,
logaritmación, etc, ya que en el lenguaje C todas estas operaciones ( y muchas
otras ) se realizan por medio de llamadas a Funciones.
El último de los operadores aritméticos es el de SIGNO . No debe confundirselo
con el de resta, ya que este es un operador unitario que opera sobre una
única variable cambiando el signo de su contenido númerico. Obviamente no
existe el operador + unitario, ya que su operación sería DEJAR el signo de
la variable, lo que se consigue simplemente por omisión del signo.
3. OPERADORES RELACIONALES Todas las operaciones
relacionales dan sólo dos posibles resultados : VERDADERO ó FALSO . En el
lenguaje C, Falso queda representado por un valor entero nulo (cero) y Verdadero
por cualquier número distinto de cero En la TABLA 5 se encuentra la descripción
de los mismos .
TABLA 5 OPERADORES RELACIONALES
SIMBOLO |
DESCRIPCION |
EJEMPLO |
ORDEN DE EVALUACION |
< |
menor que |
(a < b) |
5 |
> |
mayor que |
(a >b) |
5 |
< = |
menor o igual que |
(a < = b) |
5 |
>= |
mayor o igual que |
( a >>= b ) |
5 |
= = |
igual que |
( a = = b) |
6 |
! = |
distinto que |
( a != b) |
6 |
Uno de los errores más comunes es confundir el operador relacional IGUAL
QUE (= =) con el de asignacion IGUAL A (=). La expresión a=b copia el valor
de b en a, mientras que a = = b retorna un cero , si a es distinto de b ó
un número distinto de cero si son iguales. Los operadores relacionales
tiene menor precedencia que los aritméticos , de forma que a < b + c se
interpreta como a < ( b + c ), pero aunque sea superfluo recomendamos
el uso de paréntesis a fin de aumentar la legilibilidad del texto.
Cuando se comparan dos variables tipo char el resultado de la operación dependerá
de la comparación de los valores ASCII de los caracteres contenidos en ellas.
Asi el caracter a ( ASCII 97 ) será mayor que el A (ASCII 65 ) ó que el 9
(ASCII 57).
4. OPERADORES LOGICOS
Hay tres operadores que realizan las conectividades lógicas Y (AND) , O (OR) y NEGACION (NOT) y están descriptos en la TABLA 6 .
TABLA 6 OPERADORES LOGICOS
SIMBOLO |
DESCRIPCION |
EJEMPLO |
ORDEN DE EVALUACION |
&& |
Y (AND) |
(a>b) && (c < d) |
10 |
|| |
O (OR) |
(a>b) || (c < d) |
11 |
! |
NEGACION (NOT) |
!(a>b) |
1 |
Los resultados de la operaciones lógicas siempre adoptan los valores CIERTO
ó FALSO. La evaluación de las operaciones lógicas se realiza de izquierda
a derecha y se interrumpe cuando se ha asegurado el resultado .
El operador NEGACION invierte el sentido lógico de las operaciones , así será
!( a >> b ) equivale a ( a < b )
!( a == b ) " " ( a != b )
etc.
En algunas operaciones suele usárselo de una manera que se presta a confusión
, por ejemplo : ( !i ) donde i es un entero. Esto dará un resultado CIERTO
si i tiene un valor 0 y un resultado FALSO si i es distinto de cero .
5. OPERADORES DE INCREMENTO Y DECREMENTO
Los operadores de incremento y decremento son sólo dos y están descriptos en la TABLA 7
TABLA 7 OPERADORES DE INCREMENTO Y DECREMENTO
SIMBOLO |
DESCRIPCION |
EJEMPLO |
ORDEN DE EVALUACION |
++ |
incremento |
++i ó i++ |
1 |
-- |
decremento |
--i ó i-- |
1 |
Para visualizar rapidamente la función de los operadores antedichos , digamos que las sentencias :
a = a + 1 ;
a++ ;
tienen una acción idéntica , de la misma forma que
a = a - 1 ;
a-- ;
es decir incrementa y decrementa a la variable en una unidad Si bien
estos operadores se suelen emplear con variables int , pueden ser usados
sin problemas con cualquier otro tipo de variable . Así si a es un float
de valor 1.05 , luego de hacer a++ adoptará el valor de 2.05 y de la misma
manera si b es una variable del tipo char que contiene el caracter 'C' ,
luego de hacer b-- su valor será 'B' .
Si bien las sentencias
i++ ;
++i ;
son absolutamente equivalentes, en la mayoria de los casos la ubicación
de los operadores incremento ó decremento indica CUANDO se realiza éste .
Veamos el siguiente ejemplo :
int i = 1 , j , k ;
j = i++ ;
k = ++i ;
acá j es igualado al valor de i y POSTERIORMENTE a la asignación i es
incrementado por lo que j será igual a 1 e i igual a 2 , luego de ejecutada
la sentencia . En la siguiente instrucción i se incrementa ANTES de efectuarse
la asignacion tomando el valor de 3 , él que luego es copiado en k .
6. OPERADORES DE ASIGNACION En principio puede resultar
algo futil gastar papel en describir al operador IGUAL A ( = ) , sin embargo
es necesario remarcar ciertas características del mismo .
Anteriormente definimos a una asignación como la copia del resultado de una
expresión ( rvalue ) sobre otra ( lvalue ) , esto implica que dicho lvalue
debe tener LUGAR (es decir poseer una posición de memoria ) para alojar dicho
valor .
Es por lo tanto válido escribir
a = 17 ;
pero no es aceptado , en cambio
17 = a ; /* incorrecto */
ya que la constante numérica 17 no posee una ubicación de memoria donde alojar al valor de a .
Aunque parezca un poco extraño al principio las asignaciones , al igual que
las otras operaciones , dan un resultado que puede asignarse a su vez a
otra expresión .
De la misma forma que (a + b) es evaluada y su resultado puedo copiarlo en
otra variable : c = (a + b) ; una asignación (a = b) da como resultado el
valor de b , por lo que es lícito escribir
c = ( a = b ) ;
Debido a que las asignaciones se evalúan de derecha a izquierda , los paréntesis son superfluos , y podrá escribirse entonces :
c = a = b = 17 ;
con lo que las tres variables resultarán iguales al valor de la contante .
El hecho de que estas operaciones se realicen de derecha a izquierda también permite realizar instrucciones del tipo :
a = a + 17 ;
significando esto que al valor que TENIA anteriormente a , se le suma
la constante y LUEGO se copia el resultado en la variable .
Como este último tipo de operaciones es por demás común , existe en C un pseudocódigo , con el fín de abreviarlas .
Asi una operación arítmetica o de bit cualquiera (simbolizada por OP )
a = (a) OP (b) ;
puede escribirse en forma abreviada como :
a OP= b ;
Por ejemplo
a += b ; /* equivale : a = a + b */
a -= b ; /* equivale : a = a - b */
a *= b ; /* equivale : a = a * b */
a /= b ; /* equivale : a = a / b */
a %= b ; /* equivale : a = a % b */
Nótese que el pseudooperador debe escribirse con los dos símbolos seguidos , por ejemplo += , y no será aceptado +(espacio) = .
Los operadores de asignación estan resumidos en la TABLA 8 .
TABLA 8 OPERADORES DE ASIGNACION
SIMBOLO |
DESCRIPCION |
EJEMPLO |
ORDEN DE EVALUACION |
= |
igual a |
a = b |
13 |
op= |
pseudocodigo |
a += b |
13 |
=?: |
asig.condicional |
a = (c>b)?d:e |
12 |
Vemos de la tabla anterior que aparece otro operador denominado ASIGNACION
CONDICIONAL . El significado del mismo es el siguiente :
lvalue = ( operación relacional ó logica ) ? (rvalue 1) : (rvalue 2) ;
de acuerdo al resultado de la operación condicional se asignará a lvalue
el valor de rvalue 1 ó 2 . Si aquella es CIERTA será lvalue = rvalue 1 y
si diera FALSO , lvalue = rvalue 2 .
Por ejemplo, si quisiéramos asignar a c el menor de los valores a ó b , bastará con escribir :
c = ( a < b ) ? a : b ;
7. OPERADORES DE MANEJO DE BITS Estos operadores
muestran una de las armas más potentes del lenguaje C , la de poder manipulear
INTERNAMENTE , es decir bit a bit , las variables .
Debemos anticipar que estos operadores sólo se aplican a variables del tipo
char , short , int y long y NO pueden ser usados con float ó double ,
Sabemos que las computadoras guardan los datos organizados en forma digital
, en bytes , formado por números binarios de 8 bits y como se vió anteriormente
cuando se analizó el tamaño de las variables , un char ocupará un byte de
8 bits , mientras que los short e int se forman con dos bytes ( 16 bits )
y los long por cuatro bytes ( 32 bits ).
Para el manejo de dichos bits , contamos con los operadores descriptos en la TABLA 9 .
TABLA 9 OPERADORES DE MANEJO DE BITS
SIMBOLO |
DESCRIPCION |
EJEMPLO |
ORDEN DE EVAL. |
& |
Y ó AND (bit a bit) |
a & b |
7 |
| |
O ú OR INCLUSIVA |
a | b |
9 |
^ |
O ú OR EXCLUSIVA |
a ^ b |
8 |
<< |
ROTACION A LA IZQUIER |
a << b |
4 |
>> |
ROTACION A LA DERECHA |
a >> b |
4 |
~ |
COMPLEMENTO A UNO |
~a |
1 |
Describiremos mediante unos pocos ejemplos la operatoria de manejo de bits.
Analicemos primero como funciona el operador Y, también llamado BITWISE AND
, las reglas para la operación son las dadas en la TABLA 10 .
TABLA 10 REGLAS PARA LA OPERACION Y (BITWISE AND)
bit a |
& |
bit b |
= |
bit c |
0 |
& |
0 |
= |
0 |
0 |
& |
1 |
= |
0 |
1 |
& |
0 |
= |
0 |
1 |
& |
1 |
= |
1 |
Si suponemos tener dos variables del tipo char, una de ella de valor 85
(hex. 55 ), otra de valor 71 (hex. 47) y realizamos el AND a nivel bits de
ellas, obtendremos :
bits decimal hexadecimal
0 1 0 1 0 1 0 1 85 55
& & &
0 1 0 0 0 1 1 1 71 47
------------------------- ------- -------
0 1 0 0 0 1 0 1 69 45
Nótese que la operación es del tipo lógico entre bits, por lo que los
resultados numéricos tienen poco ó ningún significado y sólo se han puesto
con el fin de ejemplificar .
De la misma manera para la operacion O INCLUSIVA, cuyas reglas se dan en la TABLA 11, será:
TABLA 11 REGLAS PARA LA OPERACION O INCLUSIVA (BITWISE OR )
bit a |
| |
bit b |
= |
bit c |
0 |
| |
0 |
= |
0 |
0 |
| |
1 |
= |
1 |
1 |
| |
0 |
= |
1 |
1 |
| |
1 |
= |
1 |
Para las mismas variables anteriores obtendremos :
0 1 0 1 0 1 1 1 87 57
Analizando ahora la O EXCLUSIVA ( ó EXOR ) tendremos :
TABLA 12 REGLAS PARA LA OPERACION O EXCLUSIVA ( EXOR )
bit a |
^ |
bit b |
= |
bit c |
0 |
^ |
0 |
= |
0 |
0 |
^ |
1 |
= |
1 |
1 |
^ |
0 |
= |
1 |
1 |
^ |
1 |
= |
0 |
Para las mismas variables anteriores obtendremos :
0 0 0 1 0 0 1 0 18 12
Veamos ahora las operaciones de desplazamiento , la sentencia
c = a << b
implica asignarle a c, el valor de a con sus bits corridos a la izquierda
en b lugares , los bits que van "saliendo" por la izquierda , se desechan
; y los bits que van quedando libres a la derecha se completan con cero .
Se procede de la misma manera para el corrimiento a la derecha >>.
El operador COMPLEMENTO A UNO es del tipo unitario , es decir que realiza
una operación sobre una única variable , y su efecto es dar a la variable
un valor igual a restar de ( -1 ) el valor que traía . Quizás es más visible
decir que este operador cambia los bits en 1 de la variable en 0 y viceversa.
TABLA 13 PRECEDENCIA DE LOS OPERADORES
PRECEDENCIA |
OPERADORES |
ASOCIATIVIDAD |
0 |
()[] -> . |
izq. a derecha |
1 |
sizeof (tipo) ! ~ ++ -- signo* & |
derecha a izq. |
2 |
* / % |
izq. a derecha |
3 |
+ - |
izq. a derecha |
4 |
> |
izq. a derecha |
5 |
>= |
izq. a derecha |
6 |
== != |
izq. a derecha |
7 |
& |
izq. a derecha |
8 |
^ |
izq. a derecha |
9 |
| |
izq. a derecha |
10 |
&& |
izq. a derecha |
11 |
|| |
izq. a derecha |
12 |
?: |
derecha a izq. |
13 |
= += -= *= etc |
derecha a izq. |
NOTA: en el renglón de los operadores de precedencia cero hemos agregado
ubicándolos a la derecha del mismo para diferenciarlos, tres operadores ,
[] ->> y . que serán analizados más adelante, de la misma manera
en el renglón siguiente hemos colocado al final a dos operadores: * y &
ya que aunque coinciden en símbolo con los de PRODUCTO y AND A NIVEL BITS,
son OTRO tipo de operadores que se describirán en capítulos sucesivos. En
ese mismo renglón se ha consignado como SIGNO al unitario (-).


© Derechos Reservados, Copyright, DATA-2013, 1998-2020.

|