Nachteile der Bitlevel-Operatoren.
Sie fragen:
"Gibt es einen Grund, die bitweisen Operatoren nicht zu verwenden? &
, |
y ^
für "bool"-Werte in C++? "
Ja, die logische Operatoren d.h. die eingebauten booleschen Operatoren auf hoher Ebene !
, &&
y ||
bieten die folgenden Vorteile:
-
Garantiert Umwandlung von Argumenten a bool
d.h. zu 0
y 1
Ordinalwert.
-
Garantiert Kurzschlussauswertung wobei die Auswertung des Ausdrucks endet, sobald das Endergebnis bekannt ist.
Dies kann als eine Baum-Wert-Logik interpretiert werden, mit Wahr , Falsch y Unbestimmt .
-
Lesbare textliche Entsprechungen not
, and
y or
auch wenn ich sie nicht selbst verwende.
Wie der Leser Antimony in einem Kommentar anmerkt, haben auch die Bitlevel-Operatoren alternative Token, nämlich bitand
, bitor
, xor
y compl
aber meiner Meinung nach sind diese weniger gut lesbar als and
, or
y not
.
Einfach ausgedrückt, ist jeder dieser Vorteile der Operatoren auf hoher Ebene ein Nachteil der Operatoren auf Bitebene.
Da die bitweisen Operatoren nicht in 0/1 umgewandelt werden können, erhalten Sie z. B. 1 & 2
→ 0
, während 1 && 2
→ true
. Auch ^
, bitweise exklusive oder, kann sich auf diese Weise falsch verhalten. Als boolesche Werte betrachtet sind 1 und 2 dasselbe, nämlich true
, aber als Bitmuster sind sie anders.
Wie man logisch ausdrückt entweder/oder in C++.
Dann geben Sie ein paar Hintergrundinformationen zur Frage,
"Ich stoße manchmal auf Situationen, in denen ich möchte, dass genau eine von zwei Bedingungen wahr ist (XOR), also füge ich den ^-Operator einfach in einen bedingten Ausdruck ein."
Nun, die bitweisen Operatoren haben höherer Vorrang als die logischen Operatoren. Dies bedeutet insbesondere, dass in einem gemischten Ausdruck wie
a && b ^ c
erhalten Sie das vielleicht unerwartete Ergebnis a && (b ^ c)
.
Schreiben Sie stattdessen einfach
(a && b) != c
präziser auszudrücken, was Sie meinen.
Für das Mehrfachargument entweder/oder es gibt keinen C++-Operator, der diese Aufgabe erfüllt. Wenn Sie zum Beispiel schreiben a ^ b ^ c
dann ist das kein Ausdruck, der sagt "entweder a
, b
o c
wahr ist". Stattdessen heißt es: "Eine ungerade Anzahl von a
, b
y c
wahr sind", was 1 von ihnen oder alle 3 sein können
Um das allgemeine Entweder-Oder auszudrücken, wenn a
, b
y c
sind vom Typ bool
schreiben Sie einfach
(a + b + c) == 1
oder, bei nicht bool
Argumente, konvertieren Sie sie in bool
:
(!!a + !!b + !!c) == 1
Verwendung von &=
um boolesche Ergebnisse zu akkumulieren.
Sie führen weiter aus,
"Ich muss auch manchmal boolesche Werte akkumulieren, und &=
y |=?
kann sehr nützlich sein."
Nun, dies entspricht der Überprüfung, ob jeweils alle o jede Bedingung erfüllt ist, und de-Morgansches Gesetz sagt Ihnen, wie Sie von einem zum anderen kommen. Das heißt, Sie brauchen nur einen von beiden. Sie könnten im Prinzip Folgendes verwenden *=
als &&=
-Operator (denn wie der gute alte George Boole entdeckte, kann logisches UND sehr leicht als Multiplikation ausgedrückt werden), aber ich denke, dass dies die Betreuer des Codes verwirren und vielleicht in die Irre führen würde.
Beachten Sie auch:
struct Bool
{
bool value;
void operator&=( bool const v ) { value = value && v; }
operator bool() const { return value; }
};
#include <iostream>
int main()
{
using namespace std;
Bool a = {true};
a &= true || false;
a &= 1234;
cout << boolalpha << a << endl;
bool b = {true};
b &= true || false;
b &= 1234;
cout << boolalpha << b << endl;
}
Ausgabe mit Visual C++ 11.0 und g++ 4.7.1:
true
false
Der Grund für die unterschiedlichen Ergebnisse ist, dass der Bitlevel &=
bietet keine Umwandlung in bool
seines Arguments auf der rechten Seite.
Welches dieser Ergebnisse wünschen Sie sich also für Ihre Verwendung von &=
?
Wenn ersteres, true
dann definieren Sie besser einen Operator (z. B. wie oben) oder eine benannte Funktion, oder verwenden Sie eine explizite Umwandlung des Ausdrucks auf der rechten Seite, oder schreiben Sie die Aktualisierung vollständig.
0 Stimmen
Wenn Sie seit dem Stellen dieser Frage ausreichend viel über C++ gelernt haben, sollten Sie zurückkommen und die aktuelle Antwort zurücknehmen und die Antwort von Patrick Johnmeyer akzeptieren, da sie den Unterschied zwischen Kurzschlüssen korrekt erklärt.
0 Stimmen
Allgemeine Bemerkung, weil die Leute sich fragen, ob dies eine gute Idee ist. Wenn man sich um die Verzweigungsabdeckung von Unit-Tests kümmert, dann ist eine Reduzierung der Verzweigungen wünschenswert. Bitweise Operatoren sind dafür nützlich.