Tabla de fichas Indice del Tema 0005
0001 0002 0003 0004 0005 0006 0007 0008

OPERADORES







Defición de operador.
De poco serviría almacenar información en variables si no fuera posible procesar esa información. El procesamiento, claro está, consiste en ejecutar instrucciones propias del procesador. En un lenguaje de alto nivel, las instrucciones se denotan mediante operadores (+, -, * etc.); de hecho, los operadores de un lenguaje de alto nivel se utilizan formando expresiones. Una expresión, en un lenguaje de alto nivel, es muy parecida a una expresión matemática:
float largo = 2.0;
float ancho = 3.0;
float superficie;

superficie = largo * ancho; /* Aquí hay dos expresiones */

Una expresión es una combinación de variables y operadores que define de forma no ambigua el resultado que se pretende calcular (esto es, se trata de una indicación que dice al compilador qué colección de instrucciones debe generar para que, al ser ejecutadas, calculen el resultado buscado por la expresión). Las expresiones, traducidas por el compilador, y ejecutadas por el procesador, producen resultados que luego se almacenará en variables.

Las informaciones que sirven como datos para la operación reciben el nombre de operandos. En el ejemplo anterior, los operandos del operador multiplicación (*) eran las variables largo y ancho. Por otra parte, el resultado de la expresión largo*ancho servía como operando para el operador de asignación (=).

Como nota adicional, conviene indicar que los operadores de los lenguajes de programación están definidos dentro del propio lenguaje; esto es, no es preciso definir su comportamiento. En algunos lenguajes, notablemente en C++, es posible redefinir el comportamiento de los operadores, de modo que éste se adapte a nuevos tipos. Esto hace posible, por ejemplo, redefinir (sobrecargar, en la jerga local) el operador + para que, al darle como operandos dos matrices adecuadas, produzca como resultado la matriz suma de ambas.

Taxonomía por número de operandos: operadores unarios y binarios.
Una posible forma de clasificar los operadores es la que atiende al número de operandos que admiten. Los operadores unarios admiten un único argumento, y entre ellos se cuenta el operador de cambio de signo (-) y los operadores de incremento y decremento (++ y --). Los operadores binarios, que son los más comunes, se caracterizan por admitir dos operandos, y entre ellos se cuentan los operadores aritméticos habituales (+, -, *, /). El uso de operadores puede asemejarse a las llamadas a funciones; se ve entonces la posibilidad de que existan operadores ternarios, cuaternarios etc. dependiendo del número de argumentos que admita la función. Este hecho resulta de especial interés en C++.

Taxonomía por tipo de operandos: operadores Aritméticos, Lógicos y Relacionales. Operador de Asignación.
Otra posible clasificación de los operadores es la debida al tipo de argumentos que admiten. Según este esquema de clasificación, podremos hablar de varios tipos de operadores:



Operadores aritméticos

Nombre Símbolo
Multiplicación *
División /
Módulo %
Suma +
Resta -

Esta tabla muestra los símbolos de los operadores aritméticos, junto con su cometido. Estos operadores permiten escribir expresiones cuya evaluación es precisamente el tratamiento de información que efectúa el ordenador. Los operadores aritméticos, junto con una amplia gama de funciones residentes en la biblioteca del lenguaje empleado, hacen posible realizar cálculos de todo tipo. La flexibilidad de los lenguajes de programación a efectos de cálculo queda patente en la conocida referencia "Numerical Recipes". Como curiosidad, el lector podría acceder a un buscador de Internet y solicitar información empleando como clave las palabras "Numerical Methods".





Operadores lógicos
Nombre Símbolo
Conjunción lógica
(AND)
&&
Disyunción lógica
(OR)
||
Negación lógica (NOT)!

Sirven para calcular el valor de expresiones lógicas, esto es, de expresiones en que los únicos valores que pueden tomar los operandos son Verdadero o Falso. Existen dos versiones de estos operadores. Cuando se desea simplemente saber si una expresión es verdadera o falsa (por ejemplo, x>7), se emplean operadores lógicos. Estos operadores no consideran la estructura de bits, limitándose a tomar el valor 0 como falso y cualquier otro como verdadero. Existe también otra versión (los operadores de bits) que imponen las operaciones lógicas a los bits empleados para representar internamente a los operandos. Se trata de los operadores &, | y ~, respectivamente.


Operadores relacionales
Nombre Símbolo
menor <
menor o igual<=
mayor>
mayor o igual>=
distinto!=
igual==

El concepto de comparación implica ciertamente distintos significados en función del tipo de datos de las variables comparadas. Los operadores presentados en esta tabla son adecuados para comparar valores numéricos u ordinales (caracteres individuales o valores enumerados), pero no para comparar cadenas o listas de cualquier tipo. La comparación de cadenas exige utilizar funciones creadas específicamente con este fin, como strcmp(). Véase aquí una descripción de las funciones de comparación de cadenas que ofrece C. Téngase en cuenta también que estas funciones no tratan correctamente los signos diacríticos; será preciso recurrir a otros métodos para comparar correctamente cadenas en idiomas que los contengan.






Operadores de bits y de desplazamiento
Nombre Símbolo
Conjunción
(AND)
&
Disyunción
(OR)
|
Negación o complemento a unos (NOT)~
Desplazamiento a la izquierda
(Multiplicación por 2)
<<
Desplazamiento a la derecha
(División por 2)
>>

