Gibt es so etwas? Es ist das erste Mal, dass ich einen praktischen Bedarf dafür habe, aber ich sehe keinen in Stroustrup . Ich habe vor zu schreiben:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Es gibt aber keinen ^^
Operator. Kann ich ^
hier das bitweise verwenden und die richtige Antwort erhalten (unabhängig von der maschinellen Darstellung von wahr und falsch)? Ich mische nie &
und &&
, oder |
und ||
, also zögere ich, das mit ^
und zu tun ^^
.
Ich würde es mir bequemer machen, bool XOR(bool,bool)
stattdessen meine eigene Funktion zu schreiben .
Antworten:
Der
!=
Operator dient diesem Zweck fürbool
Werte.quelle
bool
Werte" zu erwähnen, weil es nicht unbedingt das tut, was Sie sich für Nicht-Boolesche Werte wünschen. Und da dies C ++ ist, gibt es einen echtenbool
Typ, anstatt ihnint
für diesen Zweck verwenden zu müssen.a
schreiben Sie einfach!(a) != !(a)
Für eine echte logische XOR-Operation funktioniert dies:
Beachten
!
Sie, dass die Werte in Boolesche Werte konvertiert und negiert werden sollen, sodass zwei ungleiche positive Ganzzahlen (jeweils atrue
) ausgewertet werdenfalse
.quelle
!!
würde funktionieren, fragen Sie einfach gut, aber da sie unterschiedlich sein müssen, schadet es nicht, sie zu negieren.Die ordnungsgemäße manuelle logische XOR-Implementierung hängt davon ab, wie genau Sie das allgemeine Verhalten anderer logischer Operatoren (
||
und&&
) mit Ihrem XOR nachahmen möchten . Diese Operatoren haben zwei wichtige Eigenschaften: 1) Sie garantieren eine Kurzschlussbewertung, 2) sie führen einen Sequenzpunkt ein, 3) sie bewerten ihre Operanden nur einmal.Wie Sie verstehen, kann die XOR-Auswertung nicht kurzgeschlossen werden, da das Ergebnis immer von beiden Operanden abhängt. 1 kommt also nicht in Frage. Aber was ist mit 2? Wenn Sie sich nicht für 2 interessieren, dann mit normalisiert (dh
bool
!=
erledigt der Operator ) Werten die Aufgabe von XOR in Bezug auf das Ergebnis. Und die Operanden können bei Bedarf leicht mit unär normalisiert werden!
. Somit!A != !B
implementiert die richtige XOR in dieser Hinsicht.Aber wenn Sie sich für den zusätzlichen Sequenzpunkt interessieren, auch nicht
!=
noch bitweise^
der richtige Weg, um XOR zu implementieren. Eine Möglichkeit, XOR (a, b) korrekt auszuführen, könnte wie folgt aussehenDies ist tatsächlich so nah wie möglich daran, ein hausgemachtes XOR "ähnlich" zu
||
und zu machen&&
. Dies funktioniert natürlich nur, wenn Sie Ihr XOR als Makro implementieren. Eine Funktion funktioniert nicht, da die Sequenzierung nicht auf die Argumente der Funktion angewendet wird.Jemand könnte jedoch sagen, dass der einzige Grund, an jedem einen Sequenzpunkt zu haben
&&
und darin||
besteht, die kurzgeschlossene Auswertung zu unterstützen, und XOR daher keinen benötigt. Das macht eigentlich Sinn. Es lohnt sich jedoch, ein XOR mit einem Sequenzpunkt in der Mitte in Betracht zu ziehen. Zum Beispiel der folgende Ausdruckhat das Verhalten und das spezifizierte Ergebnis in C / C ++ definiert (zumindest in Bezug auf die Sequenzierung). Man könnte also vernünftigerweise dasselbe von benutzerdefiniertem logischem XOR erwarten wie in
Ein
!=
XOR auf Basis hat diese Eigenschaft nicht.quelle
||
und&&
: C) sie bewerten die Operanden in einem booleschen Kontext. Das heißt,1 && 2
ist wahr, im Gegensatz zu1 & 2
dem , was Null ist. Ebenso^^
könnte ein Operator nützlich sein, um diese zusätzliche Funktion bereitzustellen und die Operanden in einem booleschen Kontext auszuwerten. ZB1 ^^ 2
ist falsch (anders als1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
ein Aufruf wieint x = 2; XOR(++x > 1, x < 5);
das falsche Ergebnis liefert, wenn eine Implementierung so aussieht . Der Aufruf müsste zusätzliche Klammern wie in enthaltenint x = 2; XOR( (++x > 1), (x < 5) );
, um das richtige erwartete Ergebnis zu erzielen.Es gibt eine andere Möglichkeit, XOR auszuführen:
Was offensichtlich gezeigt werden kann, funktioniert über:
quelle
Der XOR-Operator kann nicht kurzgeschlossen werden. Das heißt, Sie können das Ergebnis eines XOR-Ausdrucks nicht einfach durch Auswerten seines linken Operanden vorhersagen. Daher gibt es keinen Grund, eine
^^
Version bereitzustellen .quelle
&&
und&
überhaupt. Es geht darum, dass es keinen Grund gibt, sich vorzustellen^^
. Die Eigenschaft,^^
die einen Wert ungleich Null als1
nicht wirklich nützlich betrachten würde, vermute ich. Zumindest kann ich keine Verwendung sehen.Es wurde ein guter Code veröffentlicht, der das Problem besser löste als! A! =! B.
Beachten Sie, dass ich BOOL_DETAIL_OPEN / CLOSE hinzufügen musste, damit es unter MSVC 2010 funktioniert
quelle
Verwenden Sie eine einfache:
quelle
Ich denke, Sie schreiben einen XOR-Vergleich in C ++:
Beweis
Der Beweis ist, dass eine umfassende Untersuchung der Ein- und Ausgänge zeigt, dass in den beiden Tabellen für jeden Eingabesatz das Ergebnis in den beiden Tabellen immer identisch ist.
Daher war die ursprüngliche Frage, wie man schreibt:
Die Antwort wäre
Oder wenn Sie möchten, schreiben Sie
quelle
(A || B) && !(A && B)
Der erste Teil ist A ODER B, welches das Inklusive ODER ist; Der zweite Teil ist NICHT A UND B. Zusammen erhalten Sie A oder B, aber nicht sowohl A als auch B.
Dies liefert den in der nachstehenden Wahrheitstabelle nachgewiesenen XOR.
quelle
Ich verwende "xor" (es scheint ein Schlüsselwort zu sein; in Code :: Blocks wird es zumindest fett), genauso wie Sie "und" anstelle von
&&
und "oder" anstelle von verwenden können||
.Ja, es ist bitweise. Es tut uns leid.
quelle
and
undxor
sind Standardbibliotheksmakros. Sie kommen nicht von "irgendwo", sondern von <iso646.h>. Diese Makros befinden sich auch in C99 (nicht sicher über C89 / 90).xor
steht für bitweises xor, währendand
es logisch ist und.struct A { compl A() { } };
beispielsweise einen Destruktor definieren.Es funktioniert wie definiert. Die Bedingungen sind zu erkennen, ob Sie Objective-C verwenden , das nach BOOL anstelle von bool fragt (die Länge ist unterschiedlich!)
quelle