Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


4.9.8  Operadores lógicos

§1  Sinopsis

Los operadores lógicos producen un resultado booleano, ( 3.2.1b), y sus operandos son también valores lógicos o asimilables a ellos (los valores numéricos son asimilados a cierto o falso según su valor sea cero o distinto de cero). Por contra, recuerde que las operaciones entre bits ( 4.9.3) producen valores arbitrarios.

Los operadores lógicos son tres; dos de ellos son binarios, el último (negación) es unario. Tienen una doble posibilidad de representación en el Estándar C++ actual: la representación tradicional que se indica a continuación, y la natural introducida recientemente que se detalla más adelante .

  • Y lógico  &&             AND 

  • O lógico  ||                OR  

  • Negación lógica  !   NOT

Las expresiones conectadas con los operadores && y || se evalúan de izquierda a derecha, y la evaluación se detiene tan pronto como el resultado verdadero o falso es conocido (muchos programas tienen una lógica que se basa en este propiedad).

§2   &&    Operador Y lógico

También denominado por su nombre en inglés (generalmente en mayúsculas) AND lógico. Devuelve un valor lógico true si ambos operandos son ciertos. En caso contrario el resultado es false.

Sintaxis

expr-AND-logica && expresion-OR-inclusive

Comentario:

La operatoria es como sigue: El primer operando (de la izquierda) es convertido a bool. Para ello, si es una expresión, se evalúa para obtener el resultado (esta computación puede tener ciertos efectos laterales). A continuación, el valor obtenido es convertido a bool cierto/falso siguiendo las reglas de conversión estándar ( 3.2.1b). Si el resultado es false, el proceso se detiene y este es el resultado, sin que en este caso sea necesario evaluar la expresión de la derecha (recuérdese que en el diseño de C++ prima la velocidad).

Si el resultado del operando izquierdo es cierto, se continúa con la evaluación de la expresión de la derecha, que también es convertida a bool. Si el nuevo resultado es true, entonces el resultado del operador es true. En caso contrario el resultado es false.

Nota: la Norma informa que antes de ser evaluada la expresión derecha, han sucedido todos los posibles efectos laterales de la expresión izquierda, a excepción de la destrucción de los posibles objetos temporales que se hubiesen creado.

Ejemplo:

int m[3] = {0,1,2};
int x = 0;
if (m && x) cout << "Cierto.";
else cout << "Falso.";

Salida:

Falso.

El valor m, que es interpretado como un puntero al primer elemento de la matriz, es transformado a un bool. Como es distinto de cero (no es un puntero nulo) el resultado es cierto. A continuación, el valor x es convertido también a bool. En este caso la conversión produce falso, con lo que este es el resultado del paréntesis de la sentencia if.

Ejemplo

#include <iostream.h>

bool alto = true, bajo = false, blanco = true, negro = false;

int main (void) {
  if (alto && bajo) { cout << "Uno cierto" << endl; }
  else cout << "Uno falso" << endl;
  if (alto && blanco) { cout << "Dos cierto" << endl; }
  else cout << "Dos falso" << endl;
  if (bajo && negro) { cout << "Tres cierto" << endl; }
  else cout << "Tres falso" << endl;
}

Salida:

Uno falso
Dos cierto
Tres falso

§3   ||    Operador O lógico

Este operador binario devuelve true si alguno de los operandos es cierto.  En caso contrario devuelve false.

Sintaxis

expr-OR-logica || expresion-AND-logica

Comentario

Este operador sigue un funcionamiento análogo al anterior. El primer operando (izquierdo) es convertido a bool. Para ello, si es una expresión, se evalúa para obtener el resultado (esta computación puede tener ciertos efectos laterales). A continuación el valor obtenido es convertido a bool cierto/falso siguiendo las reglas de conversión estándar ( 3.2.1b). Si el resultado es true, el proceso se detiene y este es el resultado, sin que en este caso sea necesario evaluar la expresión de la derecha (recuérdese que en el diseño de C++ prima la velocidad).

Si el resultado del operando izquierdo es false, se continúa con la evaluación de la expresión de la derecha, que también es convertida a bool. Si el nuevo resultado es true, entonces el resultado del operador es true. En caso contrario el resultado es false.

Nota: el Estándar establece que antes de ser evaluada la expresión derecha, han sucedido todos los posibles efectos laterales de la expresión izquierda, a excepción de la destrucción de los posibles objetos temporales que se hubieran creado.

