C Zuweisung in Zuweisung?

Lockedoor

Lieutenant
Registriert
Sep. 2008
Beiträge
676
Hallo Ihr!


Ich habe momentan ein kleines Problem mit dem logischen Verständnis von Zuweisungen... Folgendes habe ich gegeben:

Code:
int x=2;
int y=1;
int z=2;
z=((z = ++x + y) > (z = x * --y));

Nach Ausführung dieses Codes ist z = 0. Ich verstehe nur leider nicht wieso? Ich hätte gedacht man vergleicht hier z=4 > z=0 und das stimmt ja eigtl.; folglich wäre z=1?
Werden die '=' in den Klammern womöglich als Vergleiche aufgefasst? :o Ändere ich das > nämlich zu einem >= ist z plötzlich 1...!

Könnte mir jemand erklären was hier passiert...?

lG
Lockedoor
 
Hi,

wird nicht schlussendlich z > z verglichen? Somit würden die Berechnungen in der Klammer keine Rolle spielen und deine Resultate wären erklärt. Leider bin ich mir nicht sicher :D

Gruss
 
... das macht tatsächlich Sinn :D
Da hätte ich auch selbst drauf kommen können... -.-'
Vielen Dank!
 
Ich bin kein C-Experte, aber innerhalb der Klammern findet eine Zuweisung statt. Und wieso sollte die Klammer jetzt auf die Idee kommen plötzlich einen Variablenwert zurückzugeben? Ich weiß nicht was sie zurückgibt, aber sie wird wohl links und rechts das selbe zurückgeben, weshalb <= auch wieder zutrifft, sprich true oder 1 als integer.
 
Ich hoffe, solchen Code schreibst du nur zum Experimentieren. Wer sowas mit ernster Mine verbockt, gehört erschossen. :p
Ergänzung ()

Übrigens, google mal "C sequence points" und lies dir das durch, wenn du magst. Ich weiß nicht, ob dein Beispiel die Regeln verletzt und damit ungültiges Verhalten provoziert. Mir ist der ganze sequence-point-Kram ganz ehrlich viel zu kompliziert, weshalb ich Code, der damit eventuell in Konflikt steht, TUNLICHST vermeide. Aber man sollte zumindest wissen, dass es diesen Fallstrick gibt.
 
Lockedoor schrieb:
Ich habe momentan ein kleines Problem mit dem logischen Verständnis von Zuweisungen...

Sieht nicht sehr "logisch" aus ;-)

Code:
  int x=2;
  int y=1;
  int z=2;
  z = (
          (z = ++x  +   y)  // EXPR_A, verändert z und x => undefiniert
                > 
          (z =   x  * --y)  // EXPR_B, verändert z und y => undefiniert
  )
  ;       // Sequenzpunkt

Nach Ausführung dieses Codes ist z = 0. Ich verstehe nur leider nicht wieso? Ich hätte gedacht man vergleicht hier z=4 > z=0 und das stimmt ja eigtl.; folglich wäre z=1?

Die ganze Rätselraterei hat ein Ende, wenn Dir klargeworden ist, daß es
nicht vorgeschrieben ist, in welcher Reihenfolge die Ausdrücke (EXPR_A/B)
aufgelöst werden. Außerdem mußt Du bedenken, daß alle Variablen, die
Du in EXPR_A veränderst, damit auch in EXPR_B verändert vorliegen
(oder eben umgekehrt). Du kannst aus dem Ergebniss erraten, was
zuerst ausgeführt wird.

Generell gilt: Mehrfachveränedrungen von variablen (z=, x++, y--)
innerhalb eines Sequenzpunktes sind undefiniert. Zu deutsch:
der Code ist fehlerhaft, es ist kein reguläres C (Sequenzpunkte
sind Semikolon oder geschweiftes Klammerpaar usw.). Das Ergebnis
ist letztlich Zufall.

/EDIT:

ich habe nochmal über den speziellen Fall nachgedacht und gesehen, dass es ganz einfach ist. Der Grund für das Verhalten liegt einfach darin, dass der Compiler für z nur eine Speicherstelle bereitstellt. Ganz egal was zuerst ausgeführt wird, es gibt nur ein z und das hat den Wert des zuletzt ausgeführten Ausdrucks. Der Vergleich reduziert sich am Ende also auf:

Code:
  z = (
          z
          > 
          z
  );

Und da z == z sein muss (es ist ja die selbe Variable), muss auch "z > z" 0 ergeben.
 
Zuletzt bearbeitet:
Zurück
Oben