it-swarm.com.de

Gibt es einen Unterschied zwischen && und & mit bool (s)?

Gibt es in C++ einen Unterschied zwischen && (logisch) und & (bitweise) zwischen Bool (s)?

bool val1 = foo();
bool val2 = bar();

bool case1 = val1 & val2;
bool case2 = val1 && val2;

Sind case1 und case2 identisch oder wenn nicht, wie genau unterscheiden sie sich und warum sollte man sich eines aussuchen? Ist ein bitweise und von Bools tragbar?

31
WilliamKF

Der Standard garantiert, dass false in null und true in eine Ganzzahl umgewandelt wird:

4.7 Integrale Konvertierungen

...

Wenn der Zieltyp bool ist, siehe 4.12. Wenn der Quellentyp bool ist, wird der Wert false in Null und der Wert true in Eins konvertiert.

Daher ist der Effekt in dem von Ihnen gegebenen Beispiel garantiert derselbe und zu 100% tragbar.

Für den Fall, den Sie angeben, erzeugt ein anständiger Compiler wahrscheinlich identischen (optimalen) Code.

Für boolesche Ausdrücke expr1 und expr2 gilt jedoch im Allgemeinen nicht, dass expr1 && expr2 mit expr1 & expr2 identisch ist, da && eine Kurzschlussauswertung durchführt. Das heißt, wenn expr1 zu false ausgewertet wird, wird expr2 nicht einmal ausgewertet. Dies kann sich auf die Leistung (wenn expr2 kompliziert ist) und das Verhalten (wenn expr2 Nebenwirkungen hat) auswirken. (Beachten Sie jedoch, dass die &-Form tatsächlich schneller sein kann, wenn ein bedingter Zweig vermieden wird ... Mit solchen Dingen aus Performance-Gründen zu spielen, ist fast immer eine schlechte Idee.)

Für das konkrete Beispiel, in dem Sie die Werte in lokale Variablen laden und dann bearbeiten, ist das Verhalten identisch und die Leistung ist sehr wahrscheinlich.

Meiner Meinung nach sollten Sie die Formulierung wählen, die Ihre Absicht am deutlichsten zum Ausdruck bringt, es sei denn, Sie verlassen sich ausdrücklich auf das Kurzschlussverhalten. Verwenden Sie also && für logisches AND und & für bit-twiddling AND, und jeder erfahrene C++ - Programmierer kann Ihren Code leicht nachvollziehen.

37
Nemo

Bei Verwendung von logisch und && wird der Ausdruck auf der rechten Seite nicht ausgewertet, wenn der Ausdruck auf der linken Seite falsch ist.

Viele C/C++/C # -Codes hängen davon ab, wie in: if (p != null && p->Foo()).

Für Ihr Beispiel würde ich case2 (logisch und) verwenden. Verwenden Sie nur bitweise, wenn Sie mit Bitflags usw. arbeiten.

Wenn jedoch foo () und bar () nur bool (0, 1) zurückgeben, sind case1 und case2 gleich.

12

Es gibt einen Unterschied (naja, zwei), obwohl Sie es in Ihrem Beispiel nicht sehen würden.

"&" führt eine bitweise "AND" -Operation aus, dh 0x1 & 0x1 = 0x1, aber 0x1 & 0x2 = 0x0. OTOH, "&&" ist ein boolesches/logisches "AND", dh, es behandelt alle Nicht-Null-Werte als WAHR, also 0x1 && 0x1 = TRUE (der im Allgemeinen als -1 dargestellt wird, dh alle Einsen [oder vielleicht 1 in C++) , Ich vergesse]), während 0x1 && 0x2 = TRUE auch.

Außerdem ist "&&" ein Kurzschluss, dh wenn der erste Operand FALSE ist, wird der zweite nicht ausgewertet. Während FALSE & null_pointer->booleanField ==> null pointer exception, FALSE && null_pointer->booleanField = FALSE.

In einigen Fällen kann es bei der Verwendung von bitweisen Operationen zu einem geringfügigen Leistungsvorteil kommen. Im Allgemeinen sollten Sie jedoch bei der Auswertung boolescher Werte Doppelformulare verwenden, damit Ihr Code unabhängig von der genauen Darstellung von booleschen TRUE und FALSE ist.

8
Hot Licks

Algorithmisch gibt es keinen Unterschied, jedoch ermöglicht die Verwendung von &&, die Überprüfung zu "kurzschließen". Das heißt, um zu entscheiden, ob case1 ist, wenn val1 falsch ist, hat der kompilierte Code keinen Grund, den Wert von val2 zu überprüfen, um die Antwort zu bestimmen, wobei case1 erfordert, dass die tatsächliche UND-Verknüpfung stattfindet.

Realistischerweise erkennt ein guter Compiler das und erzeugt den gleichen Code ... es kommt darauf an, wie gut Ihr Compiler ist.

4
mah

" && " ist eine "bedingte logische" UND " es wertet den zweiten Ausdruck NUR aus, wenn der erste WAHR ist

" & " ist ein "nicht-bedingtes logisches AND" <- (wenn Sie mit booleschen Ausdrücken spielen) Beide Ausdrücke werden ausgewertet


AU&SZLIG;ERDEM IST "&" ein "bitweiser" Operator, dh er arbeitet auf Bitebene. 

Dieses Beispiel kann Sie besser verstehen.

4 = 00000100  // 'four' bit set
5 = 00000101  // 'four' bit and 'one' bit set

00000100 (4) & // AND: only keep bits set in both
00000101 (5)
--------
00000100 (4)

00000100 (4) | // OR: keep bits set in either
00000101 (5)
--------
00000101 (5)

00000100 (4) ^ //  EXCLUSIVE OR: keep bits only set in one but not the other
00000101 (5)
--------
00000001 (1)
2
makiSTB

Die logischen Operatoren && und || werden verwendet, wenn zwei Ausdrücke ausgewertet werden, um ein einzelnes relationales Ergebnis zu erhalten. Der Operator && entspricht der booleschen logischen Operation AND. Diese Operation führt zu true, wenn beide Operanden true sind, andernfalls false.

Der Operator || entspricht der booleschen Verknüpfung ODER. Diese Operation führt zu "true", wenn einer ihrer beiden Operanden "true" ist. Dies ist nur dann "false", wenn beide Operanden selbst "false" sind. 

0
Javeria