Supposons que nous ayons une int
et que nous voulions basculer entre 0
et 1
de manière booléenne. J'ai pensé aux possibilités suivantes:
int value = 0; // May as well be 1
value = value == 0 ? 1 : 0;
value = (value + 1) % 2;
value = !value; // I was curious if that would do...
!0
est 1
?_Bool
(ou bool
de stdbool.h)? Si non, quelles sont les différences?EDIT: Beaucoup de bonnes réponses avec beaucoup d'informations précieuses, merci! Malheureusement, je ne peux en accepter qu'un.
value = !value;
exprime ce que vous voulez faire directement, et il fait exactement ce que vous voulez faire par définition.
Utilisez cette expression.
A partir de C99 6.5.3.3/5 "Opérateurs arithmétiques unaires":
Le résultat de l'opérateur de négation logique! vaut 0 si la valeur de son opérande est différente de 0, 1 si la valeur de son opérande compare à 0. Le résultat est de type int. L'expression! E est équivalente À (0 == E).
Le troisième semble fonctionner. Pourquoi? Qui décide que! 0 est 1?
C Standard garantit que !0
est 1
.
Y a-t-il d'autres possibilités? par exemple. opérateurs au niveau des bits?
Oui, vous pouvez utiliser l'opérateur exclusif OR:
value ^= 1;
En passant, je préfère ceci à value = !value;
car les opérateurs relationnels et d’égalité peuvent entraîner des branches et les opérateurs au niveau des bits ne le font généralement pas.
value = !value
semble le plus raisonnable, mais vous pouvez également utiliser value = 1 - value
ou value ^= 1
. Mais les deux derniers casse si value
n'est pas 0
ou 1
. Le premier fonctionnerait toujours.
value = (value ^ 1) & 1;
_Bool
aurait les mêmes résultats. La seule différence avec _Bool est que les valeurs sont forcées d'être 1 ou 0. Cela signifie que bool x = 55;
aura la valeur x == 1
EDIT: Correction de la formule en 3 à cause de mon brainfart. Je laisse les commentaires pour que les gens puissent voir mon bêtisier.
Il peut y avoir des problèmes de performances notables avec les alternatives en fonction de l'architecture:
Quoi qu'il en soit, la première règle d'optimisation est de ne pas optimiser un code qui ne fonctionne pas. Pour remplacer! A par un ^ 1, il faut être sûr à 100% qu'il produit toujours la valeur attendue.
Votre expression value = value == 0 ? 1 : 0;
fonctionnera exactement comme value = !value;
. Vous pouvez utiliser n'importe lequel des deux.
!0
est toujours 1
et !(any non zero value)
est également 0
value = 1 - value; // toggle from 0 to 1 ... or 1 to 0
// when you know initial value is either 0 or 1
En C #, vous pouvez utiliser Math.Abs(value -1)
pour basculer entre zéro et un en tant qu'entiers.