Wann sollten Sie Bools in C ++ verwenden?

34

Wir hatten eine Aufgabe für unsere Klasse, bei der wir ein Tic-Tac-Toe- Spiel erstellen mussten . Die Leute machen sich gerne Komplikationen und schrieben komplexe Spiele mit Menüs. Am Ende des Spiels musste man die Option haben, erneut zu spielen oder das Programm zu beenden. Ich habe dafür eine intVariable verwendet, aber ich habe festgestellt, dass einige Klassenkameraden BOOLs verwenden.

Ist es effizienter? Was ist der Unterschied zwischen dem Speichern einer Antwort, in der nur zwei Werte gespeichert werden sollen, intund dem Speichern in einem Bool? Was ist der genaue Zweck dieser Variablen?

Bugster
quelle
32
Wir sind uns nicht sicher über die Effizienz, aber der Zweck von a intist das Speichern einer Ganzzahl und der Zweck von a boolist das Speichern eines Booleschen Wertes ( trueoder false). Die Verwendung eines boolIMO spiegelt seine Verwendung viel besser wider als die Verwendung eines int.
George Duckett
12
Tatsächlich hatte C89 vor C ++ und C99 keinen Booleschen Typ. Programmierer verwendeten häufig typedef int Booleinen Booleschen Wert, um deutlich zu machen, dass sie diesen verwendeten. C ++ integrierte Unterstützung für boolin die Sprache, ebenso wie C99 mit dem (ziemlich hässlichen) _BoolSchlüsselwort.
Charles Salvia
Es geht nicht darum, "zu wissen, wann es zu verwenden ist bool", sondern darum, warum wir unterschiedliche Namen für ähnliche Typen (wie length_t) haben und warum es wichtig ist, dass der Compiler Typen überprüft.
Abyx
Manchmal lautet die Antwort einfach "Geschmack". Ich wette, wenn Sie in diesem Moment die gleiche Aufgabe umschreiben, gibt es verschiedene Dinge wie die Reihenfolge der Funktionsparameter und ihre Namen. Warum haben Sie nicht die gleiche Parameterreihenfolge oder den gleichen Namen geschrieben? Es liegt daran, dass du es einfach nicht getan hast oder dass es nicht sehr wichtig war und du einfach alles geschrieben

Antworten:

82

Bei der Auswahl von Variablentypen und Variablennamen soll Ihre Absicht so klar wie möglich sein. Wenn Sie einen bool(booleschen) Typ auswählen , gibt es nur zwei zulässige Werte: trueoder false. Wenn Sie einen int(Ganzzahl-) Typ verwenden, ist nicht mehr klar, dass die Absicht dieser Variablen nur 1 oder 0 sein kann oder welche Werte Sie auch immer bedeuten möchten trueund false. Plus sizeof(int)gibt normalerweise 4 Bytes zurück, während sizeof(bool)1 zurückgegeben wird.

Andrew T. Finnell
quelle
7
Einverstanden. Ich denke, Designabsichten sind wichtiger. Nur gelegentlich müssen Sie sie überschreiben.
ChrisF
9
Um @ AndrewFinnels Punkt zu wiederholen: Bool ist selbstdokumentierender. Eine Variable, die Sie auf 0 oder 1 setzen, kann ein Zähler sein. Eine Variable, die Sie auf true oder false setzen, ist eindeutig ein Flag.
Scott C Wilson
2
Bools verhindern den Missbrauch einer Variablen für andere Zwecke. Eine Ganzzahl kann auf andere Werte als 0 oder 1 gesetzt werden, um zusätzliche Zustände zu erstellen, die Ihrem Code möglicherweise nicht bekannt sind.
Michael Shopsin
+1. Es macht die Absichten / Optionen klar. Sie können eine beliebige Methode verwenden, um den Wert zu speichern, einschließlich einer Zeichenfolge mit dem Wert "yes" oder "no". Wählen Sie jedoch die Methode aus, die am sinnvollsten ist. In diesem Fall ist das ein Boolescher Wert.
Craige
Ich dachte, Boolesche Werte in C ++ hätten die gleiche Größe wie ints, 4 Bytes.
DogDog
53

Es scheint in allen (bis jetzt) ​​gesammelten Antworten niemand aufgefallen zu sein, dass das OP darüber BOOLnicht sprach bool.

