Quand faut-il utiliser des bools en C ++?

34

Nous avions une tâche pour notre classe où nous devions créer un jeu de tic-tac-toe . Les gens aiment se compliquer, alors ils ont écrit des jeux complexes qui comprenaient des menus. À la fin du jeu, vous deviez avoir la possibilité de rejouer ou de quitter le programme. J'ai utilisé une intvariable pour cela, mais j'ai remarqué que certains de mes camarades de classe utilisaient des BOOL.

Est-ce plus efficace? Quelle est la différence entre stocker une réponse qui ne devrait stocker que deux valeurs dans un intplutôt que de le stocker dans un bool? Quel est le but exact de ces variables?

Bugster
la source
32
Pas sûr de l'efficacité, mais l'objectif d'un intest de stocker un entier et le but d'un boolest de stocker une valeur booléenne ( trueou false). L'utilisation d'une boolOMI reflète son utilisation bien mieux que celle d'un int.
George Duckett
12
En fait, avant C ++ et C99, C89 n’avait pas de type booléen. Les programmeurs le typedef int Boolfaisaient souvent pour préciser qu'ils utilisaient un booléen. C ++ a intégré le support booldans le langage, tout comme C99 avec le _Boolmot clé (plutôt laid) .
Charles Salvia
Il ne s'agit pas de "savoir quand utiliser bool", mais de savoir pourquoi nous avons des noms différents pour des types similaires (comme length_t) et pourquoi il est important que le compilateur vérifie les types.
Abyx
Parfois, la réponse est juste "goût". Je parie que si vous réécrivez votre même affectation maintenant, il y aura plusieurs choses différentes, telles que l'ordre des paramètres de la fonction et leurs noms. Pourquoi n'avez-vous pas écrit le même ordre de paramètre ou le même nom? C'est parce que vous venez de ne pas ou que ce n'était pas très important et que vous venez d'écrire quoi que ce soit

Réponses:

82

Lorsque vous choisissez des types et des noms de variable, vous voulez que votre intention soit aussi claire que possible. Si vous choisissez un type bool(booléen), il est clair qu'il n'y a que deux valeurs acceptables: trueou false. Si vous utilisez un type int(entier), il n'est plus clair que l'intention de cette variable ne peut être que 1 ou 0 ou peu importe les valeurs que vous avez choisi de signifier trueet false. Plus sizeof(int)retournera typiquement comme étant 4 octets, alors que sizeof(bool)retournera 1.

Andrew T Finnell
la source
7
D'accord. Je pense que les intentions de conception sont plus importantes. De temps en temps, vous devrez les remplacer.
ChrisF
9
Pour reprendre le point de @ AndrewFinnel: Bool est plus auto-documenté. Une variable que vous définissez sur 0 ou 1 pourrait être un compteur; une variable définie sur true ou false est clairement un indicateur.
Scott C Wilson
2
Les tabourets empêchent l'abus d'une variable pour d'autres utilisations. Un entier peut être défini sur une valeur autre que 0 ou 1 pour créer des états supplémentaires que votre code peut ne pas connaître.
Michael Shopsin
+1 Cela rend l'intention / les options claires. Vous pouvez utiliser n’importe quelle méthode pour stocker la valeur, y compris une chaîne avec la valeur "oui" ou "non", mais vous devez choisir celle qui a le plus de sens. Dans ce cas, c'est un booléen.
Craige
Je pensais que les booléens en C ++ avaient la même taille que ints, 4 octets.
DogDog
53

