Soweit ich sehen kann, gibt es drei Möglichkeiten, Booleans in c zu verwenden
mit dem Typ bool, ab dann mit true und false
Definieren mit Präprozessor #define FALSE 0 ... #define TRUE !(FALSE)
Nur um Konstanten direkt zu verwenden, dh 1 und 0
Gibt es andere Methoden, die ich verpasst habe? Was sind die Vor- und Nachteile der verschiedenen Methoden?
Ich nehme an, die schnellste wäre Nummer 3, 2 ist immer noch leichter lesbar (obwohl die bitweise Negation den Overhead leicht erhöht), 1 ist am lesbarsten und nicht mit allen Compilern kompatibel.
Glaubst du wirklich, die Compiler warten bis zur Laufzeit, um eine Konstante zu negieren?
– GManNickG
12. Februar 2010 um 18:16 Uhr
Um nachzufassen, damit ich nicht wie ein Idiot wirke, kein Compiler wird tatsächlich seine Zeit damit verschwenden. Compiler sind starke Optimierer, und wenn sie wissen, dass die Ergebnisse immer gleich sein werden, fügt sie das stattdessen ein. Es wird nie bis zur Laufzeit warten, um es auszuwerten int i = 12 + 3 * 4;; es wird nur sagen int i = 24;. Sich über die Leistung Sorgen zu machen, ist ein häufiges Problem, fühlen Sie sich nicht schlecht. Optimierungen kommen letzte, und wenn es kommt, müssen Sie Ihren Code timen und sich die Assembly-Ausgabe ansehen, nicht raten. Selbst wenn es einen Zyklus gekostet hätte, würde ich mich für die am besten lesbare Lösung entscheiden. Erst als sich herausstellte, dass es sich um eine
– GManNickG
12. Februar 2010 um 18:21 Uhr
Problem würde ich zu einer schnelleren Lösung wechseln und sie zeitlich so einstellen, dass sie tatsächlich schneller sind. Wenn Sie die Wahl zwischen Lesbarkeit und einem Zyklus haben, wählen Sie Lesbarkeit. 🙂 Es ist einfach, guten Code schnell zu machen, aber schwer, “schnellen” Code gut zu machen.
– GManNickG
12. Februar 2010 um 18:23 Uhr
Denken Sie daran, wenn Sie die Makros verwenden (x == TRUE) ist nicht dasselbe wie (x). Ersteres gilt nur dann, wenn x hält den Wert von TRUE. Letzteres gilt für jeden Wert ungleich Null.
– Devon_C_Miller
12. Februar 2010 um 18:24 Uhr
Ich rate davon ab, spezielle boolesche Makros zu definieren; Dies verleitet nur unerfahrene Programmierer dazu, Dinge zu schreiben wie if(foo == TRUE) oder if(foo == FALSE)was in den meisten Sprachen eine Gräueltat ist, aber noch mehr in C, wo jeder Skalarwert != 0 wird in booleschen Kontexten als wahr angesehen; aus ähnlichen, aber weniger schwerwiegenden Gründen mag ich es nicht if(foo != NULL) und if(foo == NULL) für Zeiger; da dies keine Fehler im Vergleich zu einführen kann TRUE kann, ist nur Geschmackssache, aber Verwendung if(foo) und if(!foo) denn jeder skalare Wert ist imo mehr im Einklang mit dem Look-and-Feel der C-Sprache
– Christoph
12. Februar 2010 um 18:57 Uhr
CK Jung
Einfach einbeziehen <stdbool.h> wenn Ihr System dies bereitstellt. Das definiert eine Reihe von Makros, einschließlich bool, falseund true (definiert zu _Bool, 0 bzw. 1). Siehe Abschnitt 7.16 von C99 für weitere Einzelheiten.
Kein “bool” ist ein Makro. Der Typ ist “_Bool”. Andernfalls würde es schrecklich alten Code brechen.
– Lothar
12. Februar 2010 um 18:20 Uhr
Sie können verwenden _Bool ohne einzubeziehen stdbool.h
– Christoph
12. Februar 2010 um 18:46 Uhr
Verwenden Sie einfach 0 oder 1 direkt im Code.
Für C-Programmierer ist dies so intuitiv wie wahr oder falsch.
Für C-Programmierer gilt auch -1, da es keine Null ist. Übrigens sind 42 und -234 auch wahre Werte. Ich habe -1, -2 und andere Werte als wahr angesehen. Einige Funktionen geben 0 (Null) als erfolgreich zurück. Hmm, so viel zur Konsistenz.
– Thomas Matthäus
12. Februar 2010 um 19:04 Uhr
Ich sehe normalerweise nur 1 oder -1 als wahre Werte verwendet. -1, weil es binär nur Einsen sind. Ich würde gerne wissen, wo Sie -2 gefunden haben.
– Mike DeSimone
12. Februar 2010 um 19:16 Uhr
Ich stimme Thomas zu. Dass 0 als Fehlercode für „kein Fehler“ verwendet wird (und oft auch als int type) macht es manchmal nicht offensichtlich, ob ein Wert in einem booleschen Kontext verwendet werden soll.
– jamesdlin
12. Februar 2010 um 19:35 Uhr
Stellen Sie sich eine Funktion vor, die 0 für keinen Fehler zurückgibt, als Antwort auf die Frage “Hatten Sie ein Problem?” – “0=falsch=nein”. int fail = close(fd); if (!fail) { great(); } else { weep(); }
– Schreihals
14. Februar 2010 um 5:26 Uhr
@squelart: Das Problem ist, dass viele Funktionen, die boolesche Werte zurückgeben, diese Semantik nicht haben und bei Erfolg einen wahren Wert zurückgeben, bei Misserfolg einen falschen Wert. (Zum Beispiel ist ein Großteil der Win32-API auf diese Weise konzipiert.)
– jamesdlin
16. Februar 2010 um 4:06 Uhr
Normalerweise mache ich ein:
typedef enum {FALSE = 0, TRUE} boolean;
Warum setzen Sie explizit FALSE=0? Ist das erste Element einer Aufzählung nicht automatisch 0?
– Lindelof
13. August 2011 um 20:06 Uhr
@lindelof Es ist nur für den Fall, dass sie hinzufügen FileNotFound vor dieser Aufzählung. 😉
– C. K. Young
13. Februar 2013 um 22:08 Uhr
@lindelof Es macht Sinn. Sicherzustellen, dass FALSE 0 ist, ist das einzig Wichtige. WAHR kann alles sein, solange es anders ist.
– klutt
20. April 2019 um 10:26 Uhr
Mit dem in stdbool.h definierten bool-Typ treten Probleme auf, wenn Sie Code von einem neueren Compiler, der den bool-Typ unterstützt, auf einen älteren Compiler verschieben müssen. Dies könnte in einer eingebetteten Programmierumgebung passieren, wenn Sie zu einer neuen Architektur mit einem C-Compiler wechseln, der auf einer älteren Version der Spezifikation basiert.
Zusammenfassend würde ich bei den Makros bleiben, wenn es auf die Portabilität ankommt. Andernfalls tun Sie, was andere empfehlen, und verwenden Sie den eingebauten Typ.
Bob Wakefield
Egal für welche der drei Sie sich entscheiden, vergleichen Sie Ihre Variablen mit FALSE oder FALSE.
Historisch gesehen ist es eine schlechte Idee zu vergleichen irgendetwas auf wahr (1) in c oder c++. Nur false ist garantiert null (0). Wahr ist irgendein anderer Wert. Viele Compiler-Anbieter haben diese Definitionen irgendwo in ihren Headern.
#define TRUE 1
#define FALSE 0
Dies hat zu viele Menschen auf den Gartenpfad geführt. Außerdem viele Bibliotheksfunktionen chartype gibt Nicht-Null-Werte zurück, die ungleich sind 1 auf Erfolg. Es gibt eine Menge Legacy-Code mit dem gleichen Verhalten.
Mir ist aufgefallen, dass Vergleiche mit TRUE mit nicht initialisierten Variablen fehlschlagen. Es ist besser, Ihre booleschen Werte zu initialisieren und mit FALSE zu vergleichen. Eine Aufzählung ist besser, wenn Sie wirklich drei Werte benötigen; nein, ja und weiß nicht. Initialisieren Sie die Aufzählung mit donotknow. Behandeln Sie die Aufzählung nicht so, als wäre sie ein boolescher Wert. Es ist nicht.
– Bob Wakefield
1. September 2013 um 17:39 Uhr
Warum nicht #define TRUE !FALSE #define FALSE 0?
– Der unglaubliche Jan
21. September um 13:03 Uhr
Wallyk
Alle int-Werte außer Null sind wahr; falsch ist null. Auf diese Weise funktioniert Code wie dieser weiterhin wie erwartet:
int done = 0; // `int` could be `bool` just as well
while (!done)
{
// ...
done = OS_SUCCESS_CODE == some_system_call ();
}
Meiner Meinung nach, bool ist ein überbewerteter Typ, vielleicht ein Überbleibsel aus anderen Sprachen. int funktioniert gut als boolescher Typ.
Mir ist aufgefallen, dass Vergleiche mit TRUE mit nicht initialisierten Variablen fehlschlagen. Es ist besser, Ihre booleschen Werte zu initialisieren und mit FALSE zu vergleichen. Eine Aufzählung ist besser, wenn Sie wirklich drei Werte benötigen; nein, ja und weiß nicht. Initialisieren Sie die Aufzählung mit donotknow. Behandeln Sie die Aufzählung nicht so, als wäre sie ein boolescher Wert. Es ist nicht.
– Bob Wakefield
1. September 2013 um 17:39 Uhr
Warum nicht #define TRUE !FALSE #define FALSE 0?
– Der unglaubliche Jan
21. September um 13:03 Uhr
Nick van Brunt
Sie können testen, ob bool in c99 stdbool.h mit definiert ist
#ifndef __bool_true_false_are_defined || __bool_true_false_are_defined == 0
//typedef or define here
#endif
Sorry für meinen letzten Kommentar, meine PDF-Suchfunktion ist kaputt. Weitere Informationen finden Sie in Abschnitt 7.16 __bool_true_false_are_defined.
– C. K. Young
12. Februar 2010 um 18:33 Uhr
14198800cookie-checkVerwenden von true und false in Cyes
Glaubst du wirklich, die Compiler warten bis zur Laufzeit, um eine Konstante zu negieren?
– GManNickG
12. Februar 2010 um 18:16 Uhr
Um nachzufassen, damit ich nicht wie ein Idiot wirke, kein Compiler wird tatsächlich seine Zeit damit verschwenden. Compiler sind starke Optimierer, und wenn sie wissen, dass die Ergebnisse immer gleich sein werden, fügt sie das stattdessen ein. Es wird nie bis zur Laufzeit warten, um es auszuwerten
int i = 12 + 3 * 4;
; es wird nur sagenint i = 24;
. Sich über die Leistung Sorgen zu machen, ist ein häufiges Problem, fühlen Sie sich nicht schlecht. Optimierungen kommen letzte, und wenn es kommt, müssen Sie Ihren Code timen und sich die Assembly-Ausgabe ansehen, nicht raten. Selbst wenn es einen Zyklus gekostet hätte, würde ich mich für die am besten lesbare Lösung entscheiden. Erst als sich herausstellte, dass es sich um eine– GManNickG
12. Februar 2010 um 18:21 Uhr
Problem würde ich zu einer schnelleren Lösung wechseln und sie zeitlich so einstellen, dass sie tatsächlich schneller sind. Wenn Sie die Wahl zwischen Lesbarkeit und einem Zyklus haben, wählen Sie Lesbarkeit. 🙂 Es ist einfach, guten Code schnell zu machen, aber schwer, “schnellen” Code gut zu machen.
– GManNickG
12. Februar 2010 um 18:23 Uhr
Denken Sie daran, wenn Sie die Makros verwenden
(x == TRUE)
ist nicht dasselbe wie(x)
. Ersteres gilt nur dann, wennx
hält den Wert vonTRUE
. Letzteres gilt für jeden Wert ungleich Null.– Devon_C_Miller
12. Februar 2010 um 18:24 Uhr
Ich rate davon ab, spezielle boolesche Makros zu definieren; Dies verleitet nur unerfahrene Programmierer dazu, Dinge zu schreiben wie
if(foo == TRUE)
oderif(foo == FALSE)
was in den meisten Sprachen eine Gräueltat ist, aber noch mehr in C, wo jeder Skalarwert!= 0
wird in booleschen Kontexten als wahr angesehen; aus ähnlichen, aber weniger schwerwiegenden Gründen mag ich es nichtif(foo != NULL)
undif(foo == NULL)
für Zeiger; da dies keine Fehler im Vergleich zu einführen kannTRUE
kann, ist nur Geschmackssache, aber Verwendungif(foo)
undif(!foo)
denn jeder skalare Wert ist imo mehr im Einklang mit dem Look-and-Feel der C-Sprache– Christoph
12. Februar 2010 um 18:57 Uhr