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
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.
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
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.
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:
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.
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.
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.
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...
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)
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;
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
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.
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
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
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.
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren
Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde Dich hier an.
Jetzt anmelden