Nachteile der Bitlevel-Operatoren.
Du fragst:
„Gibt es einen Grund , nicht die Bit - Operatoren zu verwenden &
, |
und ^
für‚Bool‘Werte in C ++? ”
Ja, die logischen Operatoren , die die integrierte High Level Booleschen Operatoren sind !
, &&
und ||
bietet folgende Vorteile:
Garantierte Umwandlung von Argumenten in bool
, dh in 0
und 1
Ordnungswert.
Garantierte Kurzschlussbewertung, bei der die Ausdrucksbewertung beendet wird, sobald das Endergebnis bekannt ist.
Dies kann als Baumwertlogik mit True , False und Indeterminate interpretiert werden .
Lesbare Textäquivalente not
, and
und or
auch wenn ich sie nicht selbst benutze.
Als Leser Antimony Notizen in einem Kommentar auch die bitlevel Operatoren alternative Token, nämlich bitand
, bitor
, xor
und compl
, aber meiner Meinung nach sind diese weniger lesbar als and
, or
und not
.
Einfach ausgedrückt ist jeder dieser Vorteile der High-Level-Operatoren ein Nachteil der Bitlevel-Operatoren.
Insbesondere, da den bitweisen Operatoren die Argumentkonvertierung in 0/1 fehlt, erhalten Sie zB 1 & 2
→ 0
, während 1 && 2
→ true
. Auch ^
bitweise exklusiv oder kann sich auf diese Weise schlecht benehmen. Als boolesche Werte betrachtet, sind 1 und 2 gleich true
, aber als Bitmuster betrachtet sind sie unterschiedlich.
Wie man logisch entweder / oder in C ++ ausdrückt .
Sie geben dann ein wenig Hintergrundwissen für die Frage,
"Manchmal stoße ich auf Situationen, in denen genau eine von zwei Bedingungen erfüllt sein soll (XOR), also wirf ich den Operator ^ einfach in einen bedingten Ausdruck."
Nun, die bitweisen Operatoren haben eine höhere Priorität als die logischen Operatoren. Dies bedeutet insbesondere, dass in einem gemischten Ausdruck wie
a && b ^ c
Sie erhalten das vielleicht unerwartete Ergebnis a && (b ^ c)
.
Schreiben Sie stattdessen einfach
(a && b) != c
präziser ausdrücken, was du meinst.
Für das Mehrfachargument gibt es entweder keinen C ++ - Operator, der den Job ausführt. Zum Beispiel, wenn Sie schreiben , a ^ b ^ c
als das ist nicht ein Ausdruck, der „entweder sagt a
, b
oder c
ist wahr“. Stattdessen heißt es : „Eine ungerade Anzahl von a
, b
und c
wahr sind“, was 1 von ihnen sein könnte oder alle 3 ...
Um auszudrücken , den allgemeinen entweder / oder , wenn a
, b
und c
sind vom Typ bool
, nur Schreib
(a + b + c) == 1
oder bool
konvertieren Sie sie mit Nichtargumenten in bool
:
(!!a + !!b + !!c) == 1
Verwenden &=
, um boolesche Ergebnisse zu akkumulieren.
Sie arbeiten weiter aus,
"Ich muss manchmal auch Boolesche Werte akkumulieren &=
und |=?
kann sehr nützlich sein."
Nun, dies entspricht der Überprüfung, ob alle oder eine Bedingung erfüllt ist, und das Gesetz von de Morgan sagt Ihnen, wie Sie von einer zur anderen gehen sollen. Dh du brauchst nur einen von ihnen. Sie könnten im Prinzip *=
als &&=
Operator verwendet werden (denn wie der gute alte George Boole herausgefunden hat, kann logisches UND sehr leicht als Multiplikation ausgedrückt werden), aber ich denke, dass dies die Betreuer des Codes verwirren und möglicherweise irrefü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:
wahr
falsch
Der Grund für den Unterschied in den Ergebnissen ist, dass der Bitlevel &=
keine Konvertierung in bool
sein Argument auf der rechten Seite bietet .
Welches dieser Ergebnisse wünschen Sie sich für Ihre Verwendung &=
?
Wenn erstere, true
definieren Sie besser einen Operator (z. B. wie oben) oder eine benannte Funktion oder verwenden Sie eine explizite Konvertierung des Ausdrucks auf der rechten Seite oder schreiben Sie die Aktualisierung vollständig.