C hat keine eingebauten booleschen Typen. Wie kann man sie am besten in C verwenden?
Können Sie das näher erläutern warum sind sie die beste bis schlechteste Wahl?
C hat keine eingebauten booleschen Typen. Wie kann man sie am besten in C verwenden?
Vom Besten zum Schlechtesten:
Option 1 (C99 und neuere Versionen)
#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
Wenn Sie unentschlossen sind, wählen Sie die Nummer 1!
@endolith Die Ausrichtung, die Optimierungen und die Art und Weise der Speicherung eines <stdbool.h>
bool
der Compiler wählt, kann für den beabsichtigten Zweck eines booleschen Wertes besser geeignet sein als die Verwendung eines int
(d.h. der Compiler kann sich für die Implementierung eines bool
anders als ein int
). Wenn Sie Glück haben, kann dies auch zu einer strengeren Typüberprüfung bei der Kompilierung führen.
Warum verwenden int
für bool
? Das ist Verschwendung. Verwenden Sie unsigned char
. Oder verwenden Sie das in C eingebaute _Bool
.
Ein paar Gedanken zu Booleschen Werten in C:
Ich bin alt genug, dass ich nur einfache int
s als meinen booleschen Typ ohne Typendefinitionen oder spezielle Definitionen oder Enums für wahre/falsche Werte. Wenn Sie meinem Vorschlag folgen, niemals mit booleschen Konstanten zu vergleichen, müssen Sie ohnehin nur 0/1 verwenden, um die Flags zu initialisieren. Allerdings könnte ein solcher Ansatz in der heutigen Zeit als zu reaktionär angesehen werden. In diesem Fall sollte man auf jeden Fall <stdbool.h>
da es zumindest den Vorteil hat, dass es standardisiert ist.
Wie auch immer die booleschen Konstanten genannt werden, verwenden Sie sie nur zur Initialisierung. Schreiben Sie niemals etwas wie
if (ready == TRUE) ...
while (empty == FALSE) ...
Diese können immer durch die klarere Variante ersetzt werden
if (ready) ...
while (!empty) ...
Es ist zu beachten, dass diese Texte vernünftig und verständlich vorgelesen werden können.
Geben Sie Ihren booleschen Variablen positive Namen, d.h. full
anstelle von notfull
. Letzteres führt zu schwer lesbarem Code. Vergleiche
if (full) ...
if (!full) ...
をもって
if (!notfull) ...
if (notfull) ...
Die beiden erstgenannten Paare lesen sich natürlich, während !notfull
ist schon in seiner jetzigen Form schwer zu lesen und wird bei komplexeren booleschen Ausdrücken noch viel schlimmer.
Boolesche Argumente sollten generell vermieden werden. Betrachten Sie eine Funktion, die wie folgt definiert ist
void foo(bool option) { ... }
Innerhalb des Funktionskörpers ist es sehr klar, was das Argument bedeutet, da es einen praktischen und hoffentlich sinnvollen Namen hat. Aber die Aufrufseiten sehen aus wie
foo(TRUE);
foo(FALSE):
Hier ist es im Grunde unmöglich, die Bedeutung des Parameters zu erkennen, ohne sich die Funktionsdefinition oder -deklaration anzusehen, und es wird noch viel schlimmer, wenn Sie noch mehr boolesche Parameter hinzufügen. Ich schlage vor, entweder
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) { ... }
In jedem Fall sieht die Aufrufsite jetzt wie folgt aus
foo(OPT_ON);
foo(OPT_OFF);
die der Leser zumindest einigermaßen verstehen kann, ohne die Definition des Begriffs foo
.
Und wie kann man zwei Variablen auf Gleichheit vergleichen? Nie mit booleschen Konstanten funktioniert gut, aber es löst nicht das Problem, wenn der Vergleich gegen eine nicht-Konstante.
Verzeihen Sie mir, aber ich verstehe die Frage nicht. Fragen Sie, wie ich zwei boolesche Variablen auf Gleichheit vergleiche? Wenn ja, muss dann nicht a == b
arbeiten?
Es funktioniert nicht, weil "a" den Wert 3 haben könnte, was wahr ist, und "b" den Wert 5 haben könnte, was wahr ist. Aber a == b sollte auch wahr sein, was nicht der Fall ist, wenn es sich um Ints handelt.
Ein boolescher Wert in C ist eine ganze Zahl: Null für falsch und ungleich Null für wahr.
Siehe auch Boolescher Datentyp Abschnitt C, C++, Objective-C, AWK .
Hier ist die Version, die ich verwendet habe:
typedef enum { false = 0, true = !false } bool;
Weil false nur einen Wert hat, ein logisches true aber viele Werte haben kann, setzt die Technik true als das, was der Compiler für das Gegenteil von false verwendet.
Damit ist das Problem gelöst, dass jemand etwas kodiert, das auf diese Weise zustande kommt:
if (true == !false)
Ich denke, wir sind uns alle einig, dass das keine gute Praxis ist, aber für die einmaligen Kosten von "true = !false" beseitigen wir dieses Problem.
[EDIT] Am Ende habe ich verwendet:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
um Namenskollisionen mit anderen Systemen zu vermeiden, die true
y false
. Aber das Konzept bleibt das gleiche.
[EDIT] Um die Umwandlung von Integer in Boolean zu zeigen:
mybool somebool;
int someint = 5;
somebool = !!someint;
Die erste (rechte) ! konvertiert die Nicht-Null-Ganzzahl in eine 0, dann die zweite (linke) ! konvertiert die 0 in eine myfalse
Wert. Ich überlasse es dem Leser als Übung, eine ganze Zahl von Null zu konvertieren.
[EDIT] Es ist mein Stil, die explizite Einstellung eines Wertes in einer Aufzählung zu verwenden, wenn der spezifische Wert erforderlich ist, auch wenn der Standardwert derselbe wäre. Beispiel: Weil false Null sein muss, verwende ich false = 0,
statt false,
[EDIT] Zeigt, wie man die Größe von enum beim Kompilieren mit gcc begrenzt:
typedef __attribute__((__packed__)) enum { myfalse = 0, mytrue = !myfalse } mybool;
Das heißt, wenn es jemand tut:
struct mystruct {
mybool somebool1;
mybool somebool2;
mybool somebool3;
mybool somebool4;
}
beträgt die Größe der Struktur 4 Byte statt 16 Byte.
Ein weiterer Vorteil der Verwendung von Enums ist die IDE-Integration - true
, false
y bool
werden in den meisten IDEs hervorgehoben, weil sie Enum-Werte und ein Typedef sind, im Gegensatz zu #defines
die selten in der Syntax hervorgehoben werden.
Neugierig: Unabhängig davon, ob es tatsächlich funktioniert oder nicht, ist es gültig C(99+) zu erlauben, dass ein Enum einen früheren Wert in der gleiche Aufzählung ?
@tgm1024 gcc -ansi -pedantic -Wall
gibt keine Warnungen, also vertraue ich gcc
Wenn dies auch für c89
sollte es funktionieren für c99
ebenfalls.
Sie sind nicht als solche "eingebaut", sondern nur in der Include-Datei typisiert stdbool.h
Sie enthalten also typedef enum {false, true} bool;
in der Include-Datei
@JamesStevens Das ist nicht richtig. Es gibt einen eingebauten Typ namens _Bool
. Es handelt sich nicht um eine Aufzählung. bool
, true
y false
sind Makros, die in <stdbool.h>
die sich auf _Bool
, 1
y 0
beziehungsweise. Siehe de.cppreference.com/w/c/types/boolean
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
93 Stimmen
C hat einen booleschen Typ. Zumindest gibt es einen in den neuesten Standards.
12 Stimmen
stackoverflow.com/questions/1608318/is-bool-a-native-c-type/