Da die Frage mit C ++ markiert ist, muss Folgendes beachtet werden:

  • inteine ganze Zahl , die von Bereich INT_MINzu INT_MAX- in definierten Makros , <climits>deren Werte sind abhängig von der Architektur des Hosting - Maschine. In C ++ diese Werte sind auch zugänglich std::numeric_limits<int>::min()und ...:max()jeweils). Das Verhalten von Booleschen Operatoren angewendet intbehandeln 0als falsch und alles andere als wahr .
  • BOOList nur ein Hinweis auf ein boolesches Verhalten für ein int. Es ist definiert in <cstddef>als

    #define BOOL int
    #define TRUE 1
    #define FALSE 0
  • BOOList also nichts weiter als syntaktischer Zucker, für was - vom Compiler - ist es nichts weiter als ein Int. Es ist etwas, das C-Programmierer verwenden, aber C ++ - Programmierer sollten es vermeiden, da C ++ dies hat bool.

  • boolist ein Sprachintegraltyp mit den unterstützten Werten just trueund false. Bei der Konvertierung in int truewird 1 und falsewird 0.

Der wichtige Aspekt ist, dass es vor Programmierfehlern sicherer ist:

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

Es ist unmöglich, mit dem richtigen Bool-Typ zu codieren:

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

Verwenden BOOLstatt boolist nur eine schlechte Angewohnheit, die von einer glorreichen Vergangenheit geerbt wurde, die niemand mehr vergessen kann, wodurch ein altes Problem für ein weniger glorreiches Morgen entsteht.

Sprachlehrer sollten ernsthaft darüber nachdenken!

Emilio Garavaglia
quelle
9
BOOL ist weder in C ++ noch in C enthalten. BOOL mit Großbuchstaben ist die häufigste Art, wie Boolesche Werte in C implementiert wurden. Früher hatte C keinen Booleschen Typ. Beispielsweise definiert die Windows-API BOOL. Außerdem ist nicht abzusehen, wie BOOL definiert ist. Einige Anwendungen definieren es möglicherweise als ein ein Bit langes Bitfeld. Sie können nicht davon ausgehen, dass es immer gleich int ist, nur weil es von einer bestimmten Bibliothek so definiert wird.
1
+1. Vielleicht hat er tatsächlich tat Mittelwert BOOL und nicht Bool. Vielleicht kann BOOL auf verschiedene Arten implementiert werden, obwohl Codereview das wahrscheinlich nicht weiß, wenn er diese Art von Frage stellt. Er sieht, dass es als int definiert ist, also fragt er sich natürlich, warum er nicht einfach int verwenden kann.
Neil
1
@Lundin: Im Allgemeinen haben Sie Recht, aber denken Sie, dass dies eine Antwort ist, die nicht in den Bereich der Frage fällt, in dem das OP über BOOL und int-Äquivalenz gesprochen hat.
Emilio Garavaglia
Trotzdem gilt die Idee, BOOL oder Bool zu verwenden, um Absichten zu kennzeichnen.
Andrew T Finnell
1
@zvrba: Stimmt, aber das liegt an der Art und Weise, wie MS beschlossen hat, Bool in seinen eigenen Compilern zu implementieren. Es gilt nur für MS-Compiler, die mit Intel-Prozessoren arbeiten. Beachten Sie, dass für Intel-Plattformen jeder Integraltyp, der kürzer als 32 Bit ist, eine Maskierung für die Eingabe oder Ausgabe erfordert. Aber char [] werden immer noch verwendet und nicht unbedingt immer durch int [] ersetzt
Emilio Garavaglia
6

Bool-Typen sind kleiner als Int-Typen und belegen daher weniger Speicherplatz. Abhängig von dem System, für das Sie kompilieren, kann ein Int 4 - 8 Byte lang sein, während ein Bool 1 Byte lang ist (wie in diesem MSDN-Artikel zu sehen ist ).

Kombinieren Sie dies mit einigen Aspekten von KISS und gutem Programmdesign, und es wird offensichtlich, warum es besser ist, einen Bool zum Speichern einer Variablen zu verwenden, die immer nur zwei Werte hat.

Warum komplizieren Sie Dinge mit einem Objekt, das einen weiten Bereich von Werten speichern kann, wenn Sie sicher sind, dass Sie immer nur 1 von 2 verschiedenen Werten speichern müssen?

Was passiert in dem System, das ein int verwendet, wenn Sie dort 75 speichern? Wenn Sie zusätzliche Bedingungen hinzugefügt haben

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

oder

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

Dann sind Sie für diese Situation abgesichert. Aber wenn nicht, dann nicht.

Sie könnten auch einen Fall haben (abhängig davon, wie Sie den Wert des int ändern), in dem Sie einen Pufferüberlauf haben und der Wert auf 0 oder die Untergrenze Ihres int "zurückgesetzt" wird (was irgendwo im sein könnte) Bereich von -127 bis -9.223.372.036.854.775.808, abhängig von Ihrer Zielarchitektur ) Was passiert dann in Ihrem Code?

