874 Stimmen

Verwendung boolescher Werte in C

C hat keine eingebauten booleschen Typen. Wie kann man sie am besten in C verwenden?

93 Stimmen

C hat einen booleschen Typ. Zumindest gibt es einen in den neuesten Standards.

12 Stimmen

50voto

Das Wichtigste zuerst. C, d.h. ISO/IEC 9899, hat einen booleschen Typ für 19 Jahre jetzt . Das ist viel mehr Zeit als die erwartet Länge der C-Programmierkarriere mit Amateur-/Akademiker-/Berufsanteil bei Besuch diese Frage . Meiner übertrifft das nur um vielleicht 1-2 Jahre. Das bedeutet, dass während der Zeit dass ein durchschnittlicher Leser überhaupt etwas über C gelernt hat, hat C tatsächlich den booleschen Datentyp .

Für den Datentyp, #include <stdbool.h> und verwenden true , false y bool . Oder lassen Sie es weg und verwenden Sie _Bool , 1 y 0 stattdessen.


Es gibt verschiedene gefährlich Praktiken, die in den anderen Antworten zu diesem Thema angesprochen wurden. Ich werde sie ansprechen:

typedef int bool;
#define true 1
#define false 0

Das geht nicht, denn ein gelegentlicher Leser - der in diesen 19 Jahren C gelernt hat - würde erwarten, dass bool bezieht sich auf die aktuell bool Datentyp und würde sich ähnlich verhalten, tut es aber nicht! Zum Beispiel

double a = ...;
bool b = a;

Mit C99 bool / _Bool , b würde auf false wenn a war Null, und true sonst. C11 6.3.1.2p1

  1. Wenn ein beliebiger Einzelwert in _Bool ist das Ergebnis 0, wenn der Vergleichswert gleich 0 ist; andernfalls ist das Ergebnis 1. 59)

Fußnoten

59) NaNs werden nicht mit 0 gleichgesetzt und daher in 1 umgewandelt.

Mit dem typedef an Ort und Stelle, die double gezwungen werden würde, eine int - wenn der Wert des Double nicht in dem Bereich liegt, der für int die Verhalten ist undefiniert .

Das Gleiche gilt natürlich auch für den Fall, dass true y false wurden in einer enum .

Was ist überhaupt gefährlicher erklärt, dass

typedef enum bool {
    false, true
} bool;

denn jetzt alle Werte außer 1 und 0 sind ungültig, und sollte ein solcher Wert einer Variablen dieses Typs zugewiesen werden, das Verhalten wäre völlig undefiniert .

Deshalb wenn können Sie aus unerklärlichen Gründen nicht C99 verwenden, für boolesche Variablen sollten Sie:

  • Typ int und Werte 0 y 1 wie besehen ; und führen Sie vorsichtig Domänenumwandlungen von anderen Werten in diese mit doppelter Negation durch !!
  • oder wenn Sie darauf bestehen Sie sich nicht daran erinnern, dass 0 falsy und ungleich Null truish ist, verwenden Sie zumindest Großbuchstaben damit sie nicht mit den C99-Konzepten verwechselt werden: BOOL , TRUE y FALSE !

2 Stimmen

Welcher Teil des C-Standards würde Objekte von Aufzählungstypen darauf beschränken, die darin ausdrücklich aufgeführten Werte zu enthalten? Wenn der größte Wert für eine aufgezählte Konstante kleiner als UCHAR_MAX oder USHRT_MAX ist, könnte eine Implementierung einen Typ verwenden, der kleiner als int o unsigned int um eine Aufzählung zu enthalten, aber ich kenne nichts in der Norm, was dazu führen würde, dass sich eine Aufzählung wie etwas anderes als ein Integer-Typ verhält.

17voto

mouviciel Punkte 64583
typedef enum {
    false = 0,
    true
} t_bool;

2 Stimmen

2 bis MAX_INT sollten ebenfalls zu true ausgewertet werden

2 Stimmen

@technosaurus Bei diesem Ansatz ist nicht garantiert, dass !false == true ist, da !false eine beliebige Zahl ungleich Null sein kann. Ein einfacher Workaround wäre, !false explizit true zuzuweisen.

3 Stimmen

@Andrew Das ist nicht wahr. !0 = 1 durch den C-Standard, und !a = 0 für jeden von Null verschiedenen Wert von a . Das Problem ist, dass alles, was nicht Null ist, als wahr angesehen wird. Wenn also a y b beide "wahr" sind, ist es nicht unbedingt der Fall, dass "a == b".

