Operadores lógicos
Los operadores && , || y ! relacionan expresiones lógicas, dando como salida a su vez nuevas expresiones lógicas. Sintaxis:
<expresión1> && <expresión2>
<expresión1> || <expresión2>
!<expresión> |
El operador "&&" equivale al "AND" o "Y"; devuelve true sólo si los dos operandos true o lo que es equivalente, distintas de cero. En cualquier otro caso el resultado es false.
El operador "||" equivale al "OR" u "O inclusivo"; devuelve true si cualquiera de las expresiones evaluadas es true, o distinta de cero, en caso contrario devuelve false.
El operador "!" es equivalente al "NOT", o "NO", y devuelve true cuando la expresión evaluada es false o cero, en caso contrario devuelve false.
Cortocircuito
Existe una regla que en muchas ocasiones nos puede resultar útil, ya que nos puede ahorrar tiempo y comprobaciones adicionales.
Esta regla se conoce como "cortocircuito" o "shortcut", y se aplica de forma diferente a expresiones AND y OR.
En el caso de operaciones AND, consiste en que si la primera expresión evaluada es false, la segunda si siquiera se evalúa, ya que el resultado será siempre false independientemente del valor del segundo operando.
En el caso de operaciones OR, si la primera expresión sea true, la segunda no se evalúa, ya que el resultado será siempre true, independientemente del valor de la segunda expresión.
Esto es porque en una operación && el resultado sólo puede ser true cuando los dos operandos sean true, y en una operación || el resultado sólo puede ser false si ambos operandos son false. En el momento en que en una expresión AND uno de los operandos sea false, o que en una expresión OR uno de los operandos sea true, el valor del otro operando es irrelevante.
Si tenemos en cuenta este comportamiento, podremos ahorrar tiempo de ejecución si colocamos en primer lugar la expresión más fácil de calcular, o aquella cuyo valor sea más probablemente false en el caso de una expresión AND o true, para una expresión OR.
También habrá casos en que una de las expresiones sea indeterminada cuando la otra sea false en una expresión AND, o true en una expresión OR. En ese caso, será preferible colocar la expresión potencialmente indeterminada en el segundo lugar.
Tablas de verdad
Una tabla de verdad es una relación de todos los posibles valores para los operandos que intervienen en una operación, y los resultados para cada caso.
En el caso de operadores lógicos podemos mostrar fácilmente tablas de verdad, ya que el dominio para cada operando es muy reducido: true o false. Si además tenemos en cuenta la regla del cortocircuito, los casos posibles se reducen todavía más.
A continuación se muestra la tabla de verdad del operador &&:
Expresión1 | Expresión2 | Expresión1 && Expresión2 |
false | ignorada | false |
true | false | false |
true | true | true |
La tabla de verdad para el operador || es:
Expresión1 | Expresión2 | Expresión1 || Expresión2 |
false | false | false |
false | true | true |
true | ignorada | true |
La tabla de verdad para el operador ! es:
Expresión | !Expresión |
false | true |
true | false |
Expresiones lógicas frecuentes
A menudo aprovechamos ciertas equivalencias entre enteros y valores lógicos para comprobar algunos valores especiales en comparaciones usadas en condiciones o bucles.
Concretamente, me refiero a las comparaciones con cero. Así, si queremos saber si un valor entero E, es distinto de cero, lo comparamos usando el operador !=: 0!=E.
Pero existe una correspondencia entre todos los valores enteros y los valores booleanos, y esa correspondencia es muy simple: un valor entero nulo equivale a false, cualquier valor entero distinto de cero, equivale a true.
Teniendo esto en cuenta, la comparación anterior es inncecesaria, ya que 0!=E es equivalente a usar, sencillamente E.
La condición contraria, 0==E, es por lo tanto equivalente a lo contrario, es decir, a la expresión !E.
Será pues, muy frecuente, que encuentres este tipo de operadores lógicos aplicados a enteros en condiciones:
if(!E) {...} // Si E es cero, hacer ...
if(E) {...} // Si E no es cero, hacer... |
Operador "sizeof"
Este operador tiene dos usos diferentes.
Sintaxis:
sizeof (<expresión>)
sizeof (nombre_de_tipo) |
En ambos casos el resultado es una constante entera que da el tamaño en bytes del espacio de memoria usada por el operando, que es determinado por su tipo. El espacio reservado por cada tipo depende de la plataforma.
En el primer caso, el tipo del operando es determinado sin evaluar la expresión, y por lo tanto sin efectos secundarios. Si el operando es de tipo char, el resultado es 1.
A pesar de su apariencia, sizeof() NO es una función, sino un OPERADOR.
Asociación de operadores binarios
Cuando decimos que un operador es binario no quiere decir que sólo se pueda usar con dos operandos, sino que afecta a dos operandos. Por ejemplo, la línea:
A = 1 + 2 + 3 - 4; |
Es perfectamente legal, pero la operación se evaluará tomando los operandos dos a dos y empezando por la izquierda, y el resultado será 2. Además hay que mencionar el hecho de que los operadores tienen diferentes pesos, es decir, se aplican unos antes que otros, al igual que hacemos nosotros, por ejemplo:
A = 4 + 4 / 4; |
Dará como resultado 5 y no 2, ya que la operación de división tiene prioridad sobre la suma. Esta propiedad de los operadores es conocida como precedencia. En el capítulo de operadores II se verán las precedencias de cada operador, y cómo se aplican y se eluden estas precedencias.
Del mismo modo, el operador de asignación también se puede asociar:
A = B = C = D = 0; |
Este tipo de expresiones es muy frecuente en C++ para asignar el mismo valor a varias variables, en este caso, todas las variables: A, B, C y D recibirán el valor 0.
Generalización de cortocircuitos
Generalizando, con expresiones AND con más de dos operandos, la primera expresión false interrumpe el proceso e impide que se continúe la evaluación del resto de las operaciones.
De forma análoga, con expresiones OR con más de dos operandos, la primera expresión true interrumpe el proceso e impide que se continúe la evaluación del resto de las operaciones.
Palabras reservadas usadas en este capítulo
sizeof.
Comentarios