Wir wissen, dass alle Zahlen, die nicht gleich 0
sind, wie true
in C angesehen werden, also können wir schreiben:
int a = 16;
while (a--)
printf("%d\n", a); // prints numbers from 15 to 0
Ich habe mich jedoch gefragt, ob wahr / falsch als 1
/ 0
in C definiert sind , also habe ich den folgenden Code ausprobiert:
printf("True = %d, False = %d\n", (0 == 0), (0 != 0)); // prints: True = 1, False = 0
Gibt der C-Standard explizit die Wahrheitswerte von wahr und falsch als 1
bzw. 0
an?
gcc
mit-std=c89
und es ergibt sich das gleiche Ergebnis.Antworten:
Der C - Standard definiert
true
undfalse
als Makros instdbool.h
dem erweitern1
und0
jeweils.C11-§7.18:
Für die Betreiber
==
und!=
, sagt StandardC11-§6.5.9 / 3:
quelle
0 == 0
und0 != 0
etc., die nicht der Wert von Makros.true
, meinte er "den Wert eines echten Vergleichs" oder so etwas, nicht das Makrotrue
ctrl
+ suchtef
;)NaN == NaN
ist falsch undNaN != NaN
ist wahr. Es gibt kein Problem mit dieser Aussage.Es ist in C11 nicht explizit angegeben. Alle Operationen auf Sprachebene geben 1 als wahr zurück (und akzeptieren alle ungleich Null einschließlich NaN als wahr).
_Bool
, muss true 1 sein, da der Standard nur 0 und 1 vorschreibt (§6.2.5 / 2).<stdbool.h>
Makrotrue
erweitert sich zu1
(§7.18 / 3)==
,!=
,<
,>
,<=
Und das>=
Rück 0 oder 1 (§6.5.8 / 6, §6.5.9 / 3).!
,&&
Und das||
Rück 0 oder 1 (§6.5.3.3 / 5, §6.5.13 / 3, §6.5.14 / 3)defined
erweitert auf 0 oder 1 (§6.10.1 / 1)Aber alles Standardbibliotheksfunktionen
islower
sagen zB einfach "ungleich Null" für die Wahrheit (z. B. §7.4.1 / 1, §7.17.5.1 / 3, §7.30.2.1 / 1, §7.30.2.2.1 / 4).quelle
Es gibt zwei Bereiche des Standards, die Sie beachten müssen, wenn Sie mit Booleschen Werten arbeiten (womit ich eher wahre / falsche Werte als das spezifische C meine
bool/_Bool
Typ ) in C .Das erste hat mit dem Ergebnis von Ausdrücken zu tun und kann in verschiedenen Teilen von
C11 6.5 Expressions
(z. B. relationale und Gleichheitsoperatoren) gefunden werden. Die Quintessenz ist, dass jedes Mal, wenn ein Boolescher Wert von einem Ausdruck generiert wird, ...Ja, das Ergebnis eines Booleschen generierenden Ausdrucks ist eins für wahr oder null für falsch. Dies entspricht dem, was Sie in
stdbool.h
den Standardmakrostrue
und findenfalse
auf die gleiche Weise definiert sind.Beachten Sie jedoch, dass nach dem Robustheitsprinzip "Seien Sie konservativ in dem, was Sie senden, liberal in dem, was Sie akzeptieren" die Interpretation von ganzen Zahlen im booleschen Kontext etwas entspannter ist.
Wiederum sehen Sie aus verschiedenen Teilen der
6.5
Sprache:Daraus (und aus anderen Teilen) geht hervor, dass Null als falsch angesehen wird und jeder andere Wert wahr ist.
Abgesehen davon erscheint die Sprache, die angibt, welche Werte für die Erzeugung und Interpretation von Booleschen Werten verwendet werden, auch in C99 und C89, sodass es sie schon seit geraumer Zeit gibt. Sogar K & R (ANSI-C zweite Ausgabe und die erste Ausgabe) spezifizierte dies mit Textsegmenten wie:
Die Makros in werden
stdbool.h
auch in C99 angezeigt, jedoch nicht in C89 oder K & R, da diese Header-Datei zu diesem Zeitpunkt noch nicht vorhanden war.quelle
||
,==
,!=
usw. Ausbeuteint
, kein boolean Typif
,while
,for
usw,‚true‘bedeutet nur‚Nicht-Null‘.“ Dies ist der herausragende Teil der Antwort und meiner Meinung nach eine unglückliche Entscheidung von Dennis Ritchie von vor langer Zeit. Jeder, der Funktionen geschrieben hat, die Fehlercodes als Rückgabewert zurückgeben,#define noErr 0
und jeder Fehlercode ungleich Null, ist ein Fehler. Und dann ist das Problem, dass die Einfachheit und Schönheit vonif ( ready_to_do_something() ){do_something();}
nicht funktioniert. Es muss sein:if ( !not_ready_to_do_something() ){do_something();}
"Es gibt viele Unwahrheiten, aber nur eine Wahrheit." WAHR sollte 0 sein.A.7.6/7/10/11
(relational / gleichheit / logisch-und / logisch-oder) alle geben an, dass es als Ergebnis 0 oder 1 gibt. Habe die Antwort aktualisiert, um das einzuschließen.Sie vermischen viele verschiedene Dinge: Steueranweisungen, Operatoren und Boolesche Typen. Jeder hat seine eigenen Regeln.
if
Steueranweisungen funktionieren wie zum Beispiel die Anweisung C11 6.4.8.1:while
,for
Usw. die gleiche Regel haben. Dies hat nichts mit "wahr" oder "falsch" zu tun.Operatoren, die angeblich ein boolesches Ergebnis
int
liefern, liefern tatsächlich ein Ergebnis mit dem Wert 1 oder 0. Zum Beispiel die Gleichheitsoperatoren C11 6.5.9:All dies ist darauf zurückzuführen, dass C bis zum Jahr 1999 keinen booleschen Typ hatte, und selbst wenn es einen bekam, wurden die oben genannten Regeln nicht geändert. Im Gegensatz zu den meisten anderen Programmiersprachen, in denen Anweisungen und Operatoren einen booleschen Typ ergeben (wie C ++ und Java), ergeben sie nur einen
int
mit dem Wert Null oder nicht Null. Beispielsweise,sizeof(1==1)
wird 4 in C aber 1 in C ++ geben.Der tatsächliche boolesche Typ in C wird benannt
_Bool
und erfordert einen modernen Compiler. Der Headerstdbool.h
definieren Makrosbool
,true
undfalse
, die zu erweitern_Bool
,1
und die0
jeweils (für die Kompatibilität mit C ++).Es wird jedoch als gute Programmierpraxis angesehen, Steueranweisungen und Operatoren so zu behandeln, als ob sie tatsächlich einen booleschen Typ benötigen / ergeben. Bestimmte Codierungsstandards wie MISRA-C empfehlen eine solche Vorgehensweise. Das ist:
if(ptr == NULL)
stattif(ptr)
.if((data & mask) != 0)
anstattif(data & mask)
.Ziel eines solchen Stils ist es, die Typensicherheit mithilfe statischer Analysewerkzeuge zu erhöhen, wodurch wiederum Fehler reduziert werden. Dieser Stil ist wahrscheinlich nur dann sinnvoll, wenn Sie statische Analysegeräte verwenden. In einigen Fällen führt dies beispielsweise zu besser lesbarem, selbstdokumentierendem Code
Gut, die Absicht ist klar, der Code ist selbstdokumentierend.
gegen
Schlecht. Könnte alles bedeuten, und wir müssen nach dem Typ suchen
c
, um den Code zu verstehen. Ist es eine ganze Zahl, ein Zeiger oder ein Zeichen?quelle
sizeof(bool)
ist implementierungsspezifisch in C ++. Siehe stackoverflow.com/questions/4897844/is-sizeofbool-defined .if(ptr != NULL)
oder vielleichtif(!ptr)
?if(c == '\0')
eignet sich für den besonders häufigen Anfängerfehler beim Codierenif(c = '\0')
, deshalb vermeide ich ihn. Einverstanden,if(c)
ist schlecht ... es sollte zum Beispiel seinif(valveIsOpen)
Ich habe in vielen Sprachen programmiert. Ich habe gesehen, dass je nach Sprache wahr 1 oder -1 ist. Die Logik hinter dem wahren Sein 1 war, dass ein Bit entweder eine 0 oder 1 war. Die Logik hinter dem wahren Sein -1 war, dass das! Betreiber war eine Ergänzung. Es änderte alle Einsen in Nullen und alle Nullen in Einsen in einem Int. Also, für ein int ,! 0 = -1 und! (- 1) = 0. Dies hat mich so gestolpert, dass ich etwas nicht mit == wahr vergleiche, sondern mit! = Falsch. Auf diese Weise funktioniert mein Programmierstil in jeder Sprache. Meine Antwort ist also, sich keine Sorgen zu machen, sondern so zu programmieren, dass Ihr Code in beiden Fällen korrekt funktioniert.
quelle
Diese Antwort muss etwas genauer betrachtet werden.
Die eigentliche Definition in C ++ ist, dass alles, was nicht 0 ist, als wahr behandelt wird. Warum ist das relevant? Da C ++ nicht weiß, was eine Ganzzahl ist, indem wir darüber nachdenken - wir schaffen diese Bedeutung, alles, was sie enthält, ist die Shell und die Regeln für das, was das bedeutet. Es weiß jedoch, was Bits sind, was eine ganze Zahl ausmacht.
1 als Ganzzahl wird lose in Bits dargestellt, beispielsweise ein 8-Bit-Int mit Vorzeichen als 0000 0001. Oft ist das, was wir visuell sehen, eine Lüge. -1 ist aufgrund der vorzeichenbehafteten Natur eine viel häufigere Art, es darzustellen von 'integer'. Ich kann wirklich nicht richtig richtig meinen, warum? Da es sich NICHT um eine Operation handelt, ist 1111 1110. Das ist ein wirklich großes Problem für einen Booleschen Wert. Wenn wir über einen Booleschen Wert sprechen, ist es nur 1 Bit - es ist wirklich einfach, 0 ist falsch und 1 ist wahr. Alle logischen Operationen gelten als trivial. Aus diesem Grund sollte '-1' für Ganzzahlen (signiert) als 'true' bezeichnet werden. 1111 1111 NOT'ed wird 0000 0000 --- die Logik gilt und wir sind gut. Unsigned Ints ist ein bisschen knifflig und wurde in der Vergangenheit viel häufiger verwendet - wobei 1 wahr bedeutet, weil es einfach ist, die Logik zu implizieren, dass '
Das ist die Erklärung. Ich sage, die hier akzeptierte Antwort ist falsch - es gibt keine klare Definition in der C / C ++ - Definition. Ein Boolescher Wert ist ein Boolescher Wert. Sie können eine Ganzzahl als Booleschen Wert behandeln. Die Tatsache, dass die Ausgabe eine Ganzzahl ist, sagt jedoch nichts über die tatsächlich ausgeführte Operation aus.
quelle
Dies geschah aufgrund der relationalen Operatoren in Ihrer
printf
Erklärung.Betreiber
==
und Betreiber!=
Da dies
(0 == 0)
zutrifft, gibt es einen Wert1
wohingegen
(0 != 0)
dies nicht zutrifft, ergibt sich ein Wert0
.quelle