Option 1 funktioniert nur, wenn Sie C99 verwenden, und dies ist die "Standardmethode". Wählen Sie dies wenn möglich.
Die Optionen 2, 3 und 4 haben in der Praxis das gleiche identische Verhalten. # 2 und # 3 verwenden jedoch keine #defines, was meiner Meinung nach besser ist.
Können Sie erläutern, warum sie die besten bis schlechtesten Entscheidungen sind?
Endolith
1
@endolith Die Ausrichtung, Optimierung und Art der Speicherung eines <stdbool.h>boolvom Compiler ausgewählten Werts ist möglicherweise für den beabsichtigten Zweck eines booleschen Werts besser geeignet als die Verwendung eines int(dh der Compiler kann sich dafür entscheiden, einen boolanderen als einen zu implementieren int). Wenn Sie Glück haben, kann dies auch zu einer strengeren Typprüfung beim Kompilieren führen.
blubberdiblub
1
Warum intfür verwenden bool? Das ist verschwenderisch. Verwenden Sie unsigned char. Oder C des builtin verwenden _Bool.
Asadefa
@NoBody Die Verwendung eines kleineren Typs kann Speicherplatz sparen, macht ihn jedoch möglicherweise nicht schneller. Oft ist es schneller, die native Wortgröße des Prozessors anstelle einer kleineren Größe zu verwenden, da der Compiler möglicherweise Bitverschiebungen vornehmen muss, um sie richtig auszurichten
Ted Klein Bergman,
241
Ein paar Gedanken zu Booleschen Werten in C:
Ich bin alt genug, dass ich nur einfaches ints als meinen booleschen Typ verwende, ohne typedefs oder spezielle Definitionen oder Aufzählungen für wahre / falsche Werte. Wenn Sie meinem Vorschlag unten folgen, niemals mit booleschen Konstanten zu vergleichen, müssen Sie ohnehin nur 0/1 verwenden, um die Flags zu initialisieren. Ein solcher Ansatz kann jedoch in diesen modernen Zeiten als zu reaktionär angesehen werden. In diesem Fall sollte man auf jeden Fall verwenden, <stdbool.h>da es zumindest den Vorteil hat, standardisiert zu werden.
Unabhängig davon, wie die booleschen Konstanten heißen, verwenden Sie sie nur zur Initialisierung. Schreibe niemals so etwas
if(ready == TRUE)...while(empty == FALSE)...
Diese können immer durch den Reiniger ersetzt werden
if(ready)...while(!empty)...
Beachten Sie, dass diese tatsächlich vernünftigerweise und verständlich laut vorgelesen werden können.
Geben Sie Ihren booleschen Variablen positive Namen, dh fullanstelle von notfull. Letzteres führt zu schwer lesbarem Code. Vergleichen Sie
if(full)...if(!full)...
mit
if(!notfull)...if(notfull)...
Beide der ersteren Paare lesen natürlich, während !notfulles schwierig ist, es zu lesen, und es wird in komplexeren booleschen Ausdrücken viel schlimmer.
Boolesche Argumente sollten generell vermieden werden. Stellen Sie sich eine so definierte Funktion vor
void foo(bool option){...}
Innerhalb des Hauptteils der Funktion ist sehr klar, was das Argument bedeutet, da es einen bequemen und hoffentlich bedeutungsvollen Namen hat. Die Anrufseiten sehen jedoch so aus
foo(TRUE);
foo(FALSE):
Hier ist es im Wesentlichen unmöglich zu sagen, was der Parameter bedeutet, ohne immer die Funktionsdefinition oder Deklaration zu betrachten, und es wird viel schlimmer, sobald Sie noch mehr boolesche Parameter hinzufügen. Ich schlage auch vor
Und wie vergleicht man zwei Variablen auf Gleichheit? Die Verwendung von Booleschen Konstanten funktioniert niemals gut, löst jedoch das Problem beim Vergleich mit einer Nichtkonstante nicht.
Baruch
Vergib mir, aber ich verstehe die Frage nicht. Fragen Sie sich, wie ich zwei boolesche Variablen auf Gleichheit vergleiche? Wenn ja, funktioniert das nicht a == b?
Dale Hagglund
5
@ Kenji Was Sie sagen, ist wahr, obwohl ich glaube, dass es fast immer eine schlechte Idee ist, andere Werte als einen als Äquivalent für wahr zu verwenden. In Ihrem Beispiel würde ich stattdessen empfehlen , dies anzunehmen aund bvon Null hochzuzählen a > 0 == b > 0. Wenn Sie darauf bestehen, die Wahrhaftigkeit beliebiger Werte ungleich Null auszunutzen, erhalten Sie !!varden booleschen Wert 0/1, der äquivalent ist var, sodass Sie schreiben können !!a == !!b, obwohl einige Leser dies verwirrend finden.
Dale Hagglund
3
!a == !bist auch ausreichend, um die Gleichheit zu testen, Nicht-Nullen werden Null und Nullen werden Eins.
Ryanpattison
5
@rpattiso Sie haben natürlich ganz recht, aber ich denke, ich würde !!aals "nicht-boolesches a in seinen äquivalenten Wahrheitswert konvertieren" lesen, während ich !aals "logisch invertieren der booleschen Variablen a" lesen würde . Insbesondere würde ich nach einem bestimmten Grund suchen, aus dem die logische Umkehrung gewünscht wurde.
Dale Hagglund
88
Ein Boolescher Wert in C ist eine Ganzzahl: Null für falsch und Nicht-Null für wahr.
Es funktioniert auch gut mit logischen Operatoren (&& und ||).
Vultrao
74
Hier ist die Version, die ich verwendet habe:
typedefenum{false=0,true=!false}bool;
Da false nur einen Wert hat, ein logisches true jedoch viele Werte haben kann, setzt die Technik true so, wie es der Compiler für das Gegenteil von false verwendet.
Dies behebt das Problem, dass jemand etwas codiert, das darauf zurückzuführen wäre:
if(true==!false)
Ich denke, wir sind uns alle einig, dass dies keine gute Praxis ist, aber für die einmaligen Kosten für "true =! False" beseitigen wir dieses Problem.
Der erste (ganz rechts)! wandelt die Ganzzahl ungleich Null in eine 0 um, dann die zweite (ganz links)! wandelt die 0 in einen myfalseWert um. Ich werde es dem Leser als Übung überlassen, eine Null-Ganzzahl umzuwandeln.
[BEARBEITEN] Es ist mein Stil, die explizite Einstellung eines Werts in einer Aufzählung zu verwenden, wenn der spezifische Wert erforderlich ist, selbst wenn der Standardwert der gleiche wäre. Beispiel: Da false Null sein muss, verwende ich false = 0,eher alsfalse,
Auch ein weiterer Vorteil Aufzählungen zu verwenden ist die IDE - Integration - true, falseund boolsind die in den meisten IDE hervorgehoben , weil sie ENUM - Werte und ein typedef sind, im Gegensatz zu #defines, die sind selten jemals Syntax - Hervorhebungen.
Neugierig: Wenn man ignoriert, ob es tatsächlich funktioniert oder nicht, ist es C (99+) gültig, damit eine Aufzählung auf einen vorherigen Wert in derselben Aufzählung verweist ?
@ tgm1024 gcc -ansi -pedantic -Wallgibt keine Warnungen, also vertraue ich gcc; Wenn dies auch für funktioniert, c89sollte es auch funktionieren c99.
yyny
1
"Weil false nur einen Wert hat, aber ein logisches true viele Werte haben kann, aber die Technik setzt true so, wie es der Compiler für das Gegenteil von false verwendet." Der Negationsoperator !kann nur Werte zurückgeben 0und 1weist daher true = !falseimmer den Wert 1 zu. Diese Methode bietet keine zusätzliche Sicherheit typedef enum { false, true } bool;.
user694733
1
Das früheste, was ich gefunden habe, stammt aus C90 (6.3.3.3 Unäre arithmetische Operatoren): "Das Ergebnis des logischen Negationsoperators! Ist 0, wenn der Wert seines Operanden ungleich 0,1 ist. 1, wenn der Wert seines Operanden gleich 0 ist Ergebnis hat den Typ int. Der Ausdruck! E entspricht (O == E). " Dies sollte jeden Compiler abdecken, der jemals behauptet hat, Standard C zu unterstützen. Compiler können diese Regel natürlich rechtlich ignorieren, wenn dies für das beobachtbare Verhalten (wie if(!value)) nicht von Bedeutung ist, aber diese Ausnahme gilt in diesem speziellen Fall nicht.
user694733
48
Wenn Sie einen C99-Compiler verwenden, bietet dieser eine integrierte Unterstützung für Bool-Typen:
#include<stdbool.h>int main(){bool b =false;
b =true;}
Das wichtigste zuerst. C, dh ISO / IEC 9899 hat seit 19 Jahren einen booleschen Typ . Das ist viel länger als die erwartete Länge der C-Programmierkarriere mit Amateur- / akademischen / professionellen Teilen, die beim Besuch dieser Frage kombiniert werden . Meins übertrifft das nur um 1-2 Jahre. Dies bedeutet, dass während der Zeit , in der ein durchschnittlicher Leser überhaupt etwas über C gelernt hat, C tatsächlich den booleschen Datentyp hatte .
Für den Datentyp #include <stdbool.h>und Verwendung true, falseund bool. Oder ist es nicht, und die Verwendung _Bool, 1und 0stattdessen.
In den anderen Antworten auf diesen Thread werden verschiedene gefährliche Praktiken beschrieben. Ich werde sie ansprechen:
typedefintbool;#definetrue1#definefalse0
Dies ist ein Nein-Nein, da ein Gelegenheitsleser - der in diesen 19 Jahren C gelernt hat - erwarten würde, dass boolsich dies auf den tatsächlichenbool Datentyp bezieht und sich ähnlich verhält, dies jedoch nicht! Zum Beispiel
double a =...;bool b = a;
Mit C99 bool/ _Bool, bwürde eingestellt werden , um falseiffa Null war, und truesonst. C11 6.3.1.2p1
Wenn ein Skalarwert in konvertiert wird, _Boolist das Ergebnis 0, wenn der Wert gleich 0 ist. Andernfalls ist das Ergebnis 1. 59)
Fußnoten
59) NaNs sind nicht gleich 0 und wandeln sich daher in 1 um.
Mit dem typedefan Ort und Stelle, das doublewäre einen gezwungen werden int- wenn der Wert des Doppels ist nicht in dem Bereich für intdas Verhalten ist nicht definiert .
Gleiches gilt natürlich auch, wenn trueund falsein einem deklariert wurden enum.
Was noch gefährlicher ist, ist zu erklären
typedefenumbool{false,true}bool;
Da jetzt alle Werte außer 1 und 0 ungültig sind und ein solcher Wert einer Variablen dieses Typs zugewiesen werden sollte, wäre das Verhalten völlig undefiniert .
Daher iff Sie nicht C99 aus unerklärlichen Gründen, für boolean Variablen verwenden können , sollten Sie verwenden:
Typ intund Werte 0und 1wie sie sind ; und führen Sie sorgfältig Domain-Konvertierungen von anderen Werten zu diesen mit doppelter Negation durch!!
oder wenn Sie darauf bestehen , Sie sich nicht erinnern , dass 0 ist falsy und Nicht-Null Truish, zumindest Verwendung oberen Fall , so dass sie mit den C99 - Konzepte werden nicht verwirrt: BOOL, TRUEund FALSE!
Welcher Teil des C-Standards würde Objekte mit aufgezählten Typen darauf beschränken, die darin explizit aufgeführten Werte zu halten? Wenn der größte Wert für eine Aufzählungs Konstante kleiner als UCHAR_MAX oder USHRT_MAX ist, könnte eine Implementierung einen Typen verwenden , die kleiner als intoder unsigned inteine Aufzählung zu halten, aber ich weiß von nichts in der Norm , die eine Aufzählung verursachen würde als etwas anderes als eine ganze Zahl verhalten Art.
@technosaurus Dieser Ansatz garantiert nicht! false == true, da! false eine beliebige Zahl ungleich Null sein kann. Eine einfache Umgehung wäre, explizit! Falsch true zuzuweisen.
Andrew
3
@ Andrew Das stimmt nicht. !0 = 1nach dem C-Standard und !a = 0für jeden Wert ungleich Null von a. Das Problem ist, dass jede Nicht-Null als wahr angesehen wird. Also , wenn aund bbeide „wahr“ ist , ist es nicht unbedingt der Fall , dass `a == b '.
Jeremy West
14
C hat einen booleschen Typ: bool (zumindest für die letzten 10 (!) Jahre)
Fügen Sie stdbool.h hinzu und true / false funktioniert wie erwartet.
10 Jahre im Standard, aber nicht 10 Jahre in Compilern! Die C-Kompilierung von MSVC ++ unterstützt C99 überhaupt nicht, außer // Kommentare zuzulassen, und wird dies wahrscheinlich nie tun. Außerdem ist _Bool in C99 als integrierter Typ definiert, während bool ein typedef im Header <stdbool.h> ist.
Clifford
5
@ Clifford 4 Jahre nach Ihrem Kommentar ... nichts hat sich geändert. MSVC ist ein C ++ - Compiler, und ich glaube, MS hat gesagt, dass sie nicht wirklich daran interessiert sind, alle neuen C-Funktionen (C99 & C11) zu unterstützen. Aber ich kann nicht davon ausgehen, dass MSVC keine neuen C-Funktionen als Grund unterstützt (insbesondere, wenn Sie dies gegen eine Antwort von 10 Jahren sagen ). 10 Jahre sind wirklich eine lange Zeit in der Programmierwelt. Jeder anständige Compiler sollte in weniger als 10 Jahren Unterstützung dafür haben, wenn der Anbieter dies unterstützen soll.
PP
2
@KingsIndian: Ich bin mir nicht sicher, warum Sie Ihren Kommentar an mich gerichtet haben oder überhaupt das Bedürfnis hatten, überhaupt einen Kommentar abzugeben. Ich habe nur die Situation zum Zeitpunkt des Schreibens angegeben. Ich habe diese Situation nicht unterstützt und lediglich darauf hingewiesen, dass die "Antwort" möglicherweise nicht unter allen Umständen gilt.
Clifford
@ Clifford: Streng genommen muss der Standard boolein Makro sein, das erweitert wird _Bool. Der Unterschied ist wichtig, weil Sie #undefein Makro können (und das ist zumindest als Übergangsmaßnahme zulässig), aber Sie können kein untypedeftypedef. Es ändert jedoch nichts an der Hauptausrichtung Ihres ersten Kommentars.
Jonathan Leffler
2
VS2015 und später (& möglicherweise früher, bis zu einem Punkt) hat kein Problem mit booldurch <stdbool.h>unter C Kompilierung. Es löst sich auf _Bool.
11
Alles, was ungleich Null ist, wird in booleschen Operationen als wahr ausgewertet
Verwenden Sie sie jedoch mit Vorsicht: Da ein echtes Ergebnis ein Wert ungleich Null sein kann, sind die Tests if (t == TRUE) {...} und if (t), die in anderen Sprachen äquivalent sind, in C nicht äquivalent .
Fortega
1
Sie haben Recht, aber das gilt auch für C ++, das einen Bool-Typ hat, oder? Während des Debuggens habe ich Bool-Variablen mit Werten von 5837834939 gesehen ...
Ggambett
1
In C ++ entspricht der if (t == true) -Test dem if (t) -Test, da C ++ eine Konvertierung durchführt (alles, was nicht 0 oder ein Nullzeigerwert ist, wird in true konvertiert)
Fortega
6
Alles, was Sie über einen booleschen wahren Wert annehmen sollten, ist, dass er nicht Null ist. Code wie if (b) ist also sicher, if if (b == TRUE) nicht; Letzteres ist schlechte Praxis (und sinnlos).
Clifford
5
Nur eine Ergänzung zu anderen Antworten und einige Erläuterungen, wenn Sie C99 verwenden dürfen.
+-------+----------------+-------------------------+--------------------+|Name|Characteristic|Dependence in stdbool.h |Value|+-------+----------------+-------------------------+--------------------+|_Bool|Native type |Don't need header ||+-------+----------------+-------------------------+--------------------+|bool|Macro|Yes|Translate to _Bool|+-------+----------------+-------------------------+--------------------+|true|Macro|Yes|Translate to 1|+-------+----------------+-------------------------+--------------------+|false|Macro|Yes|Translate to 0|+-------+----------------+-------------------------+--------------------+
Einige meiner Vorlieben:
_Booloder bool? Beide sind in Ordnung, sehen aber boolbesser aus als das Schlüsselwort _Bool.
Akzeptierte Werte für boolund _Boolsind: falseoder true. Zuweisen 0oder 1anstelle von falseoder trueist gültig, aber es ist schwieriger, den Logikfluss zu lesen und zu verstehen.
Einige Infos aus dem Standard:
_Boolist NICHT unsigned int, ist aber Teil der Gruppe vorzeichenloser Ganzzahltypen . Es ist groß genug, um die Werte 0oder zu halten 1.
NICHT, aber ja, Sie können neu definieren booltrueund falsedas ist sicher keine gute Idee. Diese Fähigkeit gilt als veraltet und wird in Zukunft entfernt.
Das Zuweisen eines Skalartyps (arithmetische Typen und Zeigertypen) zu _Booloder bool, wenn der Skalarwert gleich ist 0oder mit diesem verglichen 0wird, ist 0, andernfalls lautet das Ergebnis 1: _Bool x = 9;9wird konvertiert, 1wenn es zugewiesen wird x.
_Boolist 1 Byte (8 Bit), normalerweise ist der Programmierer versucht, die anderen Bits zu verwenden, wird jedoch nicht empfohlen, da nur garantiert wird, dass nur ein Bit zum Speichern von Daten verwendet wird, nicht wie bei einem Typ charmit 8 Bits verfügbar.
Auch in C ist es normalerweise ein int, und es kann zu einem Verlust von Präzisionswarnungen durch anderen Code führen, der int verwendet.
Thomas Bonini
Wenn Sie nicht für den Speicherplatz von Hand optimieren, ist es immer besser, die normale Wortgröße der Hardware zu verwenden (z. B. normalerweise eine int), da Sie bei einigen Architekturen einen erheblichen Leistungseinbruch erzielen, wenn Sie diese Variablen entpacken / maskieren müssen.
Kingsley
2
Sie könnten _Bool verwenden, aber der Rückgabewert muss eine Ganzzahl sein (1 für wahr, 0 für falsch). Es wird jedoch empfohlen, bool wie in C ++ einzuschließen und zu verwenden, wie in
dieser Antwort aus dem daniweb-Forum sowie in dieser Antwort aus dieser anderen Stackoverflow-Frage angegeben:
_Bool: Der boolesche Typ von C99. Die direkte Verwendung von _Bool wird nur empfohlen, wenn Sie Legacy-Code verwalten, der bereits Makros für bool, true oder false definiert. Andernfalls werden diese Makros im Header standardisiert. Wenn Sie diesen Header einschließen, können Sie bool wie in C ++ verwenden.
Bedingte Ausdrücke gelten als wahr, wenn sie nicht Null sind. Der C-Standard verlangt jedoch, dass logische Operatoren selbst entweder 0 oder 1 zurückgeben.
@ Tom: #define TRUE! FALSE ist schlecht und völlig sinnlos. Wenn die Header-Datei in kompilierten C ++ - Code gelangt, kann dies zu Problemen führen:
void foo(bool flag);...int flag = TRUE;
foo(flag);
Einige Compiler generieren eine Warnung über die Konvertierung von int => bool. Manchmal vermeiden die Leute dies, indem sie Folgendes tun:
foo(flag == TRUE);
um den Ausdruck als C ++ - Bool zu erzwingen. Aber wenn Sie TRUE! FALSE definieren, erhalten Sie:
foo(flag ==!0);
Dies führt zu einem Int-to-Bool-Vergleich, der die Warnung trotzdem auslösen kann.
Wenn Sie C99 verwenden, können Sie den _BoolTyp verwenden. Es #includesind keine s erforderlich. Sie müssen es jedoch wie eine Ganzzahl behandeln, wo 1ist trueund 0ist false.
Sie können dann TRUEund definieren FALSE.
_Bool this_is_a_Boolean_var =1;//or using it with true and false#define TRUE 1#define FALSE 0_Bool var = TRUE;
Das NOT-Makro sollte durch Klammern um argund den Ausdruck als Ganzes geschützt werden : #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). Es wäre jedoch besser, auf Falschheit zu testen (es wird die richtige Antwort geben, selbst wenn arg23 statt 0 oder 1 war : #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE). Aber der gesamte Ausdruck kann #define NOT(arg) (!(arg))natürlich auf das reduziert werden , was das gleiche Ergebnis liefert.
Antworten:
Vom Besten zum Schlechten:
Option 1 (C99)
Option 2
Option 3
Option 4
Erläuterung
Wenn Sie unentschlossen sind, gehen Sie mit # 1!
quelle
<stdbool.h>
bool
vom Compiler ausgewählten Werts ist möglicherweise für den beabsichtigten Zweck eines booleschen Werts besser geeignet als die Verwendung einesint
(dh der Compiler kann sich dafür entscheiden, einenbool
anderen als einen zu implementierenint
). Wenn Sie Glück haben, kann dies auch zu einer strengeren Typprüfung beim Kompilieren führen.int
für verwendenbool
? Das ist verschwenderisch. Verwenden Sieunsigned char
. Oder C des builtin verwenden_Bool
.Ein paar Gedanken zu Booleschen Werten in C:
Ich bin alt genug, dass ich nur einfaches
int
s als meinen booleschen Typ verwende, ohne typedefs oder spezielle Definitionen oder Aufzählungen für wahre / falsche Werte. Wenn Sie meinem Vorschlag unten folgen, niemals mit booleschen Konstanten zu vergleichen, müssen Sie ohnehin nur 0/1 verwenden, um die Flags zu initialisieren. Ein solcher Ansatz kann jedoch in diesen modernen Zeiten als zu reaktionär angesehen werden. In diesem Fall sollte man auf jeden Fall verwenden,<stdbool.h>
da es zumindest den Vorteil hat, standardisiert zu werden.Unabhängig davon, wie die booleschen Konstanten heißen, verwenden Sie sie nur zur Initialisierung. Schreibe niemals so etwas
Diese können immer durch den Reiniger ersetzt werden
Beachten Sie, dass diese tatsächlich vernünftigerweise und verständlich laut vorgelesen werden können.
Geben Sie Ihren booleschen Variablen positive Namen, dh
full
anstelle vonnotfull
. Letzteres führt zu schwer lesbarem Code. Vergleichen Siemit
Beide der ersteren Paare lesen natürlich, während
!notfull
es schwierig ist, es zu lesen, und es wird in komplexeren booleschen Ausdrücken viel schlimmer.Boolesche Argumente sollten generell vermieden werden. Stellen Sie sich eine so definierte Funktion vor
Innerhalb des Hauptteils der Funktion ist sehr klar, was das Argument bedeutet, da es einen bequemen und hoffentlich bedeutungsvollen Namen hat. Die Anrufseiten sehen jedoch so aus
Hier ist es im Wesentlichen unmöglich zu sagen, was der Parameter bedeutet, ohne immer die Funktionsdefinition oder Deklaration zu betrachten, und es wird viel schlimmer, sobald Sie noch mehr boolesche Parameter hinzufügen. Ich schlage auch vor
oder
In beiden Fällen sieht die Anrufseite jetzt so aus
was der Leser zumindest eine Chance hat zu verstehen, ohne die Definition von auszubaggern
foo
.quelle
a == b
?a
undb
von Null hochzuzählena > 0 == b > 0
. Wenn Sie darauf bestehen, die Wahrhaftigkeit beliebiger Werte ungleich Null auszunutzen, erhalten Sie!!var
den booleschen Wert 0/1, der äquivalent istvar
, sodass Sie schreiben können!!a == !!b
, obwohl einige Leser dies verwirrend finden.!a == !b
ist auch ausreichend, um die Gleichheit zu testen, Nicht-Nullen werden Null und Nullen werden Eins.!!a
als "nicht-boolesches a in seinen äquivalenten Wahrheitswert konvertieren" lesen, während ich!a
als "logisch invertieren der booleschen Variablen a" lesen würde . Insbesondere würde ich nach einem bestimmten Grund suchen, aus dem die logische Umkehrung gewünscht wurde.Ein Boolescher Wert in C ist eine Ganzzahl: Null für falsch und Nicht-Null für wahr.
Siehe auch Boolescher Datentyp , Abschnitt C, C ++, Objective-C, AWK .
quelle
Hier ist die Version, die ich verwendet habe:
Da false nur einen Wert hat, ein logisches true jedoch viele Werte haben kann, setzt die Technik true so, wie es der Compiler für das Gegenteil von false verwendet.
Dies behebt das Problem, dass jemand etwas codiert, das darauf zurückzuführen wäre:
Ich denke, wir sind uns alle einig, dass dies keine gute Praxis ist, aber für die einmaligen Kosten für "true =! False" beseitigen wir dieses Problem.
[EDIT] Am Ende habe ich verwendet:
um eine Namenskollision mit anderen Schemata zu vermeiden, die
true
und definiert wurdenfalse
. Das Konzept bleibt jedoch dasselbe.[EDIT] So zeigen Sie die Konvertierung einer Ganzzahl in einen Booleschen Wert an:
Der erste (ganz rechts)! wandelt die Ganzzahl ungleich Null in eine 0 um, dann die zweite (ganz links)! wandelt die 0 in einen
myfalse
Wert um. Ich werde es dem Leser als Übung überlassen, eine Null-Ganzzahl umzuwandeln.[BEARBEITEN] Es ist mein Stil, die explizite Einstellung eines Werts in einer Aufzählung zu verwenden, wenn der spezifische Wert erforderlich ist, selbst wenn der Standardwert der gleiche wäre. Beispiel: Da false Null sein muss, verwende ich
false = 0,
eher alsfalse,
quelle
true
,false
undbool
sind die in den meisten IDE hervorgehoben , weil sie ENUM - Werte und ein typedef sind, im Gegensatz zu#defines
, die sind selten jemals Syntax - Hervorhebungen.gcc -ansi -pedantic -Wall
gibt keine Warnungen, also vertraue ichgcc
; Wenn dies auch für funktioniert,c89
sollte es auch funktionierenc99
.!
kann nur Werte zurückgeben0
und1
weist dahertrue = !false
immer den Wert 1 zu. Diese Methode bietet keine zusätzliche Sicherheittypedef enum { false, true } bool;
.if(!value)
) nicht von Bedeutung ist, aber diese Ausnahme gilt in diesem speziellen Fall nicht.Wenn Sie einen C99-Compiler verwenden, bietet dieser eine integrierte Unterstützung für Bool-Typen:
http://en.wikipedia.org/wiki/Boolean_data_type
quelle
Das wichtigste zuerst. C, dh ISO / IEC 9899 hat seit 19 Jahren einen booleschen Typ . Das ist viel länger als die erwartete Länge der C-Programmierkarriere mit Amateur- / akademischen / professionellen Teilen, die beim Besuch dieser Frage kombiniert werden . Meins übertrifft das nur um 1-2 Jahre. Dies bedeutet, dass während der Zeit , in der ein durchschnittlicher Leser überhaupt etwas über C gelernt hat, C tatsächlich den booleschen Datentyp hatte .
Für den Datentyp
#include <stdbool.h>
und Verwendungtrue
,false
undbool
. Oder ist es nicht, und die Verwendung_Bool
,1
und0
stattdessen.In den anderen Antworten auf diesen Thread werden verschiedene gefährliche Praktiken beschrieben. Ich werde sie ansprechen:
Dies ist ein Nein-Nein, da ein Gelegenheitsleser - der in diesen 19 Jahren C gelernt hat - erwarten würde, dass
bool
sich dies auf den tatsächlichenbool
Datentyp bezieht und sich ähnlich verhält, dies jedoch nicht! Zum BeispielMit C99
bool
/_Bool
,b
würde eingestellt werden , umfalse
iffa
Null war, undtrue
sonst. C11 6.3.1.2p1Mit dem
typedef
an Ort und Stelle, dasdouble
wäre einen gezwungen werdenint
- wenn der Wert des Doppels ist nicht in dem Bereich fürint
das Verhalten ist nicht definiert .Gleiches gilt natürlich auch, wenn
true
undfalse
in einem deklariert wurdenenum
.Was noch gefährlicher ist, ist zu erklären
Da jetzt alle Werte außer 1 und 0 ungültig sind und ein solcher Wert einer Variablen dieses Typs zugewiesen werden sollte, wäre das Verhalten völlig undefiniert .
Daher iff Sie nicht C99 aus unerklärlichen Gründen, für boolean Variablen verwenden können , sollten Sie verwenden:
int
und Werte0
und1
wie sie sind ; und führen Sie sorgfältig Domain-Konvertierungen von anderen Werten zu diesen mit doppelter Negation durch!!
BOOL
,TRUE
undFALSE
!quelle
int
oderunsigned int
eine Aufzählung zu halten, aber ich weiß von nichts in der Norm , die eine Aufzählung verursachen würde als etwas anderes als eine ganze Zahl verhalten Art.quelle
!0 = 1
nach dem C-Standard und!a = 0
für jeden Wert ungleich Null vona
. Das Problem ist, dass jede Nicht-Null als wahr angesehen wird. Also , wenna
undb
beide „wahr“ ist , ist es nicht unbedingt der Fall , dass `a == b '.C hat einen booleschen Typ: bool (zumindest für die letzten 10 (!) Jahre)
Fügen Sie stdbool.h hinzu und true / false funktioniert wie erwartet.
quelle
bool
ein Makro sein, das erweitert wird_Bool
. Der Unterschied ist wichtig, weil Sie#undef
ein Makro können (und das ist zumindest als Übergangsmaßnahme zulässig), aber Sie können keinuntypedef
typedef. Es ändert jedoch nichts an der Hauptausrichtung Ihres ersten Kommentars.bool
durch<stdbool.h>
unter C Kompilierung. Es löst sich auf_Bool
.Alles, was ungleich Null ist, wird in booleschen Operationen als wahr ausgewertet
und benutze die Konstanten.
quelle
Nur eine Ergänzung zu anderen Antworten und einige Erläuterungen, wenn Sie C99 verwenden dürfen.
Einige meiner Vorlieben:
_Bool
oderbool
? Beide sind in Ordnung, sehen aberbool
besser aus als das Schlüsselwort_Bool
.bool
und_Bool
sind:false
odertrue
. Zuweisen0
oder1
anstelle vonfalse
odertrue
ist gültig, aber es ist schwieriger, den Logikfluss zu lesen und zu verstehen.Einige Infos aus dem Standard:
_Bool
ist NICHTunsigned int
, ist aber Teil der Gruppe vorzeichenloser Ganzzahltypen . Es ist groß genug, um die Werte0
oder zu halten1
.bool
true
undfalse
das ist sicher keine gute Idee. Diese Fähigkeit gilt als veraltet und wird in Zukunft entfernt._Bool
oderbool
, wenn der Skalarwert gleich ist0
oder mit diesem verglichen0
wird, ist0
, andernfalls lautet das Ergebnis1
:_Bool x = 9;
9
wird konvertiert,1
wenn es zugewiesen wirdx
._Bool
ist 1 Byte (8 Bit), normalerweise ist der Programmierer versucht, die anderen Bits zu verwenden, wird jedoch nicht empfohlen, da nur garantiert wird, dass nur ein Bit zum Speichern von Daten verwendet wird, nicht wie bei einem Typchar
mit 8 Bits verfügbar.quelle
Es ist das:
quelle
Sie können ein Zeichen oder einen anderen Container mit kleiner Nummer dafür verwenden.
Pseudocode
quelle
int
), da Sie bei einigen Architekturen einen erheblichen Leistungseinbruch erzielen, wenn Sie diese Variablen entpacken / maskieren müssen.Sie könnten _Bool verwenden, aber der Rückgabewert muss eine Ganzzahl sein (1 für wahr, 0 für falsch). Es wird jedoch empfohlen, bool wie in C ++ einzuschließen und zu verwenden, wie in dieser Antwort aus dem daniweb-Forum sowie in dieser Antwort aus dieser anderen Stackoverflow-Frage angegeben:
quelle
Bedingte Ausdrücke gelten als wahr, wenn sie nicht Null sind. Der C-Standard verlangt jedoch, dass logische Operatoren selbst entweder 0 oder 1 zurückgeben.
@ Tom: #define TRUE! FALSE ist schlecht und völlig sinnlos. Wenn die Header-Datei in kompilierten C ++ - Code gelangt, kann dies zu Problemen führen:
Einige Compiler generieren eine Warnung über die Konvertierung von int => bool. Manchmal vermeiden die Leute dies, indem sie Folgendes tun:
um den Ausdruck als C ++ - Bool zu erzwingen. Aber wenn Sie TRUE! FALSE definieren, erhalten Sie:
Dies führt zu einem Int-to-Bool-Vergleich, der die Warnung trotzdem auslösen kann.
quelle
Wenn Sie C99 verwenden, können Sie den
_Bool
Typ verwenden. Es#include
sind keine s erforderlich. Sie müssen es jedoch wie eine Ganzzahl behandeln, wo1
isttrue
und0
istfalse
.Sie können dann
TRUE
und definierenFALSE
.quelle
#include <stdbool.h>
und verwendenbool
,true
undfalse
wie der Standard es wünscht.Heutzutage unterstützt C99 boolesche Typen, aber Sie müssen
#include <stdbool.h>
.Beispiel:
Ausgabe:
quelle
Das benutze ich:
_Bool
ist ein eingebauter Typ in C. Er ist für boolesche Werte vorgesehen.quelle
Sie können die
#define
Direktive einfach wie folgt verwenden:Und verwenden Sie wie folgt:
und so weiter
quelle
arg
und den Ausdruck als Ganzes geschützt werden :#define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
. Es wäre jedoch besser, auf Falschheit zu testen (es wird die richtige Antwort geben, selbst wennarg
23 statt 0 oder 1 war :#define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
. Aber der gesamte Ausdruck kann#define NOT(arg) (!(arg))
natürlich auf das reduziert werden , was das gleiche Ergebnis liefert.