Entwickler-Ecke
C# - Die Sprache - Wann Zuweisung, wann Funktionswertrückgabe?
Delphi-Laie - Di 12.06.12 23:23
Titel: Wann Zuweisung, wann Funktionswertrückgabe?
Hallo C#-Experten!
Mit C & Derivaten habe ich weiterhin so meine Probleme. Jetzt raubt mir wieder ein Konstrukt in C# den letzten Nerv. Es geht um:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| using Xint = System.Numerics.BigInteger; . . . private Xint Product(int n)
{ int m = n / 2; if (m == 0) return (Xint)(currentN += 2); if (n == 2) return (Xint)((currentN += 2) * (currentN += 2)); return Product(n - m) * Product(m); } |
Mein Problem liegt in der 2. und 3. Anweisungszeile dieser Routine (Zeilen 8 und 9 im Zitat). Berechnung und Zuweisung des Rückgabewertes werden mit der Zuweisung eines neuen Wertes an currentN (weiter oben als int definiert) vermischt - was ja üblich und typisch für C & Co. ist. Das kann ich leider nicht nach Delphi übersetzen. Auch das Ausprobieren aller mir möglich erscheinenden Varianten half mir nicht weiter. Also: Wird zuerst der Rückgabewert berechnet und zugewiesen und dann der Wert von currentN um 2 erhöht und zugewiesen oder umgekehrt? Und was bedeutet die zweimalige Addition von 2 zu currentN in der 3. Codezeile der Routine? Wird einmal mit currentN+2 und bei zweiten Male (weil ja currentN+2 schon einmal berechnet wurde) faktisch mit currentN+4 (aus Sicht des Ausgangswertes der Variable currentN)? Und was bedeutet (Xint) als erster Ausdruck nach dem return? Eine Typkonvertierung zu BigInteger ("Casting")?
Nur zwei Zeilen Quellcode, aber sie erzeugen leider eine Menge Fragen. Vielleicht hat jemand die Geduld, sie (mir) zu beantworten. Dafür vielen Dank im voraus!
Gruß Delphi-Laie
Moderiert von
Christian S.: Quote- durch C#-Tags ersetzt
Christian S. - Mi 13.06.12 00:19
Hallo!
Hier sind zwei Dinge relevant. Zum einen kann x+=y; geschrieben werden als x = x + y;. Eine solche Zuweisung hat in C# einen Rückgabewert, nämlich das Ergebnis der Zuweisung. Man verwendet also den Wert, der nach der Zuweisung in x steht. Zum anderen erfolgt die Auswertung immer von links nach rechts.
Das heißt, in Zeile 9 des Quelltextes (zweite Anweisungszeile) wird erst currentN um 2 erhöht und das Ergebnis zurückgeliefert.
In Zeile 10 (dritte Ausführungszeile) wird erst currentN um 2 erhöht, das Ergebnis dieser Rechnung ist der erste Multiplikand. Anschließend wird currentN erneut um 2 erhöhrt, das Ergebnis ist der rechte Multiplikand. Daraus wird dann das Produkt gebildet. Somit ist, vom Ausgangswert gesehen, der rechte Multiplikant currentN + 4, das ist richtig.
Das (XInt) ist ein Casting.
Viele Grüße,
Christian
Delphi-Laie - Mi 13.06.12 09:35
Hallo Christian, vielen Dank für Deine Geduld und Ausführlichkeit!
Die Kurzform der Wertzuweisungen (+=, -=, *= usw.) war mir schon bekannt, danach fragte ich nicht. Diese Vermischung aus Rechenoperation und "gleichzeitiger" Wertzuweisung irritierte mich. "Irgendwie" muß ich aber beim Probieren auch eine Variante in der Mangel gehabt haben, die Deiner Beschreibung zumindest nahekommt. Für Delphi benötige ich wohl tatsächlich eine temporär zu nutzende zusätzliche Variable. Das ist eben der Preis der größeren Übersichtlichkeit (Übersichtlichkeit zumindest auf den ersten Blick).
Nochmals besten Dank!
Gruß Delphi-Laie
Ralf Jansen - Mi 13.06.12 09:37
Zitat: |
Nur zwei Zeilen Quellcode, aber sie erzeugen leider eine Menge Fragen. |
Nur um es gesagt zu haben. Das liegt nicht an der Sprache sondern an der Code Qualität.
Delphi-Laie - Mi 13.06.12 10:11
Ralf Jansen hat folgendes geschrieben : |
Zitat: | Nur zwei Zeilen Quellcode, aber sie erzeugen leider eine Menge Fragen. |
Nur um es gesagt zu haben. Das liegt nicht an der Sprache sondern an der Code Qualität. |
Das suggeriert m.E. eine verminderte Qualität. Nun kann man Quellcode qualitativ drücken (schlecht oder gar nicht strukturieren, z.B. auch mehrere Anweissungen in eine Zeile quetschen, nicht einrücken u.ä.).
Hier wurde der Quellcode aber insofern "sauber" erstellt und dadurch etwas komprimiert, daß angebotene Sprachmittel genutzt werden, was konseqeunt wirkt. Natürlich kann man es auch ausführlicher aufschreiben. Ist die Codequalität deshalb vermindert? Wer ist "schuld": Der Codeschreiber oder die Programmiersprache an sich? Ansichtssache, meine ich.
Ralf Jansen - Mi 13.06.12 10:24
Vielleicht ist Code Qualität nicht ganz die treffende Wortwahl gewesen. Aber Code der sein Verhalten unnötigerweise nicht offensichtlich darstellt ist für mich schlechter Code.
Dieser Code wäre mit ein paar mehr Zeilen Code lesbarer und dabei keinen Takt langsamer. Für die Maschine ist die ~Komprimierung~ ok dem Leser zwingt sie ein paar Extra Denktakte auf.
Delphi-Laie - Mi 13.06.12 11:06
Ist schon klar, aber das ist doch das Wesen der Programmiersprache C und ihren Derivaten?!
Mich stört es auch, daß ich beim Lesen C-artiger Quelltexte mich nicht maximal auf den Inhalt, den Algorithmus konzentrieren kann und immer und immer wieder von solch komprimierten Konstrukten abgelenkt werde und mich in diese hineindenken muß. Doch inzwischen bin ich der Meinung, daß das nur eine Frage der Übung ist.
Delphi hat derlei "Komprimate" längst nicht so viele zu bieten, doch ich benutze z.B. auch inc, dec, succ und pred ohne jedes Schamgefühl und fühle mich, da eben damit ertraut, beim Lesen von Pascal-Quelltexten davon nicht gestört oder behindert.
Yogu - Mi 13.06.12 15:08
Hallo,
nun misch ich mich auch mal wieder ein. Mit der Philosophie hinter C oder C++ bin ich nicht vertraut, aber das Wesen von C# ist ganz klar ein strukturierter, einfach zu lesender Code. Aus diesem Grund wurden Dinge wie Polymorphie entfernt.
Der Quelltext, um den es hier geht, stört mich in sofern, dass die
return-Klauseln einen Nebeneffekt haben, nämlich das Verändern eines Feldes. So etwas sollte auf jeden Fall vermieden werden, auch in C#. Ich würde ihn daher vielleicht so umschreiben:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| if (m == 0) { currentN += 2; return (Xint)current; } else if (m == 2) { currentN += 4; return currentN * (currentN - 2); } else return Product(n - m) * Product(m); |
Das aber nur am Rande.
Grüße,
Yogu
Ralf Jansen - Mi 13.06.12 18:46
Zitat: |
Mit der Philosophie hinter C oder C++ bin ich nicht vertraut, aber das Wesen von C# ist ganz klar ein strukturierter, einfach zu lesender Code |
Trotzdem benutzt du den Linux C Stil (ich nenn den mal so) zum Einrückung der Klammern? Das findet man sonst eigentlich nur noch bei den C/C++ Leuten aber kaum im C# Bereich. Gesehen habe ich sowas nur bei Umsteigern die nicht loslassen können oder wollen ;)
Kha - Mi 13.06.12 18:56
Den benutze ich auch :( . Ich mag keine fast-leeren Zeilen, wenn dann schon ganz Leerzeilen ;) .
Yogu - Mi 13.06.12 19:44
Den Einrückstil habe ich wohl von JavaScript mitgenommen. Aber das vermindert in meinen Augen die Lesbarkeit des Quelltextes nicht, da der innere Teil ja eingerückt wird. Wie
Kha schon schreibt, entstehen durch die Standard-Formatierung viele Zeilen mit nur einer geschweiften Klammer, und daher passt weniger auf einen Bildschirm.
ujr - Do 14.06.12 09:07
Kha hat folgendes geschrieben : |
Ich mag keine fast-leeren Zeilen, wenn dann schon ganz Leerzeilen ;) . |
Seh' ich genauso. Allerdings nötigen die Visual-Studio-Standardeinstellungen inkl. "Autoformat" und ein Team, das diese Optionen nicht verändern möchte, aufgrund ansonsten häufiger Änderungen für die Versionverwaltung, zur Änderung.
Aber ich hatte auch schon immer "Begin" auf die vorherige Zeile verschoben (etwa if/then). Vielleicht kommt die Vorliebe daher.
Ralf Jansen - Do 14.06.12 09:51
Zitat: |
Ich mag keine fast-leeren Zeilen, wenn dann schon ganz Leerzeilen |
Ich vermute mal dein Code sähe aber trotzdem anders als als der von Yogu oder? Der gibt für mich optisch kaum zu erkennen wo die einzelnen Blöcke starten oder enden. Die Einrückung der Blöcke ist identisch und es gibt keinen offensichtlichen Trenner. Zumindest für mein für diesen Stil ungeübtes Auge übersieht die geschweiften Klammern und glaubt erstmal an einen zusammenhängenden Codeblock. Das da auch else Zweige sind fällt erst später auf.
Palladin007 - Do 14.06.12 12:41
Also ich persönlich finde es am angenehmsten, wenn man jeden Block mit einer einsamen geschweiften Klammer beginnt und endet.
Nagut, bei z.B. Schleifen lasse ich die auch gerne weg, wenn ich den Code im Block auf eine Zeile reduzieren kann.
Ich bevorzuge also die neue C#-Schreibweise, versuche aber immer, den Code möglichst zu kürzen. Wenn eine Zeile dann besonders lang wird, dann kann ich sie ja über mehrere Absätze teilen oder mit Kommentaren zeigen, was darin passiert.
Aber ich persönlich mag es z.B. nicht, eine Variable zu deklarieren und erst in der folgenden Zeile zu instanzieren.
Das ist jetzt nur ein Beispiel, aber ich habe gerne alles kompakt.
So, aber was hat das jetzt eigentlich mit dem eigentlichen Thema zu tun? O.o
Ralf Jansen - Do 14.06.12 13:37
Zitat: |
So, aber was hat das jetzt eigentlich mit dem eigentlichen Thema zu tun? O.o |
Du verpfeifst uns doch jetzt nicht bei den on-topic Wächtern? Hast schließlich beim off-topic Teil selbst mitgewirkt. Ich zieh dich da gnadenlos mit rein. :twisted:
Palladin007 - Mo 18.06.12 20:17
Ich doch nicht :D
Bin da der Letzte xD
Ich bin sowieso dafür, mal ein Spam-Forum für die Programmier-Spammer auf zu machen :D
So für freie Diskussionen über die Welt der Programme und allgemein und so^^
Delphi-Laie - Mo 18.06.12 22:22
Ihr seid ja wirklich tüchtig vom Thema "meiner" Diskussion abgekommen. Danke noch einmal, und das Problem ist für mich längst gelöst, und als Dankeschön verrate ich auch, worum es ging, nämlich darum, einen Fakultätsalgorithmus, den ich auf der Seite von Peter Luschny als C#-Quelltexte (
es war Splitrekursiv [
http://www.luschny.de/math/factorial/csharp/FactorialSplit.cs.html]) fand, nach Pascal bzw. Delphi zu übersetzen.
Postscriptum: Natürlich verpetze ich niemanden wegen der Themaabweichung, solang es nicht überhandnimmt. :wink:
Palladin007 - Mo 18.06.12 22:32
Der Link ist down O.o
Liegt wahrscheinlich daran, dass der unvollständig ist ^^
Und Programmierung ist doch schon was tolles, wenn man dem PC so die ganzen unangenehmen Aufgaben (wie z.B. Mathe) auftragen und dabei sogar noch Spaß haben kann, oder? :D
Delphi-Laie - Mo 18.06.12 23:31
Korrigiert, danke für den Hinweis!
In den Locator rutschte ein %29 oder ähnlich am Ende hinein; meine Schuld war das nicht, denn ich gab das nicht ein, jedenfalls nicht explizit.
Sicher macht mir Mathematik Spaß, sonst wäre ich nicht mit so etwas bei der Sache.
Daß die allermeisten Mathematik nicht mögen, kann ich allerdings nachvollziehen: Dieses Fach wird seit Jahrzehnten, ja wohl eher schon seit Urzeiten pädagogisch und evtl. auch methodisch-didaktisch fehlerhaft vermittelt.
ujr - Di 19.06.12 10:32
Delphi-Laie hat folgendes geschrieben : |
verrate ich auch, worum es ging, nämlich darum |
Was sich anhand des Quelltexts aber ohnehin unschwer finden ließ.
:lol:
Palladin007 - Di 19.06.12 14:08
Ich hab auch nichts gegen Mathe, aber ich finde es trotzdem cool, was man mit einer guten Programmier-Umgebung, einer Programmiersprache, die man beherrscht und einem halbwegs tauglichen PC alles abwälzen kann :D
Und die Lehrer sollen dagegen mal nix sagen, weil ein Programm schreibt, dass eine bestimmte Formel oder sogar ein ganzen Aufgabenbereich immer korrekt berechnet, der muss das alles verstanden haben, sonst würde nur Blödsinn bei raus kommen. :D
Auch mit der Aussage, dass Mathe falsch vermittelt wird, hast du Recht, allerdings ist das nicht alles:
Denn ich denke, dass das Thema an sich mittlerweile in einer Art Teufelskreis ist. Alle (ok, fast alle) hassen Mathe und meckern ständig, sodass die jüngeren Schüler nach dem Propaganda-Prinzip dazu getrimmt werden, Mathe ebenfalls zu hassen. Und wer ein Fach hasst, ist total demotiviert und bekommt folglich auch keine guten Leistungen zu Stand. Das sorgt wieder für schlechte Laune und Hass gegenüber dem Fach, womit sich der Kreis wieder schließt.
Ist denke ich mal bei vielen Fächern, die eben etwas mehr geistige Arbeit fordern, als Andere. Informatik mit dem Thema Java bei uns war da kein Unterschied. Physik, was ja eigentlich auch ganz interessant sein kann, fällt da auch rein, Biologie, Chemie, etc. Bei all den Fächern muss man oft aktiv mit denken und auch mal einstecken können, dass man etwas nicht versteht. Das kann man bei z.B. Englisch oder Geologie lange suchen, denn wer da fleißig genug lernt, der wird auch zumindest halbwegs gute Noten bekommen.
Mein Fazit: Wir Schüler sind im Grunde selber Schuld, denn dass wir nicht bereit sind, mal die Faulheit links liegen zu lassen (schaffe ich auch nicht :D) sorgt dafür, dass wir im Unterricht gerne mal nicht auf passen und danach das gerade Erklärte nicht verstehen. Die Lehrer haben einen Zeitplan einzuhalten und wollen es auch einfach nicht wiederholen und das kann ich vollkommen verstehen, denn der Schüler kann ja auf passen.
Mathe ist nun mal ein Fach, bei dem man nicht einfach mal 30 Minuten abschalten und quatschen kann. Gut manche können das trotzdem, aber das sind dann die, die alle diese komplizierteren Dinge können, wie auch Informatik und die finden sich hier wieder :D
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!