Ejemplo

#include <iostream.h>
bool alto = true, bajo = false, blanco = true, negro = false;

int main (void) {
  if (alto || bajo) { cout << "Uno cierto" << endl; }
  else cout << "Uno falso" << endl;
  if (alto || blanco) { cout << "Dos cierto" << endl; }
  else cout << "Dos falso" << endl;
  if (bajo || negro) { cout << "Tres cierto" << endl; }
  else cout << "Tres falso" << endl;
}

Salida

Uno cierto
Dos cierto
Tres falso

§4   !    Operador NO lógico:

Este operador es denominado también negación lógica y se representa en el texto escrito por la palabra inglesa NOT (otros lenguajes utilizan directamente esta palabra para representar el operador en el código).

Sintaxis

! expresion-cast

Comentario

El operando expresion-cast (que puede ser una expresión que se evalúa a un resultado 1.2.1) es convertido a tipo bool, con lo que solo puede ser uno de los valores cierto/falso. A continuación el operador cambia su valor:  Si es cierto es convertido a falso y viceversa.

Resulta por tanto, que el resultado de este operador es siempre un tipo bool, aunque al existir una conversión estándar por la que un cero es convertido a false, y cualquier valor distinto de cero a true ( 3.2.1b), coloquialmente se dice que este operador convierte un operando 0 en 1 y uno no-cero en 0. En otras palabras: este operador devuelve cierto (true) si la expresión se evalúa a distinto de cero, en caso contrario devuelve falso (false).

Ejemplo

#include <iostream.h>
bool alto = true, bajo = false;

int main (void) {
  if (alto) { cout << "Uno cierto" << endl; }
  else cout << "Uno falso" << endl;
  if (!alto) { cout << "Dos cierto" << endl; }
  else cout << "Dos falso" << endl;
  if (!bajo) { cout << "Tres cierto" << endl; }
  else cout << "Tres falso" << endl;
}

Salida:

Uno cierto
Dos falso
Tres cierto


Si E es una expresión, !E es equivalente a (0 == E). Como consecuencia, las expresiones que siguen son equivalentes dos a dos:

if (! valid);

if (valid == 0);

...

if (valid);

if (valid != 0);

§7  Representación explícita

Los operadores lógicos entre valores lógicos &&, ||, !; la relación de desigualdad !=; algunos de los operadores lógicos entre bits (&, |, ^, ~) y sus expresiones compuestas (&=, |=, ^=), tienen una representación realmente difícil de leer, con la desventaja adicional que sus símbolos no siempre están fácilmente accesibles en ordenadores con teclados distintos del estándar USA. Para resolver este problema, el Estándar C++ ha introducido nuevas formas para su representación; las denominamos formas explícitas o naturales, en razón de que se parecen más a las palabras correspondientes del lenguaje natural. Las nuevas formas constituyen palabras-clave, y la tabla de equivalencias es la siguiente:

Palabra  clave Símbolo Referencia  Descripción

 and

&&

   Operador Y lógico

 or

||

   Operador O lógico

 not

!

   Operador negación lógica

 bitand

&

  4.9.3  Operador AND entre bits
 xor

^

  4.9.3  Operador OR exclusivo entre bits
 bitor

|

  4.9.3  Operador OR inclusivo entre bits
 compl

~

  4.9.3  Operador complemento a uno de bits
 and_eq

&=

  4.9.3  Asignación compuesta (AND entre bits)
 xor_eq

^=

  4.9.3  Asignación compuesta (XOR entre bits)
 or_eq

|=

  4.9.3  Asignación compuesta (OR entre bits)
 not_eq

!=

  4.9.12  Operador relacional de desigualdad


Nota
: ni el compilador Borland C++ 5.5 ni MS VC++ 6.0 soportan esta característica del estándar, aunque el de Microsoft anuncia en su documentación que pueden utilizarse "defines" ( 4.9.10b).  Por ejemplo:

#define bitand &

#define bitor |

#define and_eq &=

#define or_eq |=

#define not_eq !=

Por su parte, el compilador GNU gcc dispone de la opción de compilación -fno-operator-names, que permite que las palabras-clave and, bitand, bitor, compl, not, y or, no sean tratadas como sinónimos de los operadores correspondientes.

  Temas relacionados:
  • Trigrafos y digrafos ( 3.2.3e)
  • Sobrecarga de los operadores lógicos ( 4.9.18g).