Wenn Sie jedoch einen Bool verwenden, können Sie Folgendes verwenden:

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

Oder auch:

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

oder auch:

return continueBool;

Abhängig von Ihrem Compiler kann es Optimierungen für Code geben, der Bools verwendet, um zugeordnete True / False-Werte zu speichern. Während es möglicherweise keine Optimierungen für Ints gibt, die zum Speichern zugeordneter wahr / falsch-Werte verwendet werden.

Wir müssen auch daran denken, dass C ++ (zusammen mit C, Assembly und FORTRAN) verwendet wird, um hocheffizienten, kleinen und schnellen Code zu schreiben. Daher ist es in diesem Fall besser, einen Bool zu verwenden - insbesondere, wenn Sie auf die Verwendung von Variablen, Speicher, Cache oder Prozessorzeit hingewiesen werden.

Eine ähnliche Frage wäre: Warum sollte ich eine Ganzzahl (einen Wert) in einem Float speichern? Antwort: Das solltest du nicht, denn es hat keinen Sinn.

Lange Rede, kurzer Sinn: Als Ihr Lehrer / Tutor / Dozent / Professor müssen Sie die Größen verschiedener Werttypen durchgehen (falls Sie sie verpasst haben) und wissen, warum sie in der Softwareentwicklung wichtig sind.

Ich hoffe, das hilft als Ausgangspunkt (ich hoffe auch, dass es nicht pedantisch rüberkommt)

Jamie Taylor
quelle
4
Unnötige Verwendung von if () award. Schreiben Sie einfach return value >= 0;für das erste Beispiel.
Zvrba
Ich war mir nicht sicher, ob OP die Syntax versteht. Manchmal lohnt es sich, etwas ausführlicher als normal zu sein - zumal OP erwähnte, dass es sich um einen Auftrag handelte
Jamie Taylor,
2
Nicht zu widersprechen - aber nur darauf hinzuweisen, dass das Speichern von drei Bytes durch Auswahl eines Bools über einem Int keinen merklichen Unterschied für die meisten Programme bedeutet. Sorgen Sie sich nicht um Effizienz, bis Sie wirklich ein Leistungsproblem haben!
James Anderson
@James: In vielen Fällen werden Sie auch keine drei Bytes speichern, da die nächste Variable, sofern es sich nicht um einen anderen Bool oder ein Zeichen handelt, wahrscheinlich an einer Vier-Byte-Grenze ausgerichtet wird.
JeremyP
1

Der Zweck ist hier die Klarheit der Absicht. Der Rückgabetyp ist Teil einer Funktionsschnittstelle und boolsagt Ihnen mehr darüber aus, was Sie von der Funktion erwarten können, als a int.

Auch BOOList ausdrucksvoller als int, obwohl es die gleiche Art ist, zeigt es zumindest Ihre Absicht.

Keiner von ihnen ist jedoch das, was ich empfehlen würde:

enum class UiCmd {QUIT, START_GAME};
Kamikaze
quelle
-1

Beim Programmieren möchten Sie etwas aus dem realen Leben im Code darstellen. Obwohl ein Int und ein Bool dasselbe tun können, ist die untergeordnete Idee völlig anders: Wenn Sie einen Bool verwenden, lautet die Antwort möglicherweise Ja oder Nein. und das ist alles, das ist die absicht. Mit ganzen Zahlen können Sie Mengen ohne Dezimalstelle darstellen. Und warum sollten Sie in diesem Sinne eine ganze Zahl wählen, wenn ein Double dasselbe kann? Wenn eine Ganzzahl bei der Modellierung des Problems mehr Sinn macht als ein Double, können Sie eine Ganzzahl wählen.

fjrg76
quelle
1
Dies scheint nichts Wesentliches zu bieten über die Punkte, die in der oberen Antwort hier gemacht und erklärt wurden, die vor ungefähr 6 Jahren gepostet wurde
Mücke
-2

Denn am Ende werden Sie Ihre Ganzzahl sowieso in einen Booleschen Wert umwandeln: "Wenn (i = 1), dann spielen Sie ein anderes Spiel". In dieser Situation (i = 1) wird in true oder false konvertiert: ein Boolescher Wert.

Pieter B
quelle
hängt sehr davon ab, auf welchem ​​Rechner Sie laufen und welche Compiler involviert sind. Es mag Sie überraschen, dass ein einzelnes Zeichen-Flag mit "Y" oder "N" die effizienteste Methode zur Implementierung der Booleschen Logik ist, als dies auf IBM-Großrechnern der Fall ist.
James Anderson
4
Zu beachten ist , if (i = 1)ist wahrscheinlich die sehr falsche Sache im eigenen Code zu haben.