Dies (beachten Sie den Komma-Operator ):
#include <iostream>
int main() {
int x;
x = 2, 3;
std::cout << x << "\n";
return 0;
}
Ausgänge 2 .
Wenn Sie jedoch return
den Komma-Operator verwenden, gilt Folgendes:
#include <iostream>
int f() { return 2, 3; }
int main() {
int x;
x = f();
std::cout << x << "\n";
return 0;
}
Ausgänge 3 .
Warum verhält sich der Kommaoperator anders return
?
Antworten:
Nach dem Operator Präzedenz , Komma - Operator hat niedrigere Priorität als
operator=
, sox = 2,3;
entspricht(x = 2),3;
. (Die Priorität des Operators bestimmt, wie der Operator an seine Argumente gebunden wird, je nach Priorität enger oder lockerer als andere Operatoren.)Beachten Sie, dass der Komma-Ausdruck
(x = 2),3
hier nicht steht2,3
.x = 2
wird zuerst ausgewertet (und seine Nebenwirkungen sind abgeschlossen), dann wird das Ergebnis verworfen und dann3
ausgewertet (es tut tatsächlich nichts). Deshalb ist der Wertx
ist2
. Beachten Sie, dass dies3
das Ergebnis des gesamten Kommaausdrucks ist (dhx = 2,3
), für dessen Zuweisung er nicht verwendet wirdx
. (Ändern Sie es inx = (2,3);
,x
wird zugewiesen mit3
.)Für
return 2,3;
ist das Komma Ausdruck2,3
,2
bewertet wird , dann wird das Ergebnis verworfen und dann3
ausgewertet wird und als das Ergebnis des gesamten Komma Ausdruck zurückgegeben, der durch die zurückgeführt wird return - Anweisung später.Zusätzliche Informationen zu Ausdrücken und Aussagen
x = 2,3;
ist Ausdruck Aussage ,x = 2,3
ist der Ausdruck hier.return 2,3;
ist die Sprunganweisung ( return-Anweisung ),2,3
ist hier der Ausdruck.quelle
for
Schleifen gesehen, wenn es seltsamerweise Code in numerischen Berechnungen klarer machen kann.i += 1, j += 2
in einer for-Schleife schreiben können . Jemand hat entschieden, dass die C ++ - Grammatik (oder besser gesagt die C-Grammatik, da dieser Teil von dort kopiert wurde) bereits kompliziert genug ist, ohne zu definieren, dass die Priorität des Kommas beim Schreiben höher ist als die Zuweisung, beim Schreibenx = 2, 3
jedoch niedrigerx = 2, y = 3
!Der Komma- Operator (auch als Ausdruckstrennung bezeichnet ) wird von links nach rechts ausgewertet. Ist
return 2,3;
also gleichbedeutend mitreturn 3;
.Die Bewertung von
x = 2,3;
ist(x = 2), 3;
auf die Priorität des Bedieners zurückzuführen . Die Auswertung erfolgt immer noch von links nach rechts, und der gesamte Ausdruck hat den Wert 3 mit dem Nebeneffekt,x
dass der Wert 2 angenommen wird.quelle
return 2,3
undreturn (2,3)
sind gleich. Ich glaubte, das erstere sollte sein(return 2),3
.return 2
ist eine Aussage (wie z. B. die vonfor,while,if
), kein Ausdruck. Du kannst zBf(return 2)
oder nicht schreiben2+return 2
. Ist(return 2),3
also syntaktisch ungültig.return 2, 3
, als interpretiert zu werden(return 2), 3
.return
nur in den folgenden Fällen auftreten: (a)return
expression_opt;
und (b)return
braced-init-list;
.Diese Aussage:
besteht aus zwei Ausdrücken :
Da Operator Vorrang ,
=
hat mehr Priorität als Komma,
, sox = 2
ausgewertet wird und nach3
. Dannx
wird gleich sein2
.In der
return
stattdessen:Die Sprachsyntax lautet:
Hinweis
return
ist nicht Teil des Ausdrucks.In diesem Fall werden die beiden Ausdrücke wie folgt ausgewertet:
Es wird jedoch nur das zweite (
3
) zurückgegeben.quelle
<expression>
(aus grammatikalischer Sicht) als explizit optional markieren würden .x=2,3
. Beide Literale2
und3
befinden sich am unteren Rand des Analysebaums, ebenso wie der Bezeichnerx
. Dies sind alles individuell gültige Ausdrücke. Operatorpriorität bedeutet, dass sie im Analysebaum niedriger=
auftritt und die beiden Ausdrücke und den vierten Ausdruck kombiniert . Schließlich wird der fünfte Ausdruck durch den Kommaoperator gebildet, der seine beiden Seiten und verbindet . Sie geben jedoch fälschlicherweise an, dass die Priorität des Operators die Reihenfolge der Auswertung bestimmt. Das tut es nicht. Die Reihenfolge der Auswertung wird durch Sequenzierungsregeln bestimmt.x
2
x=2
x=2
3
Versuchen Sie, den simplen Ansatz anzuwenden, indem Sie nur den Vorrang in Klammern hervorheben:
( x = 2 ), 3;
return ( 2, 3 );
Jetzt können wir sehen, dass der binäre Operator "" auf beiden von links nach rechts auf die gleiche Weise funktioniert.
quelle
x = 2, 3
selbst ein Ausdruck ist, während fürreturn
esreturn <expression>
. Also liest du sie als(x = 2, 3)
und(2, 3)
.