Le C n'a pas de types booléens intégrés. Quelle est la meilleure façon de les utiliser en C ?
Pouvez-vous élaborer sur pourquoi ce sont les meilleurs et les pires choix ?
Le C n'a pas de types booléens intégrés. Quelle est la meilleure façon de les utiliser en C ?
Du meilleur au pire :
Option 1 (C99 et plus récent)
#include <stdbool.h>
Option 2
typedef enum { false, true } bool;
Option 3
typedef int bool;
enum { false, true };
Option 4
typedef int bool;
#define true 1
#define false 0
Si vous êtes indécis, choisissez le numéro 1 !
@endolith L'alignement, les optimisations et la manière de stocker une <stdbool.h>
bool
que le compilateur choisit peut être plus adapté à l'usage prévu d'une valeur booléenne que l'utilisation d'une fonction int
(c'est-à-dire que le compilateur peut choisir d'implémenter une bool
différemment d'un int
). Si vous avez de la chance, cela pourrait également entraîner une vérification plus stricte des types au moment de la compilation.
Pourquoi utiliser int
pour bool
? C'est du gaspillage. Utilisez unsigned char
. Ou utilisez la fonction intégrée de C _Bool
.
Quelques réflexions sur les booléens en C :
Je suis assez vieux pour utiliser de simples int
comme mon type booléen sans aucun typedefs ou définitions spéciales ou enums pour les valeurs vrai/faux. Si vous suivez ma suggestion ci-dessous sur le fait de ne jamais comparer avec des constantes booléennes, alors vous n'avez de toute façon qu'à utiliser 0/1 pour initialiser les drapeaux. 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 normalisé.
Quel que soit le nom des constantes booléennes, 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 les plus clairs
if (ready) ...
while (!empty) ...
Notez qu'il est possible de les lire à haute voix de manière raisonnable et compréhensible.
Donnez à vos variables booléennes des noms positifs, c'est-à-dire full
au lieu de notfull
. Ce dernier conduit à un code difficile à lire facilement. Comparez
if (full) ...
if (!full) ...
avec
if (!notfull) ...
if (notfull) ...
Les deux premières paires se lisent naturellement, tandis que !notfull
est difficile à lire, même telle quelle, et devient bien pire 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 suit
void foo(bool option) { ... }
Dans le corps de la fonction, la signification de l'argument est très claire puisqu'il porte un nom pratique et, espérons-le, significatif. Mais, le site d'appel ressemble à
foo(TRUE);
foo(FALSE):
Dans ce cas, il est pratiquement impossible de savoir ce que le paramètre signifie sans toujours regarder la définition ou la déclaration de la fonction, et la situation empire dès que l'on ajoute des paramètres booléens. Je suggère soit
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
o
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
Dans les deux cas, le site d'appel ressemble maintenant à ceci
foo(OPT_ON);
foo(OPT_OFF);
que le lecteur a au moins une chance de comprendre sans devoir déterrer la définition de foo
.
Et comment comparez-vous l'égalité de deux variables ? Ne jamais utiliser de constantes booléennes fonctionne très bien, mais cela ne résout pas le problème de la comparaison avec une variable non constante.
Pardonnez-moi, mais je ne comprends pas la question. Demandez-vous comment je compare deux variables booléennes pour l'égalité ? Si oui, est-ce que a == b
travail ?
Cela ne fonctionne pas car "a" peut avoir la valeur 3, ce qui est vrai, et "b" peut avoir la valeur 5, ce qui est vrai. Mais a == b devrait également être vrai, ce qui n'est pas le cas s'il s'agit d'entiers.
Un booléen en C est un entier : zéro pour faux et non-zéro pour vrai.
Voir aussi Type de données booléennes , 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 seule valeur, alors qu'un true logique pourrait avoir plusieurs valeurs, mais la technique définit true comme étant ce que le compilateur utilisera pour l'opposé de false.
Cela résout le problème de quelqu'un qui coderait quelque chose qui se résumerait à cela :
if (true == !false)
Je pense que nous sommes tous d'accord pour dire que ce n'est pas une bonne pratique, mais pour le coût unique de l'utilisation de "true = !false", nous éliminons ce problème.
[Finalement, j'ai utilisé.. :
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
pour éviter toute collision de noms avec d'autres systèmes qui définissaient true
y false
. Mais le concept reste le même.
[EDIT] Pour montrer la conversion d'un 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 laisse au lecteur le soin de convertir un nombre entier nul.
[EDIT] C'est mon style d'utiliser le réglage explicite d'une valeur dans un enum 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 égal à zéro, j'utilise false = 0,
plutôt que false,
Un autre avantage de l'utilisation des enums est l'intégration à l'IDE. true
, false
y bool
sont mis en évidence dans la plupart des IDE parce que ce sont des valeurs d'énumération et un typedef, par opposition à #defines
qui sont rarement mis en évidence par la syntaxe.
Curieux : Sans tenir compte du fait que cela fonctionne ou non, est-il valide en C(99+) de permettre à un enum de faire référence à une valeur antérieure dans le champ de l'enum. même énumération ?
@tgm1024 gcc -ansi -pedantic -Wall
ne donne aucun avertissement, donc je fais confiance à gcc
Si cela fonctionne même pour c89
cela devrait fonctionner pour c99
également.
@technosaurus Cette approche ne garantit pas que !false == true puisque !false peut être un nombre non nul. Une solution de contournement simple consisterait à affecter explicitement true à !false.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
90 votes
Le C a un type booléen. Du moins, il y en a un dans les normes les plus récentes.
12 votes
stackoverflow.com/questions/1608318/is-bool-a-native-c-type/
2 votes
Je sais que cette fois-ci, c'était il y a 11 ans, mais MERCI pour avoir posé cette question (et, ci-dessous - répondu) (ainsi que les commentaires ci-dessus !) @neuromancer ! //Best wishes in these corona times.