Una computadora es un dispositivo lógico programable, según se ha indicado. Por tanto, ofrece herramientas adecuadas para la manipulación de bits, que son a fin de cuentas el método de representación de su información. En este sentido, existen operadores que aplican las leyes lógicas habituales (AND, OR, NOT, etc.) a las representaciones internas de sus operandos. Esto hace posible crear máscaras adecuadas para extraer información relativa a fragmentos concretos de la representación interna de esos operandos. Por otra parte, existen métodos sumamente rápidos para realizar operaciones de multiplicación o división por dos. Si todos los bits de un número escrito en binario se desplazan hacia la izquierda una posición, el resultado equivale a multiplicar por 2; si el desplazamiento es de una posición a la derecha, esto equivale a dividir por 2. Los operadores de desplazamiento permiten realizar, precisamente, este tipo de operaciones.

El operador de asignación
La asignación es una operación consistente en calcular el valor de una expresión y copiar ese valor en algún lugar, que se indicará en la propia expresión de asignación. Las sentencias de asignación son de la forma

destino operador_de_asignación expresión

y un ejemplo podría ser

x = 7

En una sentencia de asignación, destino especifica la zona de memoria que recibirá el valor y expresión es cualquier expresión válida en el lenguaje considerado. El mecanismo de funcionamiento de las sentencias de asignación tiene tres paso: Las sentencias de asignación son terreno abonado para incurrir en errores relacionados con la compatibilidad de tipos. Es muy sencillo, por ejemplo, intentar asignar el valor de una cadena a un entero, o viceversa. Este tipo de errores será detectado por el compilador, pero existen errores más sutiles, que no se detectan en el proceso de compilación. Tal sería el caso, por ejemplo, de posibles errores lógicos debidos a una refundición de tipos sin sentido.

ADVERTENCIA.- Es frecuente que los lenguajes de programación ofrezcan un operador de comparación de igualdad cuyo símbolo sea similar al símbolo del operador de asignación. En el caso de C, el operador de comparación de igualdad son dos signos de igual seguidos ("=="), y el operador de asignación es un solo signo de igual ("="). Su confusión suele ser indetectable por parte del compilador, y dará lugar a resultados inexplicables e incorrectos. ¡No los confunda!

Expresiones. Concepto de prioridad de operadores.
Una expresión, como se ha indicado, es una combinación de operadores y operandos. En particular, cualquier variable individual es una expresión: el valor de esa expresión, claro está, será el valor de la variable. Todos los operadores poseen una "sintaxis", esto es, un cierto orden en el que deben escribirse los operandos y el símbolo del operador. Por ejemplo, para denotar la suma de dos números lo normal es escribir

a + b

En este caso, la sintaxis del operador exige escribir primero un operando, después el símbolo del operador, y por último el segundo operando. Evidentemente, esta expresión produciría un resultado, pero ese resultado se perdería al no haber sido asignado a una variable. Consiguientemente, es frecuente encontrar expresiones de la forma

c = a + b

en que aparecen dos operadores: el de asignación ("=") y el de adición ("+"). Evidentemente, se pueden crear expresiones mucho más complejas, en las que aparecerá un elevado número de operandos y operadores; de hecho lo normal es que se utilice el resultado de ciertas expresiones como operando para otras. Considérese por ejemplo

d = (a + b) / c

Esta expresión contiene una subexpresión, (a + b), que será preciso evaluar antes de efectuar la división, para por último realizar la asignación. Se observa que el orden de evaluación de expresiones es totalmente crucial para obtener un resultado correcto. Será preciso entonces indicar al compilador lo que debe hacer. Considérese la expresión
d = a + b / c

El compilador va a interpretarla en la forma d = a + (b/c), que probablemente no sea lo que deseaba el usuario. Sin embargo, la expresión anterior, d= (a + b) / c, se evaluará correctamente, porque el compilador entiende que las expresiones encerradas entre paréntesis tienen prioridad con respecto a las que no están encerradas entre paréntesis (deben evaluarse antes). Cuando dos expresiones están igualmente rodeadas por paréntesis, como en el caso d = (a + b) / (c + f) el compilador efectúa la evaluación de izquierda a derecha.

Existen algunas reglas más, que será preciso estudiar para cada lenguaje de programación. Sin embargo, basta emplear las reglas matemáticas habituales (y los paréntesis correspondientes) para estar seguro de que el compilador interpretará las expresiones tal como desea el usuario. En ausencia de paréntesis, se siguen unas reglas (propias de cada lenguaje) que indican cuales son los operadores (y por tanto las expresiones) que se evaluarán en primer lugar.

La tabla de prioridades de los operadores del lenguaje C, mostrados desde la prioridad más alta hasta la más baja, es como sigue:

Operadores Comentarios
() [] -> . Las expresiones más anidadas construidas con estos operadores son las de mayor prioridad.
! ~ ++ -- - (tipo) * & sizeof , Todos estos operadores son unarios.
* / % Multiplicación, división y módulo.
+ - Suma y resta.
<< >> Operadores de desplazamiento de bits.
< <= > >= Operadores de comparación numérica.
== != Operadores de comparación de igualdad y desigualdad.
& Conjunción lógica bit a bit (AND).
^ Disyunción lógica excluyente bit a bit (XOR).
| Disyunción lógica bit a bit (OR).
&& Conjunción lógica.
|| Disyunción lógica.
?: Operador condicional.
= *= /= %= += -= <<= >>= &= ^= |= Operadores de asignación; son los de menor prioridad,para asegurar que la expresión esté completamente evaluada antes de almacenar su resultado.

Se hallará información más detallada en el Tema 3.