Comment basculer un int / _Bool en C
Supposons que nous avons un int
et souhaitez basculer entre 0
et 1
dans un booléen de la mode. 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...
- Le troisième semble fonctionner. Pourquoi? Qui décide que
!0
est1
? - Est quelque chose de mal avec l'un de ces?
- Existe-il d'autres possibilités? par exemple, les opérateurs sur les bits?
- Qui offre les meilleures performances?
- Seraient tous être identiques avec
_Bool
(oubool
de stdbool.h)? Si non, quelles sont les différences?
EDIT: Beaucoup de grandes réponses avec beaucoup d'informations précieuses, merci! Malheureusement, je ne peux accepter.
source d'informationauteur riha
Vous devez vous connecter pour publier un commentaire.
value = !value;
exprime ce que vous voulez faire directement, et c'est exactement ce que vous voulez faire, par définition.Utiliser cette expression.
De C99 6.5.3.3/5 "opérateurs arithmétiques Unaires":
C Standard garantit que
!0
est1
.Oui, vous pouvez utiliser le OU exclusif de l'opérateur:
value ^= 1;
Par la façon dont je préfère cela à
value = !value;
relationnelles et des opérateurs d'égalité peut entraîner de branchement et les opérateurs au niveau du bit généralement pas.value = !value
semble la plus raisonnable, mais vous pouvez également utiliservalue = 1 - value
ouvalue ^= 1
. Mais les deux derniers permettrait à la fois de se briser sivalue
n'est pas0
ou1
. Le premier fonctionne encore.Il peut être perceptible problèmes de performances avec les solutions de rechange en fonction de l'architecture:
ce qui peut nécessiter encore 3 instructions pour terminer (avec dépendances)
Mais de toute façon la première règle de l'optimisation est qui n'optimisent pas non code du travail.
Pour le remplacer !un avec a^1, on doit être à 100% certain qu'il produit toujours de la valeur attendue.
value = (value ^ 1) & 1;
_Bool
aurait les mêmes résultats. La seule chose de différent avec _Bool, c'est que les valeurs sont contraints à être 1 ou 0. Ce qui signifie quebool x = 55;
aura la valeurx == 1
EDIT: correction de la formule en 3 à cause de mon brainfart. Je laisse les commentaires, afin que les gens puissent voir mon erreur.
Votre expression
value = value == 0 ? 1 : 0;
fonctionnera exactement commevalue = !value;
. Vous pouvez utiliser l'un des deux.!0
est toujours1
et aussi!(any non zero value)
est0
En C#, vous pouvez utiliser
Math.Abs(value -1)
pour basculer entre zéro et un, comme des entiers.