2015-02-09 16 views
5

arbeiten Ich habe SO für eine Weile als eine Referenz verwendet, aber nie zuvor eine Frage gestellt. Ich bin derzeit in einem College C++ - Klasse und auch lesen Programmierung: Principles and Practice von Bjarne Stroutstrup nur für mich selbst, wie ich eine Antwort auf eine Frage hier sah, die wirklich empfohlen.Einige Verwirrung mit, wie Kommas in C/C++

Wir decken momentan die Operatoren in meiner Klasse ab, und ich kann mich einfach nicht vorstellen, wie der Komma-Operator in einer Anweisung arbeitet. Ein Beispiel ist eine Beispielfrage für den Online-Teil der Klasse, die ich falsch verstanden habe, selbst wenn ich ein C-Programm schreibe und GDB verwende, um das Ergebnis zu erhalten. Die Frage lautet:

Angenommen, x == 16 vor dem folgenden Ausdruck, was ist der Wert des folgenden Ausdrucks (nicht unbedingt der Wert von x)?

x ++ ++ x, x + = x

Ich bin nicht daran interessiert, die richtige Antwort, so viel wie, wie die richtige Antwort zu bekommen. Ich habe ein paar Antworten auf ähnliche Fragen gelesen, wie diese here, aber es scheint, als ob ich vermisse, wie dies gilt, wenn es eigentlich keinen Assignment-Operator gibt. Ist dies das gleiche wie zu sagen

int y = (x++, ++x, x+=x); 

oder

int y = x++, ++x, x+=x; 

oder keines von beiden? Könnte jemand bitte erklären, wie der Komma-Operator arbeitet, speziell in Bezug auf eine Aussage ohne Auftrag?

+4

@SouravGhosh Nein, der Komma-Operator führt einen Sequenzpunkt zwischen seinen Operanden ein. Die Ausdrücke werden von links nach rechts sequenziert. – juanchopanza

+0

@KeithThompson Danke, Sir, dass Sie mich korrigiert haben. –

+0

@juanchopanza Sir, irgendwie habe ich Kapitel 6.5.17 vermisst. Das tut mir leid. Ich stehe korrigiert. –

Antwort

8

Der Komma-Operator ist einfach - so einfach ist es schwer. Es hat die niedrigste Priorität aller Betreiber; seine Priorität ist sogar niedriger als die Zuweisungsoperatoren. Beachten Sie, dass Argumente für Funktionen nicht durch den Kommaoperator getrennt sind.

Der Kommaoperator wertet seinen linken Operanden aus, generiert einen Sequenzpunkt und verwirft das Ergebnis und wertet dann den rechten Operanden aus.

im Kontext:

x++, ++x, x += x; 

entspricht:

x++; 
++x; 
x += x; 

außer daß der Gesamtwert ist das Ergebnis der x += x;.

Da x beginnt bei 16, um es zu 17 erhöht, dann 18, dann verdoppelt bis 36. Der Gesamtwert 36.

Man beachte, daß wegen der Sequenzpunkte daher ist es nicht läuft Foul die Regeln, die gleiche Variable nicht mehr als einmal zwischen den Sequenzpunkten zu erhöhen.

Der einzige Grund für die Verwendung eines Komma-Operators ist, dass es Kontexte gibt, in denen Sie keine separaten Anweisungen verwenden können, aber Sie können Kommaoperatoren verwenden. Beispiel:

for (i = 0, j = n; i < j; ++i, --j) 

Sie können Semikolons anstelle dieser Kommata nicht verwenden.


in der Frage gibt es zwei Proben:

int y = (x++, ++x, x+=x); 

int y = x++, ++x, x+=x; 

Die erste legitim ist (wenn auch nicht unnötig contorted), und initialisiert y bis 36 (und setzt x bis 36).

Die zweite ist nicht legitim und wird nicht kompilieren; Die Kommas sind keine Komma-Operatoren und sollten verschiedene Deklaratoren trennen, aber die ++x und x += x sind keine Deklaratoren. Wenn es jedoch geändert wurde:

dann wäre es legitim. Der erste Term ist:

y = x++ 

der 16 bis y und Inkremente x bis 17. Der zweite Term Inkrementen x bis 18 zuordnet; Der dritte Term ändert x bis 36.

+1

[Klas Lindbäck] (http://stackoverflow.com/users/646887/klas-lindb% c3% a4ck) - danke für deine Bearbeitung; Ich habe das Material nach der Regel hinzugefügt, als du deine Änderung vorgenommen hast. Ich hoffe, meine Erklärung ist mindestens so gut wie deine. Ich habe bereits oben auf der Antwort darauf hingewiesen, dass der Komma-Operator eine noch niedrigere Priorität als die Zuweisung hat. –

4

der Komma-Operator den ersten Operanden auswertet, verwirft sie, und wertet dann zu die zweite, mit einer Sequenz Punkt zwischen den Bewertungen.

In Ihrem Fall bedeutet es Ihnen diese Folge von Ausdrücken ausgewertet

x++ // evaluates to 16, increments x to 17 
++x // increments x to 18, evaluates to 18 
x+=x // increments x by x, i.e. by 18, evaluates to 36. 

Und der volle Ausdruck wertet mit dem dritten Unterausdruck. Der erste Ausdruck wird mit 16 ausgewertet, erhöht aber die Werte x auf 17. Der zweite Wert erhöht x auf 18 und berechnet diese Zahl. Der dritte Wert erhöht den Wert x um den Wert 18 und wird x, also die Auswertung 36.