Claus77 Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 Hallo, ich habe diese Zeile mal mit mehreren Programmiersprachen ausprobiert und hier die Ergebnisse: Visual C# 5 Visual C++ 7 Perl v5.8.8 7 G++ 5 Benutzt man in Perl übrigens statt i += i = i+, so kommt 6 heraus. Kann mir jemand sagen, wie die Compiler auf die unterschiedlichen Ergebnisse kommen? Grüße, Claus Zitieren
Magoo Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 Die große Frage ist, was steht in i bevor diese Zeile verarbeitet wird? Möglicherweise etwas undefiniertes. Das würde die unterschiedlichen Ergebnisse erklären. Zitieren
Claus77 Geschrieben 9. Januar 2008 Autor Geschrieben 9. Januar 2008 Hoppla, ganz vergessen: So in etwa sah der Code aus: i = 1 i += i++ + ++i print i Zitieren
Klotzkopp Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 Das Ergebnis dieses Ausdrucks ist in C und C++ nicht definiert. Der Compiler darf da tun, was er will. Zitieren
TDM Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 Theorie: i = 1 i++ -> i + 1 i = 1 ++i -> i + 1 i = 3 1 + 3 = 4 i = 4 Anfangs-i (1) + 4 i = 5 -> Yeaha, ich wäre der perfekte Compiler. :floet: Zitieren
Kael_Uka Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 Gegentheorie: i = 1; i++ -> i = 2; ++i -> i = 3 i(3) + i(3) -> i = 6 Anfangs i(1) + 6 = 7. Zitieren
TDM Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 i++ -> i = 2; ++i -> i = 3 i++ gibt doch aber das aktuelle i (1) erst zurück und erhöht dann erst i um 1. Zitieren
Klotzkopp Geschrieben 9. Januar 2008 Geschrieben 9. Januar 2008 Auf 7 kommt man, wenn man zuerst den rechten Operanden des + auswertet, und dann erst den linken. Zitieren
Claus77 Geschrieben 9. Januar 2008 Autor Geschrieben 9. Januar 2008 Wenn jetzt noch jemand logisch erklären kann, wie man in Perl auf das Ergebnis 6 kommt bei i = i + i++ + ++ i bin ich (fast) zufrieden ;-) Aber das sollte ich wohl woanders posten... Zitieren
SoL_Psycho Geschrieben 22. Januar 2008 Geschrieben 22. Januar 2008 Sehr geiler Thread i += i++ + ++i -------------------------------------------------------------------------------- Hallo, ich habe diese Zeile mal mit mehreren Programmiersprachen ausprobiert und hier die Ergebnisse: Visual C# 5 Visual C++ 7 Perl v5.8.8 7 G++ 5 Benutzt man in Perl übrigens statt i += i = i+, so kommt 6 heraus. Nochmal ne Zusammenfassung: Ergebnis 5: i = 1 i += i++ + ++i Das führt zu: 1 += i++ + ++i 1 += 1 + ++i (i wurde nach dem "Einlesen" inkrementiert) 1 += 1 + 3 (i wurde vor dem "Einlesen" inkrementiert) i = 1 + (1 + 3) = 5 Man nimmt das linke i, zu dem etwas addiert werden will (die erste 1) Dann wird das i genommen und dazugerechnet (die zweite 1), nun wird i auf 2 inkrementiert Als letztes wird i wieder inkrementiert und dann dazugerechnet (die 3) Ergebnis 7: i = 1 i += i++ + ++i Auflösung von rechts nach links: i += i++ + 2 (i wurde vor dem "Einlesen" inkrementiert) i += 2 + 2 (i wurde nach dem "Einlesen inkrementiert) 3 += 2 + 2 i = 3 + 2 + 2 = 7 Bei Ergebnis 6 hätt ich gern noch, was genau du da eingegeben hast (kann das oben irgendwie nit rauslesen :bimei) Zitieren
TDM Geschrieben 24. Januar 2008 Geschrieben 24. Januar 2008 Bei Ergebnis 6 hätt ich gern noch, was genau du da eingegeben hast (kann das oben irgendwie nit rauslesen :bimei) 1 += 2 + 3 Das links vom Zuweisungsoperator bleibt i(1) und rechts dann 1++; i = 2 -> ++2 -> i = 3; Zitieren
relo Geschrieben 24. Januar 2008 Geschrieben 24. Januar 2008 1 += 2 + 3 Das links vom Zuweisungsoperator bleibt i(1) und rechts dann 1++; i = 2 -> ++2 -> i = 3; Aber warum ist dann i =2 und das andere i=3? Wenn ich das nochmal zusammenfasse: i += i++ + ++i => i = 1 => 1 += i++ + ++i => entweder: 1 += 1 + 3 oder 1 += 2 + 2 Das wäre wenn das i vor dem Zuweisungsoperator immer gleich bleiben würde. Warum ist dann aber hinten auch eines 3, wenn man von links nach rechts ginge würde der erste parameter erst nach der Anweisung incrementieren, der zweite würde dann vor der Anweisung inkrementieren. Wenn man es von rechts nach links machen würde, wären es auch jeweils 2, siehe oben die Ausführung. Ich komme nicht darauf, wie du auf die eine 3 kommst... Vielleicht könntest du das nochmal erläutern TDM. Ansonsten muss ich sagen, sehr sehr geiler Thread, hab noch nie drüber nachgedacht, aber jetzt *grinst* Viele Grüße relo Zitieren
TDM Geschrieben 24. Januar 2008 Geschrieben 24. Januar 2008 Post und Preinkrement. Aber ich muss sagen, ich hab es grad verwechselt. Eigentlich 1 += 3 + 2 Das Preinkrement (erst erhöhen und dann zurückgeben) wird zu erst aufgelößt. 1 += i++ + 1+1 (i = 2) 1 += 2+1 + 1+1 1 += 3 + 2 Naja, Perl halt. Edit: Um es mal mathematisch hervorzuheben. (i += ((i++) + (++i))) (++i) <- 1. Schritt. (i++) <- 2. Schritt. ((i'') + (i')) <-- 3. Schritt. i += i''' <-- 4. Schritt. Ich denke die Schritte variieren je nach Compiler oder so. Zitieren
relo Geschrieben 25. Januar 2008 Geschrieben 25. Januar 2008 So ergibt es "eigentlich" Sinn, aber ich muss sagen, das ist mal total wirr *lacht* Wozu hat man Post und Preinkrement, wenn es eigentlich so oder so anders gemacht wird, wie es eigentlich sein sollte. Vielleicht denke ich auch falsch oder in falschen Programmiersprachen, aber die Compilerprogrammierer haben doch einen Schaden *kichert* Danke für die Antwort nochmal TDM Viele grüße relo Zitieren
TDM Geschrieben 25. Januar 2008 Geschrieben 25. Januar 2008 So ergibt es "eigentlich" Sinn, aber ich muss sagen, das ist mal total wirr *lacht* Wozu hat man Post und Preinkrement, wenn es eigentlich so oder so anders gemacht wird, wie es eigentlich sein sollte. Vielleicht denke ich auch falsch oder in falschen Programmiersprachen, aber die Compilerprogrammierer haben doch einen Schaden *kichert* Es liegt definitiv nicht an den Sprachen, sondern am Compiler, ob er die Pre- und Postinkrements zu erst ausrechnet. Sonst würde ja nicht VC++ 7 und bei G++ 5 rauskommen. Ich persönlich finde, dass sie zu erst ausgerechnet werden sollten. Beim Postinkrement nach Standard erst das alte i zurückgeben und dann erhöhen. Dann kommt 7 raus: (i += ((i++) + (++i))) (++i) <- 1. Schritt. i = 2; 2 zurückgeben (i++) <- 2. Schritt. i = 3; 2 zurückgeben ((i'') + (i')) <-- 3. Schritt. 4 zurückgeben i += i''' <-- 4. Schritt. 3 + 4 = 7 Logik und was man draus macht. :beagolisc Zitieren
Klotzkopp Geschrieben 25. Januar 2008 Geschrieben 25. Januar 2008 Ich persönlich finde, dass sie zu erst ausgerechnet werden sollten. Beim Postinkrement nach Standard erst das alte i zurückgeben und dann erhöhen. Wozu hat man Post und Preinkrement, wenn es eigentlich so oder so anders gemacht wird, wie es eigentlich sein sollte. Das Problem ist hier nicht der Unterschied zwischen Prä- und Postinkrement. Das machen die Compiler schon richtig. Das Problem ist, dass in C und C++ nicht festgelegt ist, ob zuerst der linke oder der rechte Operand des + Operators ausgewertet wird, undwann sich der Nebeneffekt des Postinkrementoperators auswirkt. Laut Standard muss das nur vor dem nächsten "Sequence Point" sein. In diesem Fall ist der Sequence Point am Ende dieser ganzen Anweisung. Wie gesagt, der Wert dieses Ausdrucks ist in C und C++ ganz offiziell nicht definiert. Es bringt eigentlich nichts, sich darüber Gedanken zu machen, was bei diesem oder jenem Compiler dabei herauskommt. Der Code ist (zumindest in diesen beiden Sprachen) nicht standardkonform. Ein Entwickler, der sich darauf verlässt, dass dieser Code etwas bestimmtes tut, arbeitet IMHO unverantwortlich. Soweit ich weiß, ist in Java das Ergebnis festgelegt. In .NET ist es das vermutlich auch. Keine Ahnung, wie es bei Perl aussieht. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.