Opérateurs logiques

Il n’existe pas en C++ de type logique, comme par exemple le type Boolean du Pascal. Les nombres, entiers ou décimaux, sont utilisés à la place avec la convention suivante : une valeur nulle correspond à la valeur logique faux, une autre valeur à vrai.

Il existe des opérateurs qui fournissent automatiquement des valeurs logiques, c’est-à-dire en l’occurrence un entier égal à 0 ou 1 ; ils s’appliquent à un ou deux nombres entiers ou décimaux (une conversion est faite pour rendre les types des deux opérandes égaux). Ce sont les suivants :

! Opérateur unaire de négation logique. !x vaut 0 si x est non nul, 1 sinon. Cet opérateur ne peut être appliqué à un décimal, car il donne un résultat erroné ; écrire dans ce cas x == 0.
== Opérateur binaire symétrique d’égalité. x == y vaut 1 si les opérandes sont égaux, 0 sinon.
!= Opérateur binaire symétrique d’inégalité. Contraire de ==.
< Opérateur binaire d’inégalité. x < y vaut 1 si x est strictement inférieur à y, 0 sinon.
> Opérateur binaire d’inégalité. x > y vaut 1 si x est strictement supérieur à y, 0 sinon.
<= Opérateur binaire d’inégalité. Contraire de >.
>= Opérateur binaire d’inégalité. Contraire de <.

Ces opérateurs sont redondants, puisque par exemple x<y équivaut à !(x>=y), que !x équivaut à x == 0, etc.

Exercice 2.5

Il n’existe pas d’opérateur logique unaire qui renvoie 1 si son opérande est non-nul, 0 sinon. Comment le simuler ? Est-ce très utile ?

Voir solution

Lorsqu’on a deux valeurs logiques, on peut effectuer des opérations dessus à l’aide de deux opérateurs particuliers :

&& Opérateur binaire symétrique logique « et » . Renvoie 1 si ses deux opérandes sont non nuls, 0 sinon.
|| Opérateur binaire symétrique logique « ou » . Renvoie 1 si l’un au moins de ses deux opérandes est non nul, 0 s’ils sont tous deux nuls.

Par exemple, on écrira :

if ( (x >0) && (y >0) ) action;

si l’on souhaite que action soit exécutée seulement quand les variables x et y sont strictement positives.

On a les relations dites de Morgan entre ces deux opérateurs :

x && y = !(!x || !y)

x || y = !(!x && !y)

Notons finalement que si test1 et test2 sont deux instructions booléennes, alors test1 && test2 n’est pas exactement identique à test1 & test2. (Dans ce dernier cas on utilise un opérateur sur les entiers, voir précédemment.) En effet, lorsque que les tests provoquent des exécutions, comme par exemple des appels de fonctions, le premier est exécuté d’abord, et s’il donne la valeur « faux » le second n’est pas exécuté lorsqu’on écrit test1 && test2 (car le && donnera de toutes façons « faux »), tandis qu’il l’est tout de même (inutilement) dans l’autre écriture. Cela permet non seulement de raccourcir l'exécution, mais aussi d’éviter des erreurs subtiles, comme dans cet exemple, où p est un pointeur sur un entier :

if ( (p != null) && (*p > 0)) ...

Le premier test vérifie que le pointeur pointe effectivement sur quelque chose, et le second n’est exécuté que dans l’affirmative. Remplacer && par & ici provoquerait des erreurs d’exécution en cas de pointeur nul !

Un remarque similaire vaut pour la différence entre || et |. On retiendra qu’il faut quasiment toujours utiliser && et || avec les booléens. (Voyez aussi la solution de l’exercice 2.7 ci-après.)

Exercice 2.6

Il n’existe pas d’opérateur de « ou exclusif logique » en C++, qui renverrait 1 si l’un seulement de ses opérateurs est non nul, 0 sinon. Comment peut-on le simuler ?

Voir solution
Exercice 2.7

Les deux relations suivantes sont-elles vraies, si i et j sont deux entiers ?

if (i&&j)...   équivaut à   if (i&j)...
if (i||j)...   équivaut à if (i|j)...

Voir solution
Précédent Précédent Sommaire Sommaire Suivant Suivant