C n'a aucun type booléen intégré. Quelle est la meilleure façon de les utiliser en C?
C n'a aucun type booléen intégré. Quelle est la meilleure façon de les utiliser en C?
Option 1
typedef int bool;
#define true 1
#define false 0
Option 2
typedef int bool;
enum { false, true };
Option 3
typedef enum { false, true } bool;
Option 4 (C99)
#include <stdbool.h>
Si vous êtes indécis, allez avec # 3!
Quelques réflexions sur les booléens en C:
Je suis assez vieux pour utiliser simplement int
s comme mon type booléen sans typedefs ou special defined ou enums pour les valeurs true / false. Si vous suivez ma suggestion ci-dessous sur la comparaison jamais avec les constantes booléennes, il vous suffit d'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 utiliser <stdbool.h>
puisqu'il a au moins l'avantage d'être standardisé.
Quelles que soient les constantes booléennes appelées, utilisez-les uniquement pour l'initialisation. N'écrivez 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 réellement et raisonnablement être lus à haute voix.
Donnez à vos variables booléennes des noms positifs, ie full
au lieu de notfull
. Ce dernier conduit à un code difficile à lire facilement. Comparer
if (full) ...
if (!full) ...
avec
if (!notfull) ...
if (notfull) ...
Les deux anciens lisent naturellement, tandis que !notfull
est maladroit à lire même tel qu'il est, et devient bien pire dans des expressions booléennes plus complexes.
Les arguments booléens devraient généralement être évités. Considérons une fonction définie comme ceci
void foo(bool option) { ... }
À l'intérieur du corps de la fonction, il est très clair ce que l'argument signifie puisqu'il a un nom commode et, espérons-le, significatif. Mais, les sites d'appel ressemblent
foo(TRUE);
foo(FALSE):
Ici, il est essentiellement impossible de dire ce que signifie le paramètre sans toujours regarder la définition ou la déclaration de la fonction, et cela devient bien pire dès que vous ajoutez encore plus de paramètres booléens. Je suggère soit
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
ou
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
Dans les deux cas, le site d'appel ressemble maintenant
foo(OPT_ON);
foo(OPT_OFF);
que le lecteur a au moins une chance de comprendre sans pour autant déblayer la définition de foo
.
Un booléen dans C est un entier: zéro pour faux et non nul pour vrai.
Voir également Type de données booléen, section C, C ++, Objective-C, AWK.
Voici la version que j'ai utilisée:
typedef enum { false = 0, true = !false } bool;
Parce que false n'a qu'une valeur, mais qu'un true logique peut avoir plusieurs valeurs, mais la technique définit true comme étant ce que le compilateur utilisera pour le contraire de false.
Cela prend en charge le problème de quelqu'un qui code quelque chose qui se résume à 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 ponctuel de faire «vrai = faux», nous éliminons ce problème.
[EDIT] A la fin j'ai utilisé:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
pour éviter la collision de noms avec d'autres régimes qui définissaient true
et false
. Mais le concept reste le même.
[EDIT] Pour montrer la conversion d'entier en booléen:
mybool somebool;
int someint = 5;
somebool = !!someint;
Le premier (le plus à droite)! convertit l'entier non nul en un 0, puis le second (le plus à gauche)! convertit le 0 en un myfalse
valeur. Je vais le laisser comme un exercice pour le lecteur de convertir un entier zéro.
Si vous utilisez un compilateur C99, il prend en charge les types de booléen:
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
typedef enum {
false = 0,
true
} t_bool;
C a un type booléen: bool (au moins pour les 10 dernières années!)
Inclure stdbool.h et true / false fonctionnera comme prévu.
Tout ce qui n'est pas nul est évalué à vrai dans les opérations booléennes, donc vous pourriez juste
#define TRUE 1
#define FALSE 0
et utilise les constantes.
Premières choses d'abord. C, c'est-à-dire ISO / CEI 9899 a un type booléen pour 19 ans maintenant. C'est beaucoup plus long que le attendu durée de la carrière en programmation C avec des parties amateur / académique / professionnel combinées lors de la visite cette question. Le mien surpasse cela de seulement peut-être 1-2 ans. Cependant, pendant le temps qu'un lecteur moyen a appris quelque chose au sujet de C, C a effectivement eu le type de données booléen.
Pour le type de données, #include <stdbool.h>
, et utilise true
, false
et bool
. Ou ne l'incluez pas et utilisez _True
, _False
et _Bool
au lieu.
Il y a plusieurs dangereux des conseils dans ce fil de réponse. Je vais les aborder:
typedef int bool;
#define true 1
#define false 0
C'est un non-non, parce qu'un lecteur occasionnel - qui a appris le C au cours de ces 19 années - s'attendrait à ce que bool
se réfère à la réel bool
type de données et se comporterait de la même manière, mais ce n'est pas le cas! Par exemple
double a = ...;
bool b = a;
Avec C99 bool
/ _Bool
, b
serait réglé à false
sff a
était zéro, et true
autrement. Avec le typedef
en place, le double
serait contraint à un int
- si la valeur du double n'est pas dans la fourchette int
int, le le comportement est indéfini.
Naturellement, il en va de même si true
et false
ont été déclarés dans un enum
.
Qu'est-ce qui est encore plus dangereux déclare
typedef enum bool {
false, true
} bool;
parce que maintenant toutes les valeurs en outre 1 et 0 ne sont pas valides, et si une telle valeur est affectée à une variable de ce type, le comportement serait totalement indéfini.
Donc sff vous ne pouvez pas utiliser C99 pour une raison inexplicable, pour les variables booléennes que vous devriez utiliser:
int
et les valeurs 0
et 1
comme si; et effectuez soigneusement les conversions de domaine à partir de toutes les autres valeurs à ceux avec une double négation !!
BOOL
, TRUE
et FALSE
!@Thomas Matthews: Les expressions conditionnelles sont considérées comme vraies si elles sont non nulles, mais la norme C exige que les opérateurs logiques retournent eux-mêmes 0 ou 1.
@Tom: #define TRUE! FALSE est mauvais et est 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 vont générer un avertissement à propos de 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 #define TRUE! FALSE, vous vous retrouvez avec:
foo(flag == !0);
ce qui finit par faire une comparaison int-to-bool qui peut déclencher l'avertissement quand même.