2014-11-11 7 views
5

Ich sah nur den Code, und ich bin nicht in der Lage die logisch zu verstehen, wie und verhält sich mit „cout“ hier:Welche logische UND-Operation wird mit der Stream-Ausgabe ausgeführt?

int userInput = 9; // Suppose user input is 9. 
int remainder = 9 % 2; 
(remainder & 1 && std::cout<<"odd")|| cout<<"even"; 
+0

Sie brauchen nicht die Klammern, die da sind, aber abhängig von der Vorrangstellung des Operators (ich kann mich nicht daran erinnern), brauchen Sie vielleicht Klammern um den 'Rest & 1'-Unterausdruck. –

+0

Siehe [C++ Operator Precedence] (http://en.cppreference.com/w/cpp/language/operator_precedence) –

Antwort

6

Die Linie in Frage:

(remainder & 1 && std::cout<<"odd") || cout<<"even"; 

die gleiche wie die folgende ist, wenn Sie nehmen Operator Vorrang und Betreiber Überlastungen Rechnung:

((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool()); 

std::cout (generischer std::basic_ostream) hat operator<<() und operator bool() Operatoren definiert. Der erste Operator gibt eine std::basic_ostream& Referenz zurück, dh einen Verweis auf den Stream selbst (nützlich für Verkettungsoperationen zusammen). Der zweite Operator gibt zurück, ob der Stream in einem Fehlerzustand ist oder nicht.

finden Sie in der folgenden Dokumentation für weitere Details:

C++ operator precedence

operator overloading

std::basic_ostream::operator<<

std::basic_ios::operator bool

+0

kann einige weitere Details oder einen Link geben, um darüber zu lesen. – Zubair

+0

@Zubair: Links hinzugefügt. –

+0

Nitpick: der spezielle 'Operator <<', der hier aufgerufen wird [ist eine Funktion, die kein Mitglied ist] (http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2). –

13

std::cout<<"odd" ist ein Ausdruck, der std::cout zurückkehren wird (was warum können Sie tun std::cout << a << b << c). Wenn im booleschen Kontext ausgewertet, gibt es einfach true zurück, wenn das Fehlerbit nicht gesetzt ist. Wenn also die Ausgabeoperation erfolgreich ist, wird sie als wahr ausgewertet.

Allerdings ist die Absicht dieses Code nicht, diesen Wert zu testen, sondern es ist ein kluger (und nicht sehr gut lesbar) Weg, dies auszudrücken:

if (remainder & 1) { 
    std::cout << "odd"; 
} else { 
    std::cout << "even"; 
} 

Es nutzt die Kurzschlüsse Art der && und || Operatoren:

  • In a && b, wenn a falsch ist dann wertet es als a(b wird nicht ausgewertet!) ansonsten wird es als b ausgewertet.
  • In a || b, wenn a wahr ist, dann wertet es als a(b nicht ausgewertet!) anders als b auswertet.

Also, wenn remainder & 1 als falsch ausgewertet wird (in diesem Fall Null) dann std::cout << "odd" ist nicht, weil die Expression && Kurzschlüsse ausgewertet, falsch zurück. Dies ist der linke Operand für den äußeren || Ausdruck, der bewirkt, dass seine b (std::cout << "even") ausgewertet wird, schreibt "even" an den Ausgang.

Wenn remainder & 1 als wahr ausgewertet wird (in diesem Fall nicht Null), wird der rechte Operand für && ausgewertet, wobei "ungerade" angezeigt wird. Unter der Annahme, dass diese Operation erfolgreich ist, wird der linke Operand für die Operation || wahr sein, was dazu führt, dass er den rechten Operanden kurzschließt und nicht auswertet.


Erfahrene Programmierer sind wahrscheinlich genau wissen, was hier vor sich geht, aber wie Sie diese Technik gefunden haben, ist nicht die lesbar. Es ist besser (IMO), über die Absicht des Codes geradlinig zu sein, also würde ich einfach eine if Bedingung verwenden - oder zumindest den ternären Operator verwenden: std::cout << (remainder & 1 ? "odd" : "even").

In anderen Sprachen (JavaScript kommt mir in den Sinn) (ab) die Verwendung der Kurzschlussoperatoren ist eine sehr verbreitete Technik. Normalerweise sehe ich nicht, dass sie in C++ so verwendet werden, und ich rate dringend davon ab.

+0

Das funktioniert nur, wenn der Compiler boolesche Ausdrücke implementiert, die kurz-curciting sind, um 'std :: cout <<" odd "zu überspringen, wenn" Rest & 1 "zu false führt. Ohne einen Kurzschluß würden sowohl cout << "odd" als auch 'cout <<" even "' wahrscheinlich bewertet werden. –

+6

@RemyLebeau Wenn der Compiler kein boolesches Kurzschließen implementiert, dann [es ist kein konformer C++ - Compiler] (http://stackoverflow.com/questions/628526/is-short-circuit-boolean-operators-mandated-in) -cc-und-Bewertungsreihenfolge). – cdhowie

+0

@cdhowie: Ihre Erklärung ist wertvoller. – Zubair

Verwandte Themen