L'option 1 ne fonctionnera que si vous utilisez C99 et c'est la "manière standard" de le faire. Choisissez ceci si possible.
Les options 2, 3 et 4 auront en pratique le même comportement identique. Les # 2 et # 3 n'utilisent cependant pas #defines, ce qui à mon avis est mieux.
Pouvez-vous expliquer pourquoi ce sont les meilleurs au pires choix?
endolith
1
@endolith L'alignement, les optimisations et la façon de stocker un que <stdbool.h>boolle compilateur choisit peuvent être plus adaptés à l'objectif prévu d'une valeur booléenne que d'utiliser un int(c'est-à-dire que le compilateur peut choisir d'implémenter un booldifféremment d'un int). Cela peut également entraîner une vérification de type plus stricte au moment de la compilation, si vous êtes chanceux.
blubberdiblub
1
Pourquoi utiliser intpour bool? C'est du gaspillage. Utilisez unsigned char. Ou utiliser le C de builtin _Bool.
user12211554
@NoBody L'utilisation d'un type plus petit peut permettre d'économiser de la mémoire, mais cela pourrait ne pas l'accélérer. Souvent, il est plus rapide d'utiliser la taille de mot native du processeur au lieu d'une taille plus petite car cela pourrait nécessiter que le compilateur effectue des décalages de bits pour l'aligner correctement
Ted Klein Bergman
241
Quelques réflexions sur les booléens en C:
Je suis assez vieux pour utiliser simplement des ints comme mon type booléen sans aucun typedefs ou définitions ou énumérations spéciales pour les valeurs true / false. Si vous suivez ma suggestion ci-dessous sur ne jamais comparer avec les constantes booléennes, alors vous n'avez qu'à utiliser 0/1 pour initialiser les indicateurs de toute façon. Cependant, une telle approche peut être jugée trop réactionnaire en ces temps modernes. Dans ce cas, il faut absolument l'utiliser <stdbool.h>car il a au moins l'avantage d'être standardisé.
Quel que soit le nom des constantes booléennes, utilisez-les uniquement pour l'initialisation. N'écris jamais quelque chose comme
if(ready == TRUE)...while(empty == FALSE)...
Ceux-ci peuvent toujours être remplacés par le plus clair
if(ready)...while(!empty)...
Notez que ceux-ci peuvent en fait être lus à haute voix de façon raisonnable et compréhensible.
Donnez à vos variables booléennes des noms positifs, c'est-à-dire fullau lieu de notfull. Ce dernier conduit à un code difficile à lire facilement. Comparer
if(full)...if(!full)...
avec
if(!notfull)...if(notfull)...
Les deux anciens couples lisent naturellement, tandis qu'ils !notfullsont difficiles à lire, même s'ils le sont, et deviennent bien pires dans les expressions booléennes plus complexes.
Les arguments booléens doivent généralement être évités. Considérons une fonction définie comme ceci
void foo(bool option){...}
Dans le corps de la fonction, il est très clair ce que l'argument signifie, car il a un nom pratique et, espérons-le, significatif. Mais, les sites d'appels ressemblent
foo(TRUE);
foo(FALSE):
Ici, il est essentiellement impossible de dire ce que signifiait le paramètre sans toujours regarder la définition ou la déclaration de fonction, et cela devient bien pire dès que vous ajoutez encore plus de paramètres booléens. Je propose soit
Et comment comparez-vous deux variables pour l'égalité? Ne jamais utiliser de constantes booléennes fonctionne très bien, mais cela ne résout pas le problème lors de la comparaison avec une non constante.
Baruch
Pardonnez-moi, mais je ne comprends pas la question. Demandez-vous comment je compare deux variables booléennes pour l'égalité? Si oui, ça ne a == bmarche pas ?
Dale Hagglund
5
@Kenji Ce que vous dites est vrai, même si je pense que l'utilisation de valeurs autres que 1 comme équivalent de true est presque toujours une mauvaise idée. Donc, dans votre exemple, en supposant cela aet en bcomptant à partir de zéro, je recommanderais a > 0 == b > 0plutôt. Si vous insistez pour tirer parti de la véracité des valeurs arbitraires non nulles, !!varla valeur booléenne 0/1 est équivalente à var, vous pouvez donc écrire !!a == !!b, bien que beaucoup de lecteurs trouveront cela déroutant.
Dale Hagglund
3
!a == !best également suffisant pour tester l'égalité, les non-zéros deviennent nuls et les zéros deviennent un.
ryanpattison du
5
@rpattiso Vous avez tout à fait raison, bien sûr, mais je suppose que je lirais !!a"convertir non-booléen a en sa valeur de vérité équivalente", alors que je lirais !a"inverser logiquement la variable booléenne a". En particulier, je chercherais une raison précise pour laquelle l'inversion logique était souhaitée.
Dale Hagglund
88
Un booléen en C est un entier: zéro pour faux et non nul pour vrai.
Cela fonctionne bien aussi avec les opérateurs logiques (&& et ||).
Vultrao
74
Voici la version que j'ai utilisée:
typedefenum{false=0,true=!false}bool;
Parce que false n'a qu'une seule valeur, mais un vrai logique peut avoir plusieurs valeurs, mais la technique définit true pour être ce que le compilateur utilisera pour l'opposé de false.
Cela résout le problème de quelqu'un codant quelque chose qui se résumerait à ceci:
if(true==!false)
Je pense que nous serions tous d'accord pour dire que ce n'est pas une bonne pratique, mais pour le coût unique de faire "vrai =! Faux", nous éliminons ce problème.
Le premier (le plus à droite)! convertit l'entier non nul en 0, puis le deuxième (le plus à gauche)! convertit le 0 en myfalsevaleur. Je vais laisser comme exercice au lecteur de convertir un entier nul.
[EDIT] C'est mon style d'utiliser le réglage explicite d'une valeur dans une énumération lorsque la valeur spécifique est requise même si la valeur par défaut serait la même. Exemple: parce que false doit être nul j'utilise false = 0,plutôt quefalse,
En outre un autre avantage à l' utilisation énumérations est l'intégration IDE - true, falseet boolsont mises en évidence dans la plupart des IDE parce qu'ils sont des valeurs enum et un typedef, par opposition à #defines, qui sont rarement la coloration syntaxique.
Curieux: Ignorer si cela fonctionne ou non, est-il valide C (99+) pour permettre à une énumération de référencer une valeur antérieure dans la même énumération ?
@ tgm1024 gcc -ansi -pedantic -Wallne donne aucun avertissement, donc j'ai confiance gcc; Si cela fonctionne même pour c89cela, cela devrait fonctionner c99aussi.
yyny
1
"Parce que false n'a qu'une seule valeur, mais un vrai logique peut avoir plusieurs valeurs, mais la technique définit true pour être ce que le compilateur utilisera pour l'opposé de false." L'opérateur de négation !ne peut renvoyer que des valeurs 0et 1, par conséquent true = !false, affectera toujours la valeur 1. Cette méthode ne donne aucune sécurité supplémentaire typedef enum { false, true } bool;.
user694733
1
Le plus ancien que j'ai trouvé provient de C90 (6.3.3.3 Opérateurs arithmétiques unaires): "Le résultat de l'opérateur de négation logique! Est 0 si la valeur de son opérande est différente de 0. 1 si la valeur de son opérande est égale à 0. Le result a le type int. L'expression! E est équivalente à (O == E). " Cela devrait couvrir tout compilateur qui a jamais prétendu prendre en charge la norme C. Les compilateurs peuvent bien sûr ignorer légalement cette règle dans les cas où cela n'a pas d'importance pour le comportement observable (comme if(!value)), mais cette exception n'est pas applicable dans ce cas spécifique.
user694733
48
Si vous utilisez un compilateur C99, il prend en charge les types booléens:
#include<stdbool.h>int main(){bool b =false;
b =true;}
Tout d'abord. C, c'est-à-dire que l'ISO / CEI 9899 a un type booléen depuis 19 ans maintenant . C'est beaucoup plus de temps que la durée prévue de la carrière de programmation C avec des parties amateur / académique / professionnel combinées lors de la visite de cette question . Le mien dépasse cela de peut-être 1-2 ans. Cela signifie que pendant le temps qu'un lecteur moyen a appris quoi que ce soit sur C, C a en fait eu le type de données booléen .
Pour le type de données,, #include <stdbool.h>et utilisez true, falseet bool. Ou ne l'incluez pas, et utilisez _Bool, 1et à la 0place.
Il existe diverses pratiques dangereuses promues dans les autres réponses à ce fil. Je vais les aborder:
typedefintbool;#definetrue1#definefalse0
Ce n'est pas non, car un lecteur occasionnel - qui a appris le C au cours de ces 19 années - s'attendrait à ce que cela se boolréfère au type de données réelbool et se comporte de la même manière, mais ce n'est pas le cas! Par exemple
double a =...;bool b = a;
Avec C99 bool/ _Bool, bserait réglé sur falsesi siffa était zéro, et truesinon. C11 6.3.1.2p1
Lorsqu'une valeur scalaire est convertie en _Bool, le résultat est 0 si la valeur se compare à 0; sinon, le résultat est 1. 59)
Notes de bas de page
59) Les NaN ne sont pas comparables à 0 et se convertissent donc à 1.
Avec le typedefen place, le doubleserait contraint à un int- si la valeur du double n'est pas dans la plage de int, le comportement n'est pas défini .
Naturellement, il en va de même si trueet falseont été déclarés dans un enum.
Ce qui est encore plus dangereux, c'est de déclarer
typedefenumbool{false,true}bool;
car maintenant toutes les valeurs en plus de 1 et 0 ne sont pas valides et si une telle valeur était affectée à une variable de ce type, le comportement serait totalement indéfini .
Par conséquent, si vous ne pouvez pas utiliser C99 pour une raison inexplicable, pour les variables booléennes, vous devez utiliser:
type intet valeurs 0et 1tels quels ; et effectuez soigneusement les conversions de domaine à partir de toute autre valeur vers celles-ci avec double négation!!
ou si vous insistez vous ne vous souvenez pas que 0 est falsy et truish non nul, au moins l' utilisation des majuscules afin qu'ils ne soient pas confondus avec les concepts de C99: BOOL, TRUEet FALSE!
Quelle partie de la norme C limiterait les objets de types énumérés à contenir les valeurs qui y sont explicitement énumérées? Si la plus grande valeur pour une constante énumérée est inférieure à UCHAR_MAX ou USHRT_MAX, une implémentation pourrait utiliser un type plus petit que intou unsigned intpour contenir une énumération, mais je ne connais rien dans la norme qui ferait en sorte qu'une énumération se comporte autrement que comme un entier type.
@technosaurus Cette approche ne garantit pas! false == true car! false peut être n'importe quel nombre différent de zéro. Une solution simple serait d'affecter explicitement true à! False.
Andrew
3
@Andrew Ce n'est pas vrai. !0 = 1par la norme C, et !a = 0pour toute valeur non nulle de a. Le problème est que tout non différent de zéro est considéré comme vrai. Donc, si aet bsont tous les deux "vrais", ce n'est pas nécessairement le cas que `a == b`.
Jeremy West
14
C a un type booléen: bool (au moins pour les 10 (!) Dernières années)
Incluez stdbool.h et true / false fonctionnera comme prévu.
10 ans en standard, mais pas 10 ans en compilateurs! La compilation C de MSVC ++ ne prend pas du tout en charge C99, à l'exception de // l'autorisation des commentaires, et il est peu probable qu'elle le fasse. _Bool est également défini dans C99 comme un type intégré, tandis que bool est un typedef dans l'en-tête <stdbool.h>.
Clifford
5
@Clifford 4 ans après votre commentaire ... rien n'a changé. MSVC est un compilateur C ++ et je pense que MS a dit qu'il ne souhaitait pas vraiment prendre en charge toutes les nouvelles fonctionnalités C (C99 et C11). Mais je ne peux pas considérer que MSVC ne prend pas en charge les nouvelles fonctionnalités C comme raison (surtout lorsque vous le dites contre 10 ans de réponse). 10 ans, c'est vraiment long dans le monde de la programmation. Tout compilateur décent devrait le prendre en charge dans beaucoup moins de 10 ans si le fournisseur a l'intention de le prendre en charge.
PP
2
@ KingsIndian: Je ne sais pas pourquoi vous m'avez adressé votre commentaire ou même ressenti le besoin de commenter. Je ne faisais qu'énoncer la situation telle qu'elle était au moment de la rédaction. Je n'appuyais pas cette situation, faisant simplement remarquer que la "réponse" pouvait ne pas s'appliquer en toutes circonstances.
Clifford
@Clifford: Strictement, la norme doit boolêtre une macro qui se développe _Bool. La différence est importante car vous pouvez #undefune macro (et c'est autorisé, au moins à titre de mesure transitoire), mais vous ne pouvez pas untypedefun typedef. Cependant, cela ne modifie pas l'orientation principale de votre premier commentaire.
Jonathan Leffler
2
VS2015 et versions ultérieures (et peut-être plus tôt, jusqu'à un certain point) n'ont aucun problème avec la compilation boolthrough <stdbool.h>under C. Il se résout à _Bool.
11
Tout ce qui n'est pas nul est évalué comme vrai dans les opérations booléennes, vous pouvez donc simplement
mais utilisez-les avec précaution: puisqu'un vrai résultat peut être n'importe quelle valeur non nulle, les tests if (t == TRUE) {...} et if (t), qui sont équivalents dans d'autres langues, ne sont pas équivalents en C .
Fortega
1
Vous avez raison, mais c'est également vrai en C ++ qui a un type bool, non? Pendant le débogage, j'ai vu des variables booléennes avec des valeurs de 5837834939 ...
ggambett
1
En C ++, le test if (t == true) est égal au test if (t), car C ++ effectue une certaine conversion (tout ce qui n'est pas 0 ou une valeur de pointeur nul est converti en true)
Fortega
6
Tout ce que vous devez supposer d'une valeur booléenne vraie, c'est qu'elle est différente de zéro. Donc, du code comme if (b) est sûr tandis que if (b == TRUE) ne l'est pas; ce dernier est une mauvaise pratique (et inutile).
Clifford
5
Juste un complément à d'autres réponses et quelques précisions, si vous êtes autorisé à utiliser C99.
+-------+----------------+-------------------------+--------------------+|Name|Characteristic|Dependence in stdbool.h |Value|+-------+----------------+-------------------------+--------------------+|_Bool|Native type |Don't need header ||+-------+----------------+-------------------------+--------------------+|bool|Macro|Yes|Translate to _Bool|+-------+----------------+-------------------------+--------------------+|true|Macro|Yes|Translate to 1|+-------+----------------+-------------------------+--------------------+|false|Macro|Yes|Translate to 0|+-------+----------------+-------------------------+--------------------+
Certaines de mes préférences:
_Boolou bool? Les deux sont bien, mais boolsemblent meilleurs que le mot-clé _Bool.
Les valeurs acceptées pour boolet _Boolsont: falseou true. Affecter 0ou 1au lieu de falseou trueest valide, mais est plus difficile à lire et à comprendre le flux logique.
Quelques informations de la norme:
_Booln'est PAS unsigned int, mais fait partie du groupe des types entiers non signés . Il est suffisamment grand pour contenir les valeurs 0ou 1.
NE PAS, mais oui, vous êtes en mesure de redéfinir booltrueet falsemais ce n'est certainement pas une bonne idée. Cette capacité est considérée comme obsolète et sera supprimée à l'avenir.
L'affectation d'un type scalaire (types arithmétiques et types de pointeurs) à _Boolou bool, si la valeur scalaire est égale 0ou comparable à 0elle le sera 0, sinon le résultat est 1: _Bool x = 9;9est convertie en 1lorsqu'elle est affectée à x.
_Boolest de 1 octet (8 bits), généralement le programmeur est tenté d'essayer d'utiliser les autres bits, mais n'est pas recommandé, car la seule garantie qui est donnée est qu'un seul bit est utilisé pour stocker les données, pas comme le type charqui en a 8 bits disponibles.
En C également, il s'agit généralement d'un int, et il peut entraîner une perte d'avertissements de précision par un autre code utilisant int.
Thomas Bonini
À moins que vous n'optimisiez manuellement l'espace, il est toujours préférable d'utiliser la taille de mot normale du matériel (par exemple: généralement un int), car sur certaines architectures, vous obtenez un impact significatif sur les performances en décompressant / masquant les vérifications de ces variables.
Kingsley
2
Vous pouvez utiliser _Bool, mais la valeur de retour doit être un entier (1 pour vrai, 0 pour faux). Cependant, il est recommandé d'inclure et d'utiliser bool comme en C ++, comme indiqué dans
cette réponse du forum daniweb , ainsi que cette réponse , de cette autre question stackoverflow:
_Bool: type booléen de C99. L'utilisation directe de _Bool n'est recommandée que si vous conservez un code hérité qui définit déjà des macros pour bool, true ou false. Sinon, ces macros sont normalisées dans l'en-tête. Incluez cet en-tête et vous pouvez utiliser bool comme vous le feriez en C ++.
Les expressions conditionnelles sont considérées comme vraies si elles ne sont pas nulles, mais la norme C exige que les opérateurs logiques renvoient eux-mêmes 0 ou 1.
@Tom: #define TRUE! FALSE est mauvais et complètement inutile. Si le fichier d'en-tête fait son chemin dans le code C ++ compilé, cela peut entraîner des problèmes:
void foo(bool flag);...int flag = TRUE;
foo(flag);
Certains compilateurs généreront un avertissement concernant la conversion int => bool. Parfois, les gens évitent cela en faisant:
foo(flag == TRUE);
pour forcer l'expression à être un booléen C ++. Mais si vous #définissez VRAI! FAUX, vous vous retrouvez avec:
foo(flag ==!0);
qui finit par faire une comparaison int-to-bool qui peut déclencher l'avertissement de toute façon.
Si vous utilisez C99, vous pouvez utiliser le _Booltype. Aucun #includes n'est nécessaire. Vous devez cependant le traiter comme un entier, où 1est trueet 0est false.
Vous pouvez ensuite définir TRUEet FALSE.
_Bool this_is_a_Boolean_var =1;//or using it with true and false#define TRUE 1#define FALSE 0_Bool var = TRUE;
NOT macro doit être protégée par des parenthèses autour de la arget l'expression dans son ensemble: #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). Cependant, il serait préférable de tester la fausseté (elle donnera la bonne réponse même si elle argétait 23 au lieu de 0 ou 1:. #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)Mais l'expression entière peut être réduite à #define NOT(arg) (!(arg)), bien sûr, ce qui produit le même résultat.
Réponses:
Du meilleur au pire:
Option 1 (C99)
Option 2
Option 3
Option 4
Explication
Si vous êtes indécis, optez pour le # 1!
la source
<stdbool.h>
bool
le compilateur choisit peuvent être plus adaptés à l'objectif prévu d'une valeur booléenne que d'utiliser unint
(c'est-à-dire que le compilateur peut choisir d'implémenter unbool
différemment d'unint
). Cela peut également entraîner une vérification de type plus stricte au moment de la compilation, si vous êtes chanceux.int
pourbool
? C'est du gaspillage. Utilisezunsigned char
. Ou utiliser le C de builtin_Bool
.Quelques réflexions sur les booléens en C:
Je suis assez vieux pour utiliser simplement des
int
s comme mon type booléen sans aucun typedefs ou définitions ou énumérations spéciales pour les valeurs true / false. Si vous suivez ma suggestion ci-dessous sur ne jamais comparer avec les constantes booléennes, alors vous n'avez qu'à utiliser 0/1 pour initialiser les indicateurs de toute façon. Cependant, une telle approche peut être jugée trop réactionnaire en ces temps modernes. Dans ce cas, il faut absolument l'utiliser<stdbool.h>
car il a au moins l'avantage d'être standardisé.Quel que soit le nom des constantes booléennes, utilisez-les uniquement pour l'initialisation. N'écris jamais quelque chose comme
Ceux-ci peuvent toujours être remplacés par le plus clair
Notez que ceux-ci peuvent en fait être lus à haute voix de façon raisonnable et compréhensible.
Donnez à vos variables booléennes des noms positifs, c'est-à-dire
full
au lieu denotfull
. Ce dernier conduit à un code difficile à lire facilement. Compareravec
Les deux anciens couples lisent naturellement, tandis qu'ils
!notfull
sont difficiles à lire, même s'ils le sont, et deviennent bien pires dans les expressions booléennes plus complexes.Les arguments booléens doivent généralement être évités. Considérons une fonction définie comme ceci
Dans le corps de la fonction, il est très clair ce que l'argument signifie, car il a un nom pratique et, espérons-le, significatif. Mais, les sites d'appels ressemblent
Ici, il est essentiellement impossible de dire ce que signifiait le paramètre sans toujours regarder la définition ou la déclaration de fonction, et cela devient bien pire dès que vous ajoutez encore plus de paramètres booléens. Je propose soit
ou
Dans les deux cas, le site d'appel ressemble maintenant à
que le lecteur a au moins une chance de comprendre sans en tirer la définition
foo
.la source
a == b
marche pas ?a
et enb
comptant à partir de zéro, je recommanderaisa > 0 == b > 0
plutôt. Si vous insistez pour tirer parti de la véracité des valeurs arbitraires non nulles,!!var
la valeur booléenne 0/1 est équivalente àvar
, vous pouvez donc écrire!!a == !!b
, bien que beaucoup de lecteurs trouveront cela déroutant.!a == !b
est également suffisant pour tester l'égalité, les non-zéros deviennent nuls et les zéros deviennent un.!!a
"convertir non-booléen a en sa valeur de vérité équivalente", alors que je lirais!a
"inverser logiquement la variable booléenne a". En particulier, je chercherais une raison précise pour laquelle l'inversion logique était souhaitée.Un booléen en C est un entier: zéro pour faux et non nul pour vrai.
Voir aussi Type de données booléen , section C, C ++, Objective-C, AWK .
la source
Voici la version que j'ai utilisée:
Parce que false n'a qu'une seule valeur, mais un vrai logique peut avoir plusieurs valeurs, mais la technique définit true pour être ce que le compilateur utilisera pour l'opposé de false.
Cela résout le problème de quelqu'un codant quelque chose qui se résumerait à ceci:
Je pense que nous serions tous d'accord pour dire que ce n'est pas une bonne pratique, mais pour le coût unique de faire "vrai =! Faux", nous éliminons ce problème.
[EDIT] Au final, j'ai utilisé:
pour éviter la collision de noms avec d'autres schémas qui définissaient
true
etfalse
. Mais le concept reste le même.[EDIT] Pour afficher la conversion de l'entier en booléen:
Le premier (le plus à droite)! convertit l'entier non nul en 0, puis le deuxième (le plus à gauche)! convertit le 0 en
myfalse
valeur. Je vais laisser comme exercice au lecteur de convertir un entier nul.[EDIT] C'est mon style d'utiliser le réglage explicite d'une valeur dans une énumération lorsque la valeur spécifique est requise même si la valeur par défaut serait la même. Exemple: parce que false doit être nul j'utilise
false = 0,
plutôt quefalse,
la source
true
,false
etbool
sont mises en évidence dans la plupart des IDE parce qu'ils sont des valeurs enum et un typedef, par opposition à#defines
, qui sont rarement la coloration syntaxique.gcc -ansi -pedantic -Wall
ne donne aucun avertissement, donc j'ai confiancegcc
; Si cela fonctionne même pourc89
cela, cela devrait fonctionnerc99
aussi.!
ne peut renvoyer que des valeurs0
et1
, par conséquenttrue = !false
, affectera toujours la valeur 1. Cette méthode ne donne aucune sécurité supplémentairetypedef enum { false, true } bool;
.if(!value)
), mais cette exception n'est pas applicable dans ce cas spécifique.Si vous utilisez un compilateur C99, il prend en charge les types booléens:
http://en.wikipedia.org/wiki/Boolean_data_type
la source
Tout d'abord. C, c'est-à-dire que l'ISO / CEI 9899 a un type booléen depuis 19 ans maintenant . C'est beaucoup plus de temps que la durée prévue de la carrière de programmation C avec des parties amateur / académique / professionnel combinées lors de la visite de cette question . Le mien dépasse cela de peut-être 1-2 ans. Cela signifie que pendant le temps qu'un lecteur moyen a appris quoi que ce soit sur C, C a en fait eu le type de données booléen .
Pour le type de données,,
#include <stdbool.h>
et utiliseztrue
,false
etbool
. Ou ne l'incluez pas, et utilisez_Bool
,1
et à la0
place.Il existe diverses pratiques dangereuses promues dans les autres réponses à ce fil. Je vais les aborder:
Ce n'est pas non, car un lecteur occasionnel - qui a appris le C au cours de ces 19 années - s'attendrait à ce que cela se
bool
réfère au type de données réelbool
et se comporte de la même manière, mais ce n'est pas le cas! Par exempleAvec C99
bool
/_Bool
,b
serait réglé surfalse
si siffa
était zéro, ettrue
sinon. C11 6.3.1.2p1Avec le
typedef
en place, ledouble
serait contraint à unint
- si la valeur du double n'est pas dans la plage deint
, le comportement n'est pas défini .Naturellement, il en va de même si
true
etfalse
ont été déclarés dans unenum
.Ce qui est encore plus dangereux, c'est de déclarer
car maintenant toutes les valeurs en plus de 1 et 0 ne sont pas valides et si une telle valeur était affectée à une variable de ce type, le comportement serait totalement indéfini .
Par conséquent, si vous ne pouvez pas utiliser C99 pour une raison inexplicable, pour les variables booléennes, vous devez utiliser:
int
et valeurs0
et1
tels quels ; et effectuez soigneusement les conversions de domaine à partir de toute autre valeur vers celles-ci avec double négation!!
BOOL
,TRUE
etFALSE
!la source
int
ouunsigned int
pour contenir une énumération, mais je ne connais rien dans la norme qui ferait en sorte qu'une énumération se comporte autrement que comme un entier type.la source
!0 = 1
par la norme C, et!a = 0
pour toute valeur non nulle dea
. Le problème est que tout non différent de zéro est considéré comme vrai. Donc, sia
etb
sont tous les deux "vrais", ce n'est pas nécessairement le cas que `a == b`.C a un type booléen: bool (au moins pour les 10 (!) Dernières années)
Incluez stdbool.h et true / false fonctionnera comme prévu.
la source
bool
être une macro qui se développe_Bool
. La différence est importante car vous pouvez#undef
une macro (et c'est autorisé, au moins à titre de mesure transitoire), mais vous ne pouvez pasuntypedef
un typedef. Cependant, cela ne modifie pas l'orientation principale de votre premier commentaire.bool
through<stdbool.h>
under C. Il se résout à_Bool
.Tout ce qui n'est pas nul est évalué comme vrai dans les opérations booléennes, vous pouvez donc simplement
et utiliser les constantes.
la source
Juste un complément à d'autres réponses et quelques précisions, si vous êtes autorisé à utiliser C99.
Certaines de mes préférences:
_Bool
oubool
? Les deux sont bien, maisbool
semblent meilleurs que le mot-clé_Bool
.bool
et_Bool
sont:false
outrue
. Affecter0
ou1
au lieu defalse
outrue
est valide, mais est plus difficile à lire et à comprendre le flux logique.Quelques informations de la norme:
_Bool
n'est PASunsigned int
, mais fait partie du groupe des types entiers non signés . Il est suffisamment grand pour contenir les valeurs0
ou1
.bool
true
etfalse
mais ce n'est certainement pas une bonne idée. Cette capacité est considérée comme obsolète et sera supprimée à l'avenir._Bool
oubool
, si la valeur scalaire est égale0
ou comparable à0
elle le sera0
, sinon le résultat est1
:_Bool x = 9;
9
est convertie en1
lorsqu'elle est affectée àx
._Bool
est de 1 octet (8 bits), généralement le programmeur est tenté d'essayer d'utiliser les autres bits, mais n'est pas recommandé, car la seule garantie qui est donnée est qu'un seul bit est utilisé pour stocker les données, pas comme le typechar
qui en a 8 bits disponibles.la source
C'est ça:
la source
Vous pouvez utiliser un caractère ou un autre conteneur de petit nombre pour cela.
Pseudo-code
la source
int
), car sur certaines architectures, vous obtenez un impact significatif sur les performances en décompressant / masquant les vérifications de ces variables.Vous pouvez utiliser _Bool, mais la valeur de retour doit être un entier (1 pour vrai, 0 pour faux). Cependant, il est recommandé d'inclure et d'utiliser bool comme en C ++, comme indiqué dans cette réponse du forum daniweb , ainsi que cette réponse , de cette autre question stackoverflow:
la source
Les expressions conditionnelles sont considérées comme vraies si elles ne sont pas nulles, mais la norme C exige que les opérateurs logiques renvoient eux-mêmes 0 ou 1.
@Tom: #define TRUE! FALSE est mauvais et complètement inutile. Si le fichier d'en-tête fait son chemin dans le code C ++ compilé, cela peut entraîner des problèmes:
Certains compilateurs généreront un avertissement concernant la conversion int => bool. Parfois, les gens évitent cela en faisant:
pour forcer l'expression à être un booléen C ++. Mais si vous #définissez VRAI! FAUX, vous vous retrouvez avec:
qui finit par faire une comparaison int-to-bool qui peut déclencher l'avertissement de toute façon.
la source
Si vous utilisez C99, vous pouvez utiliser le
_Bool
type. Aucun#include
s n'est nécessaire. Vous devez cependant le traiter comme un entier, où1
esttrue
et0
estfalse
.Vous pouvez ensuite définir
TRUE
etFALSE
.la source
#include <stdbool.h>
et utiliserbool
,true
etfalse
comme le veut la norme.De nos jours, C99 prend en charge les types booléens, mais vous en avez besoin
#include <stdbool.h>
.Exemple:
Production:
la source
Voici ce que j'utilise:
_Bool
est un type intégré en C. Il est destiné aux valeurs booléennes.la source
Vous pouvez simplement utiliser la
#define
directive comme suit:Et utilisez comme suit:
etc
la source
arg
et l'expression dans son ensemble:#define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
. Cependant, il serait préférable de tester la fausseté (elle donnera la bonne réponse même si ellearg
était 23 au lieu de 0 ou 1:.#define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
Mais l'expression entière peut être réduite à#define NOT(arg) (!(arg))
, bien sûr, ce qui produit le même résultat.