Frage zur Auswertungsreihenfolge von Operatoren in einem konkreten Fall
-
Laputzki schrieb:
Und um es in Anbetracht gegenteiliger Vermutungen von Belli und EOP ganz klar zu sagen: Nein, ich will hier niemanden verarschen, argumentiere hier nach bestem Wissen und Gewissen und bin für jeden eurer Versuche, mir zu helfen, dankbar, auch wenn sich die eine oder andere eurer Aussagen möglicherweise als nicht korrekt herusstellen sollte. Der gute Wille zählt, und den habe auch ich.
Du machst hier den Eindruck, willst du mit allen Mitteln deine Faustregel zurechtbiegen. Das geht aber nicht, da sie einen falschen Ansatz hat. Auf uns wirkt das, als würdest du unsere Erklärungen ignorieren oder falsch deuten.
Um nochmal auf das Beispiel vomgaeckler zurückzukommen:
mgaeckler schrieb:
(35 + 50) × (32 - 11)
Es gibt 2 mögliche Berechnungsarten:
int a = 35+50; int b = 32-11; int c = a*b;
int a = 32-11; int b = 35+50; int c = a*b;
Beide sind erlaubt. Deine Faustregel lässt aber nur eine Möglichkeit zu.
Es gibt nur 4 Ausnahmen, bei denen die Reihenfolge eindeutig ist: ';', ',', '&&' und '||'.
-
Die Operatoren rangfolge sagt nur aus, wie die Operatoren zu Ihren Operanden in Bezug stehen.
Also 5+2×3 heisst, das der Operator × zu den Operanden 2 und 3 gehört. Der Operator + hat die Operatoren 5 und 2×3. Welche der beiden zuerst in das Register geladen wird bleibt aber dem Compiler überlassen.
move #5, d0
move #3, d1
move #2, d2
mul d2, d1
Add d1, d0Ist ok
Move #2, d0
Move #3, d1
Mul, d1, d0
Move #5, d1
Add, d1, d0Ist auch ok
Wie Du siehst, wurden die drei Operatoren in unterschiedlicher Reihenfolge ausgewertet.
Diese 3 Operatoren könnten wieder Operationen mit eigenen Operatoren enthalten. Deren Reihenfolge ist dann auch entsprechend anders.
Hoffe es ist jetzt klar.
Mfg Martin
-
Darüber hinaus gibt es wohl ein kleines Missverständnis bezüglich dem Begriff der Auswertungsreihenfolge.
Bei so einem Ausdruck: a + b * c ist es natürlich klar, dass zuerst b * c multipliziert werden und dann a addiert. Aber hat man Funktionsaufrufe: a() + b() * c() ist es nicht spezifieziert in welcher Reihenfolge die Funktionen aufgerufen werden. Das meinte ich (und vermutlich andere) hauptsächlich mit Auswertungsreihenfolge.
-
Mach einfach keine so dämlichen Konstrukte wenn du nicht SeppJ's und Swordfish's code obfuscation contest beitreten willst.
In-/Dekremente sind immer mit Vor- und Voraussicht zu benutzen.
Aufgeteilt und eine Zeile mehr geschrieben kann dich vor überraschenden Ergebnissen bewahren.
Ansonsten ist das eine ziemlich überflüssige, konstruierte Geschichte, die eigentlich Keinem hilft.
Interessant wäre vielleicht wie das Ganze mit einem Präfix ausgehen würde.
Bliebe aber immernoch eine ziemlich überflüssige, konstruierte Geschichte, die eigentlich Keinem hilft.
-
EOP schrieb:
Mach einfach keine so dämlichen Konstrukte wenn du nicht SeppJ's und Swordfish's code obfuscation contest beitreten willst.
In-/Dekremente sind immer mit Vor- und Voraussicht zu benutzen.
Die Kurzschlussauswertung in Kombination mit Seiteneffekten auf der rechten Seite ist aber ein Klassiker der (nicht-obskuren) C-Programmierung. Das sollte man schon kennen und auch keine Scheu vor der Benutzung haben. Man kann auch sagen das muss man kennen, denn sonst kommt es schnell zu eben dem Fehler, vor dem du hier warnst. Aber wenn man es sowieso kennt, kann man es ja auch produktiv einsetzen
.
-
SeppJ schrieb:
EOP schrieb:
Mach einfach keine so dämlichen Konstrukte wenn du nicht SeppJ's und Swordfish's code obfuscation contest beitreten willst.
In-/Dekremente sind immer mit Vor- und Voraussicht zu benutzen.
Die Kurzschlussauswertung in Kombination mit Seiteneffekten auf der rechten Seite ist aber ein Klassiker der (nicht-obskuren) C-Programmierung. Das sollte man schon kennen und auch keine Scheu vor der Benutzung haben. Man kann auch sagen das muss man kennen, denn sonst kommt es schnell zu eben dem Fehler, vor dem du hier warnst. Aber wenn man es sowieso kennt, kann man es ja auch produktiv einsetzen
.
Wieso bist du um 3 morgens nicht im Bett, wo du eigentlich hingehörst?
EDIT:
Und - natürlich benutze ich es auch. Ist ja eine der Sachen, die ich an C/C++ ziemlich cool finde.
Aber nicht bei Konstrukten wieif( a < 1 && b < c++ || d > --c & f-- && ~g | --h ^ c )
Muss nicht sein wenn du vorhersagbare Ergebnisse haben willst.
-
Klar, kann man's auch übertreiben.
-
4 morgens und SeppJ sitzt immernoch aufm Wachturm. Unglaublich.
-
EOP schrieb:
4 morgens und SeppJ sitzt immernoch aufm Wachturm. Unglaublich.
Zeit ist relativ.
-
SeppJ schrieb:
Zeit ist relativ.
Für mich anscheinend auch.
-
EOP schrieb:
Mach einfach keine so dämlichen Konstrukte wenn du nicht SeppJ's und Swordfish's code obfuscation contest beitreten willst.
Siehst Sepp was wir angerichtet haben? EOP wird wohl alles obskur anmutende von nun an in die Obfuscation-Ecke stellen
-
Möglicherweise hat es gerade bei mir *klick* gemacht, also hoffe ich, dass ihr mir bestätigen könnt, dass mein folgendes Gedankenspiel korrekt ist:
Gegeben ist: 1 < 0 && 2 < a++
Was macht C nun damit? Nun, zunächst mal halten wir fest, was C damit nicht macht:
Compiler: "Dummdidumm was für ein schöner Morgen...oh was seh ich da? Ein Ausdruck, wie schön! Ich bin jetzt aber noch zu müde, mir sofort den ganzen Ausdruck anzusehen und in Gänze zu interpretieren. Also pick ich mir erstmal nur den Operanden mit der höchsten Priorität raus und guck mir den Rest später an. Na, dann komm her, kleiner Inkrement-Operator. Du zählst jetzt erstmal schön a um 1 hoch. Danke, jetzt darfst du dich wieder setzen. Sodelle, was haben wir noch? Aahhh, einen <-Operator, ein Klassiker! 1 < 0 ?? Unsinn! Setzen, sechs! *kopfschüttel* Wie gehts weiter? Hmm, ein &&-Operator...na, der dürfte von dem Quatsch, der da links von ihm veranstaltet wird aber gar nicht begeistert sein und bricht beleidigt den ganzen Ausdruck ab. Oh, hoppla, dann hätte ich dem Inkrement-Operator ja gar nicht sagen dürfen, dass er um 1 hochzählen soll...jetzt ist's zu spät...wie peinlich..."
Ok, das macht C also nicht. Und was macht es nun wirklich? Folgendes:
Compiler: "Dummdidumm was für ein schöner Morgen...oh was seh ich da? Ein Ausdruck, wie schön! Ich bin zwar noch nicht ganz wach, aber bevor ich hier irgendeinen peinlichen Unsinn anstelle, guck ich mir den Ausdruck lieber erstmal ganz genau von vorne bis hinten in seiner vollem Pracht an, um zu wissen, was der letztendlich im Schilde führt. Du brauchst gar nicht so eifrig zu winken, kleiner Inkrement-Operator. Ich hab dich schon gesehen und weiß, dass du die höchste Priorität hast, du kleiner Angeber. Aber ich guck mir erst noch deine Freunde an, was die so vorhaben. *guck* *amkopfkratz* *grübel* Aha, der &&-Operator wird, wenn ich den Code ausführe, wieder die beleidigte Leberwurst spielen und allen den Spaß versauen. *kopfschüttel* Sorry, kleiner Inkrement-Operator, du hast zwar die höhere Priorität, aber wenn hier eh gleich das Spielbrett vom Tisch gefegt wird, ist es auch überflüssig dich vorher noch a um 1 hochzählen zu lassen. Sei nicht traurig, morgen ist ein neuer Tag."
Ist das so korrekt? Der Compiler analysiert erst den Gesamtausdruck und entscheidet dann, dass der Inkrement-Operator, obwohl seine Priorität höher ist als die des &&-Operators, nicht ausgeführt wird, da der &&-Operator das nachträglich als Fehler entlarfen würde?
EOP schrieb:
Mach einfach keine so dämlichen Konstrukte wenn du nicht SeppJ's und Swordfish's code obfuscation contest beitreten willst.
In-/Dekremente sind immer mit Vor- und Voraussicht zu benutzen.
Aufgeteilt und eine Zeile mehr geschrieben kann dich vor überraschenden Ergebnissen bewahren.
Ansonsten ist das eine ziemlich überflüssige, konstruierte Geschichte, die eigentlich Keinem hilft.
Da stimme ich dir voll und ganz zu. Ich selbst würde das auch so nicht schreiben. Ich will aber darauf vorbereitet sein, sowas in der anstehenden Klausur richtig lösen zu können. In den vom gleichen Proffessor gestellten Übungen kam der In-/Dekrement-Operator dran und sorgte bei den meisten für reichlich Verwirrung.
EOP schrieb:
Interessant wäre vielleicht wie das Ganze mit einem Präfix ausgehen würde.
Jemand 'ne Idee?
-
Laputzki schrieb:
Ist das so korrekt? Der Compiler analysiert erst den Gesamtausdruck und entscheidet dann, dass der Inkrement-Operator, obwohl seine Priorität höher ist als die des &&-Operators, nicht ausgeführt wird, da der &&-Operator das nachträglich als Fehler entlarfen würde?
Natürlich muss ein Compiler immer das gesamte Statement "ansehen". Bei deinem Beispiel
1 < 0 && 2 < a++
geht es aber nicht um ausführen oder nicht ausführen. Für2 < a++
wird schlicht garkein Code erzeugt, weil1 < 0
immerfalse
ist.Laputzki schrieb:
EOP schrieb:
Interessant wäre vielleicht wie das Ganze mit einem Präfix ausgehen würde.
Jemand 'ne Idee?
*kopfkratz* was?
-
Laputzki, wenn du mit deinem Prof ebenfalls wie mit einem Vierjährigen redest, kriegst du auf jeden Fall einen Schein. Nur nicht den, den du erwartest.