Il semble que dans toutes les réponses recueillies (jusqu'à maintenant), personne n'ait compris le fait que le PO BOOLn'en parlait pas bool.

Puisque la question est étiquetée C ++, il convient de noter que:

  • intest un nombre entier qui varie de INT_MINà INT_MAX- macros définies dans les <climits>valeurs qui dépendent de l'architecture de la machine hôte. En C ++, ces valeurs sont également accessibles en tant que std::numeric_limits<int>::min()et ...:max()respectivement). Le comportement des opérateurs booléens appliqués à inttraiter 0comme faux et tout le reste comme vrai .
  • BOOLest juste un indice suggérant un comportement booléen pour un int. Il est défini dans <cstddef>comme

    #define BOOL int
    #define TRUE 1
    #define FALSE 0
  • BOOLn’est donc rien de plus que du sucre syntaxique, pour quoi, par le compilateur, ce n’est rien de plus qu’un int. C’est quelque chose que les programmeurs C utilisent, mais les programmeurs C ++ devraient éviter, puisque C ++ l’a bool.

  • boolest un type de langage intégral dont les valeurs supportées sont justes trueet false. Lorsque converti en int truedevient 1 et falsedevient 0.

L'aspect important est qu'il est plus sûr contre les erreurs de programmation:

BOOL a = FALSE;  // in fact int a = 0;
a = 5; //now a == 5 -- what does it mean?;

est impossible de coder avec le type bool approprié:

bool a = false;
a = 5; // error: no bool(const int&) available.

Utiliser BOOLau lieu de boolest simplement une mauvaise habitude héritée d'un passé glorieux que personne n'est encore capable d'oublier, ce qui crée un vieux problème pour un avenir moins glorieux.

Les professeurs de langues devraient sérieusement y penser!

Emilio Garavaglia
la source
9
BOOL ne fait pas partie du langage C ++ ni du langage C. BOOL avec des majuscules est la méthode la plus utilisée pour implémenter les booléens en C, à l’époque où C n’avait pas de type booléen. Par exemple, l'API Windows définira BOOL. De plus, la définition de BOOL n'est pas connue, certaines applications peuvent définir ce champ comme un champ de bits long d'un bit. Vous ne pouvez pas supposer qu'il est toujours égal à int simplement parce qu'une bibliothèque spécifique le définit de cette façon.
1
+1 Peut-être qu'il a réellement voulu dire BOOL et pas bool. Peut-être que BOOL peut être implémenté de différentes manières, bien que Codereview ne le sache probablement pas s’il pose ce type de question. Il voit qu'il est défini comme un int, il demande donc naturellement pourquoi il ne peut pas simplement utiliser int.
Neil
1
@Lundin: en général, vous avez raison, mais considérez que c'est une réponse qui reste dans le champ de la question, où le PO a parlé de BOOL et d'int équivalence.
Emilio Garavaglia
Même dans ce cas, l'idée d'utiliser BOOL ou bool pour signifier une intention s'applique toujours.
Andrew T Finnell
1
@zvrba: vrai, mais cela est dû à la façon dont MS a décidé d'implémenter bool dans ses propres compilateurs. Il n'est valable que pour les compilateurs MS travaillant pour des processeurs Intel. Notez que, pour la plate-forme Intel, chaque type d'intégrale de moins de 32 bits nécessite un masquage en entrée ou en sortie. Mais les caractères [] sont toujours utilisés et ne sont pas nécessairement toujours remplacés par int []
Emilio Garavaglia
6

Les types de booléens sont plus petits que les types Int, utilisez donc moins d'espace en mémoire. Selon le système que vous compilez / pour, un int peut comporter 4 à 8 octets, tandis qu'un booléen est un octet (comme on peut le voir dans cet article MSDN )

Ajoutez à cela quelques aspects de KISS et une bonne conception de programme. Vous comprendrez pourquoi il est préférable d'utiliser un bool pour stocker une variable qui n'aura jamais que 2 valeurs.

Pourquoi trop compliquer les choses avec un objet pouvant stocker une large gamme de valeurs, alors que vous êtes sûr de ne jamais avoir besoin de stocker qu'une seule de deux valeurs différentes?

Que se passe-t-il dans le système qui utilise un int si vous en stockez 75? Si vous avez ajouté des conditions supplémentaires

if (value >= 0 )
  return true;  //value is greater than 0, thus is true
else
  return false; //value is 0 or smaller than 0, thus is false

ou

if (value == 0)
  return false;  //value is greater than 0, thus is true
else if (value == 1)
  return true; //value is 0 or smaller than 0, thus is false

alors vous êtes couvert pour cette situation. Mais si vous ne l'avez pas fait, alors vous ne l'êtes pas.

Vous pouvez également avoir un cas (en fonction de la façon dont vous modifiez la valeur de l'int) où vous avez un dépassement de tampon, et la valeur "réinitialisée" à 0 ou à la limite inférieure de votre int (qui peut se situer quelque part dans le région de -127 à −9,223,372,036,854,775,708, en fonction de votre architecture cible ) que se passe-t-il dans votre code alors?

Cependant, si vous utilisiez un bool, vous pourriez utiliser quelque chose comme ceci:

if(continueBool == true)
  return true;
else
  return false;

Ou même:

return (continueBool== true) ? true : false;

ou même:

return continueBool;

Selon votre compilateur, il peut exister des optimisations qu'il peut effectuer sur du code utilisant Bools pour stocker des valeurs true / false mappées. Tandis que, il n’existera peut-être pas d’optimisations possibles pour Ints utilisé pour stocker les valeurs true / false mappées.

Nous devons également nous rappeler que le C ++ (avec C, Assembly et FORTRAN) est utilisé pour écrire du code très efficace, petit et rapide. Il serait donc préférable d’utiliser un booléen dans ce cas, surtout si vous utilisez des variables, de la mémoire, du cache ou du temps processeur.

Une question similaire serait: pourquoi devrais-je stocker un entier (valeur) dans un float? Réponse: Vous ne devriez pas, car cela ne sert à rien.

Longue histoire: En tant que professeur / tuteur / conférencier / professeur, il vous expliquera les tailles de différents types de valeur (au cas où vous l'auriez manquée) et leur importance dans le développement de logiciels.

J'espère que cela aide comme point de départ (j'espère aussi que cela ne semble pas aussi pédant)

Jamie Taylor
la source
4
Utilisation inutile de if () award. Il suffit d'écrire return value >= 0;pour le premier exemple.
Zvrba
Je n'étais pas sûr du niveau de compréhension de la syntaxe par OP. Parfois, il est gratifiant d'être un peu plus verbeux que d'habitude - d'autant plus que OP a mentionné qu'il s'agissait d'une tâche
Jamie Taylor
2
Ne pas être en désaccord - mais juste souligner que sauver trois octets en choisissant un bool plutôt qu'un int ne va pas faire de différence notable pour la plupart des programmes. Ne vous inquiétez pas de l'efficacité jusqu'à ce que vous ayez vraiment un problème de performance!
James Anderson
@ James: dans de nombreux cas également, vous ne sauvegarderez pas trois octets, car la variable suivante, à moins qu'il s'agisse d'un autre caractère booléen ou d'un caractère, sera probablement alignée sur une limite de quatre octets.
JeremyP
1

Le but ici est la clarté de l'intention. Le type de retour fait partie d'une interface de fonctions et a boolvous en dit plus long sur ce à quoi vous pouvez vous attendre de la fonction int.

Even BOOLest plus expressif que int, même si c'est du même type, cela montre au moins votre intention.

Cependant, aucun d’entre eux n’est ce que je recommanderais:

enum class UiCmd {QUIT, START_GAME};
kamikaze
la source
-1

En programmation, vous voulez représenter quelque chose de la vie réelle dans le code. Même si un int et bool peuvent faire la même chose, l’idée sous-jacente est complètement différente: lorsqu’on utilise un bool, la réponse peut être oui ou non; et c'est tout, c'est l'intention. Avec des nombres entiers, vous pouvez représenter des quantités sans point décimal. Et dans le même esprit, pourquoi choisiriez-vous un entier quand un double peut faire la même chose? Si un entier a plus de sens qu'un double lors de la modélisation du problème, vous pouvez choisir un entier.

fjrg76
la source
1
cela ne semble offrir aucun avantage substantiel par rapport aux points soulevés et expliqués dans la réponse la plus haute ici publiée il y a environ 6 ans
gnat
-2

Parce que finalement, vous allez convertir votre entier en un booléen de toute façon: "if (i = 1) alors jouez un autre jeu". Dans cette situation, (i = 1) est converti en vrai ou en faux: un booléen.

Pieter B
la source
dépend beaucoup de la machine que vous utilisez et des compilateurs impliqués. Vous serez peut-être surpris d'apprendre que sur les ordinateurs centraux IBM, un indicateur à caractère unique avec "Y" ou "N" est le moyen le plus efficace d'implémenter la logique booléenne.
James Anderson
4
Il est à noter que if (i = 1)c'est probablement la très mauvaise chose à avoir dans son code.