& oder &&
-
Wenn man zwei logische Ausdrücke hat
a > b a > c
dann müsste es doch egal sein, ob man schreibt
if ((a > b) && (a > c)) oder if ((a > b) & (a > c))
Der gcc-Compiler hat zumindest nichts dagegen.
Oder gibt es Compilereinstellungen, bei denen die zweite Möglichkeit nicht akzeptiert wird?
-
& -> Bitweises Und
&& -> logisches UndEs gibt da einen Unterscheid!
-
Ja, es geht beides, bedeutet in diesem Ffall sogar das gleiche. Aber warum sollte man das verbieten wollen? bool ist nach int konvertierbar, damit sind automatisch alle Operationen von int mit bool erlaubt. Das hast du mitgekauft in dem Moment, als du dich für C++ entschieden hast.
-
Danke,
jetzt ist mir klar, dass ich es auch richtig verstanden habe.
-
HighLigerBiMBam schrieb:
Es gibt da einen Unterscheid!
Dann erläuter ihn auch
Naja...
Ich spar mir die Erklärung auch mal...Kuck dir einfach mal Folgendes an:
#include <iostream> bool check1(){ std::cout << "check1" << std::endl; return false; } bool check2(){ std::cout << "check2" << std::endl; return true; } int main(int argc, char** arg){ if(check1() & check2()); if(check1() && check2()); }
check1
check2
check1Gruß,
XSpille
-
es ist einfach so:
bei a&b in nem if wird beides ausgewertet
bei a && b greift bei bedarf lazy evaluation
also sprich wenn a falsch ist wird b gar nicht erst angepackt (gleiche mit | und ||)
-
Fraglich, ob man das als Anfänger ohne Erklärung versteht.
Man muss sich im klaren sein, dass eine Bedingung der Form
A && B
nur dann wahr sein kann, wenn sowohl A, als auch Btrue
ergeben. Wenn also bereits Afalse
ist, dann kann man sich die Überprüfung von B sparen. Man nennt das Kurzschlussauswertung (Short Circuit Evaluation).http://de.wikipedia.org/wiki/Kurzschlussauswertung
Man kann sich damit also unnötige Vergleiche und Seiteneffekte (z.B. einen Funktionsaufruf) sparen und kann Performance gewinnen.
Das ist bei & nicht gegeben.
-
In dem ersten Beispiel ist das kein Problem. Also solange man mit reinen boolischen Werten arbeitet, sprich 0 und 1.
Man benutzt jedoch auch Werte über 1 wie Pointer als boolische Werte um zu testen ob diese nicht null sind.
if(mrPonter) { //Wird ausgeführt wenn mrPointer != 0 delete(mrPointer); mrPointer = 0; }
Solche Werte kann man nicht mit & verknüpfen, da man dann ein false bekommt wenn zufällig keine Bits beider Werte an der selben Stelle auf 1 gesetzt sind.
pointer1 = 0x0010
pointer2 = 0x0100if(pointer1) <-- wird ausgeführt
if(pointer2) <-- wird ausgeführt
if(pointer1 && pointer2) <-- wird ausgeführt
if(pointer1 & pointer2) <-- wird NICHT ausgeführt
-
Kein gutes Beispiel, diese if-Abfrage ist unnötig.
Der Rest, den Du sagst, ist natürlich richtig.
-
Niko99 schrieb:
Wenn man zwei logische Ausdrücke hat
...dann stellt sich die Frage gar nicht. Bei logischen Ausdrücken nimmt man
&&
und||
.
-
weil's hier grad hauptsächlich um die Kurzschluss-Eigenschaften von && und || geht, möchte ich auch nochmal den Fokus auf etwas anderes lenken:
#include <iostream> int main() { using namespace std; cout << "Tach auch!\n"; if (1 & 2) cout << "Ja1\n"; if (1 && 2) cout << "Ja2\n"; cout << "Teschuess!\n"; }
Ausgabe:
Tach auch! Ja2 Teschuess!
Erklärung:
& : (ganzzahl, ganzzahl) --> ganzzahl
&&: (bool, bool) --> boolBei der (ggf impliziten) Konvertierung von bool nach int kommt entweder 0 oder 1 raus. Bei der (ggf impliziten) Konvertierung von int nach bool kommt false raus, wenn die Ganzzahl 0 war und true sonst.
Im ersten if liefert 1&2 also 0 und wird zu false konvertiert
Im zweiten if liefert 1&&2 true, weil 1 und 2 jeweils zu true konvertiert werden.Das mit dem "Kurzschluss" (also dass && oder || die rechte Seite nur dann auswertet, falls für die Bestimmung des Ergebnisses notwendig) stimmt natürlich auch.
kk
-
Warum gibt es eigentlich kein &&=
alsobool ok=true; ok &&= foo(); ok &&= bar();
-
weil man bei bool auch normal & und | nutzen kann...
und die gibts in kurzform ---> &=, |=
-
Aber er hat schon Recht:
void* bla = 0; bool isItTrue = true; isItTrue &&= bla;
Über die Lesbarkeit darf man natürlich streiten.
-
Skym0sh0 schrieb:
weil man bei bool auch normal & und | nutzen kann...
und die gibts in kurzform ---> &=, |=Nein, diese Operatoren haben ja nicht die Kurzschlusseigenschaft.
-
aber man könnte sie nutzen...
ok man verliert ein klein bisschen performance...
(aber mal ehrlich bei bitoperationen und bei eifnachen logischen bool verküpfungen macht das nicht viel, da gibts andre bottlenecks)
-
Skym0sh0 schrieb:
aber man könnte sie nutzen...
ok man verliert ein klein bisschen performance...
(aber mal ehrlich bei bitoperationen und bei eifnachen logischen bool verküpfungen macht das nicht viel, da gibts andre bottlenecks)Person* user; ... bool isAdult = user; isAdult &= user->isOlderThanWhatever(); // Kaboom, Weltuntergang
bool dieWeltGehtUnter = wasCriticalOperatationSuccessful(); dieWeltGehtUnter |= terminate();
-
Skym0sh0 schrieb:
aber man könnte sie nutzen...
ok man verliert ein klein bisschen performance...
(aber mal ehrlich bei bitoperationen und bei eifnachen logischen bool verküpfungen macht das nicht viel, da gibts andre bottlenecks)Das nicht nur ein bisschen Performance, sondern das Verhalten ist total unterschiedlich
bool ok=true; ok &= foo(); ok &= bar();
bar() wird immer aufgerufen, egal was foo() zurück gibt.
bool ok=true; ok = ok && foo(); //ok &&=foo() ok = ok && bar(); //ok &&=bar()
bar wird nur aufgerufen, wenn foo() true zurück gibt.
-
Um Performance geht es da gar nicht, sondern um rechtsseitige Operanden, die im Fall des Falles nicht ausgewertet werden dürfen, z.B.
ptr != 0 && *ptr == 42
. Ich denke, die &&= / ||= Operatoren gibt es deshalb nicht, weil sie nur in einem bestimmten Muster vorkommen:bool b = true; b &&= f(); b &&= g(); ...
(dh von der ganzen Reihe von Funktionen werden nur solange welche aufgerufen, bis mal eine false zurückgibt)
Der Fall, dass man da nicht einfach
b = b && f()
schreiben kann, also dass b ein komplizierterer lvalue-Ausdruck ist, dürfte extrem selten sein.