14voto

dmeister Punkte 33302

C hat einen booleschen Typ: bool (zumindest in den letzten 10(!) Jahren)

Binden Sie stdbool.h ein und true/false wird wie erwartet funktionieren.

13 Stimmen

10 Jahre in der Norm, aber nicht 10 Jahre in den Compilern! Die C-Kompilierung von MSVC++ unterstützt C99 überhaupt nicht, abgesehen davon, dass sie // Kommentare zulässt, und wird dies wahrscheinlich auch nie tun. Außerdem ist _Bool in C99 als eingebauter Typ definiert, während bool ein Typedef im <stdbool.h>-Header ist.

5 Stimmen

@Clifford Seit Ihrem Kommentar sind 4 Jahre vergangen... nichts hat sich geändert. MSVC ist ein C++-Compiler und ich glaube, MS hat gesagt, dass sie nicht wirklich scharf darauf sind, alle neuen C-Features (C99 & C11) zu unterstützen. Aber ich kann die Tatsache, dass MSVC keine neuen C-Features unterstützt, nicht als Grund nehmen (vor allem, wenn Sie es gegen eine 10 Jahre danach Antwort). 10 Jahre sind in der Welt der Programmierung wirklich eine lange Zeit. Jeder anständige Compiler sollte in viel weniger als 10 Jahren Unterstützung dafür haben, wenn der Anbieter es unterstützen soll.

2 Stimmen

@KingsIndian: Ich bin mir nicht sicher, warum Sie Ihren Kommentar an mich gerichtet haben oder es überhaupt für nötig hielten, einen Kommentar abzugeben. Ich habe nur die Situation dargestellt, wie sie zum Zeitpunkt des Schreibens war. Ich habe diese Situation nicht unterstützt, sondern lediglich darauf hingewiesen, dass die "Antwort" nicht unter allen Umständen gilt.

13voto

ggambett Punkte 3146

Alles, was nicht Null ist, wird bei booleschen Operationen als wahr gewertet, so dass Sie einfach

#define TRUE 1
#define FALSE 0

und verwenden Sie die Konstanten.

11 Stimmen

Aber verwenden Sie sie mit Vorsicht: da ein wahres Ergebnis ein beliebiger Wert ungleich Null sein kann, sind die Tests if(t==TRUE){...} und if(t), die in anderen Sprachen gleichwertig sind, in C nicht gleichwertig.

2 Stimmen

Sie haben Recht, aber das gilt auch für C++, das einen bool-Typ hat, nicht wahr? Während der Fehlersuche habe ich bool-Variablen mit Werten von 5837834939 gesehen...

1 Stimmen

In C++ entspricht der if(t == true)-Test dem if(t)-Test, da C++ eine Konvertierung vornimmt (alles, was nicht 0 oder ein Null-Zeigerwert ist, wird in true umgewandelt)

8voto

Undefined Behavior Punkte 1930

Nur als Ergänzung zu anderen Antworten und zur Klärung, ob 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:

  • _Bool ou bool ? Beides ist in Ordnung, aber bool sieht besser aus als das Schlüsselwort _Bool .
  • Akzeptierte Werte für bool y _Bool sind: false ou true . Zuweisung von 0 ou 1 anstelle von false ou true ist gültig, aber schwieriger zu lesen und den logischen Ablauf zu verstehen.

Einige Informationen aus dem Standard:

  • _Bool ist NICHT unsigned int sondern ist Teil der Gruppe Ganzzahlige Typen ohne Vorzeichen . Sie ist groß genug, um die Werte zu halten 0 ou 1 .
  • NICHT, aber ja, Sie können neu definieren bool true y false aber das ist sicher keine gute Idee. Diese Fähigkeit wird als veraltet angesehen und wird in Zukunft entfernt werden.
  • Zuweisung einer Skalartyp (arithmetische Typen und Zeigertypen) zu _Bool ou bool wenn die skalar Wert ist gleich 0 oder vergleicht mit 0 wird es sein 0 , andernfalls lautet das Ergebnis 1 : _Bool x = 9; 9 wird umgewandelt in 1 bei Zuordnung zu x .
  • _Bool ist 1 Byte (8 Bits), normalerweise ist der Programmierer versucht, die anderen Bits zu verwenden, aber das wird nicht empfohlen, weil die einzige Garantie, die gegeben ist, ist, dass nur ein Bit verwendet wird, um Daten zu speichern, nicht wie beim Typ char die 8 Bits zur Verfügung haben.

CodeJaeger.com

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.

Powered by:

X