Mehrere Ergebnisse mit einer Funktion

Kachelator

Peter Jerz
Original geschrieben von umbrasaxum
moin


Nochmal!
Du hast die Subtraktion und die Division vertauscht!

Außerdem verstehe ich nciht warum du die Funktion "gesamt" nicht benutzt?!

mfg
umbrasaxum
Will er wohl, aber hat sich vermutlich vertippt. Jedenfalls sieht diese Zeile so aus:
Code:
(a,b,add_erg,div_erg,mul_erg,sub_erg);
Das sollte der Aufruf sein, oder? Da fehlt das "gesamt" vorne.
 

Dudadida

Erfahrenes Mitglied
@Kachelator: Ich finde die Array-Lösung nicht unanschaulich. So bleibt das meiner Meinung nach sogar übersichtlicher, weil man halt nach wie vor nur 2 Parameter übergibt und einen einfachen Zeiger auf die Lösungen zurückbekommt. Man braucht sich doch nur zu merken in welches der 4 Teile was gespeichert wurde, hat alles strukturell schön identisch und kann sogar arrithmetisch damit arbeiten ("ich drücke die 1, also nehme ich das 1. Element", das geht mit unterschiedlichen Namen nicht ohne blöde Abgleiche). Ich finde das ist manchmal leichter als sich hunderte von Variablen einzuprägen, die alle komplett unterschiedlich heißen und/oder die vollkommen schwachsinnig benannt wurden (manche mögen es ja das Alphabet erstmal durchzugehen, statt sich sinnvolle Namen auszudenken...).
 

Kachelator

Peter Jerz
Stell dir vor, du bekommst von irgendeiner Library so eine Funktion vorgesetzt: Was ist einfacher: Wenn du 4 benannte "Rückgabe"-Parameter hast, oder ein homogenes Array zurükbekommst, das du als User der Lib sogar noch selber freigeben musst -- und dann auch noch mit der richtigen Methode? Aua!

Das Alloziieren innerhalb der Funktion (deren interne Funktion ja zur korrekten Freigabe dem User bekannt sein muss, um zu entscheiden, ob delete, delete[], free oder sogar GlobalFree verwendet werden muss) empfinde ich als besonders kritisch.

Das ist es schon besser, wenn der User ein lokales Struct definiert und einen Pointer auf dieses an die Funktion übergibt, wie es in der Windows-API Quasistandard ist.

Oder man gibt einen std::vector zurück, der mit Werten gefüllt ist -- das ist zwar eventuell etwas teurer, aber man hat keine offenen Fragen zur Verantwortlichkeit der Ressourcenfreigabe.

All diese Wege lösen übrigens auch nicht das Problem der Rückgabe von verschiedenen Datentypen. Da muss ein std:: pair oder boost::tuple her, was meiner Meinung nach ohnehin der beste Weg ist : http://www.boost.org/libs/tuple/doc/tuple_users_guide.html (oder die Rückgabe eines std:: pairs) [das Forum macht aus : p immer :p!]
 

Dudadida

Erfahrenes Mitglied
Ja, du magst damit ja recht haben, ich habe mein Bsp. aber eben genau auf die Anforderungen dieser Aufgabe hier zurechtgeschneidert. Es geht hier ja sicher nicht darum 'ne Bibliothek für einfachste Arithmetik zu schreiben. Wenn ich irgendetwas Programmübergreifendes schreibe, dann sehe ich prinzipiell zu, möglichst intuitiven Code zu erzeugen (zumindest nach außen hin), wie ich intern arbeite, interessiert dabei aber keinen und deswegen mache ich es so, wie ich es für sinnvoll halte. Und bei diesem Beispiel halte ich es für sinnvoll einen Zeiger von der Funktion zurückzubekommen und ihn wieder mit delete [ ] freizugeben (wo die Initialisierung nur ein paar Zeilen höher steht), und das ganz ohne Referenzen (die Anfänger oft noch mehr verwirren als Zeiger, wie ich festgestellt habe) und aufgeblähten Funktionsaufruf. Innerhalb seines Programms nimmt man für gewöhnlich sowieso immer die gleichen Allozierungsmethoden und weiß wie man mit einem Zeiger umzugehen hat.
 

Kachelator

Peter Jerz
Wenn ich irgendetwas Programmübergreifendes schreibe, dann sehe ich prinzipiell zu, möglichst intuitiven Code zu erzeugen (zumindest nach außen hin)
Warum nicht immer intuitiv schreiben und auf der sicheren Seite bleiben?

und das ganz ohne Referenzen (die Anfänger oft noch mehr verwirren als Zeiger, wie ich festgestellt habe) und aufgeblähten Funktionsaufruf
Es ist zwar richtig, das Referenzen nicht unbedingt sofort verstanden werden, aber das gilt genauso für Zeiger und Arrays. Ich denke nicht, dass Referenzen da besonders problematisch sind. Und gerade wenn man etwas zeitgemässeren Code schreibt, kommt man um Referenzen ohnehin nicht herum, wobei ich mit zeitgemäss einfach nur meine, dass man C++ schreibt anstelle von "C mit Schuss". Zeiger haben ihre Rechtfertigung immer noch, aber man kann und sollte lernen, sie bewusst einzusetzen und auf sie zu verzichten, wenn es eleganter geht.

Und bei diesem Beispiel halte ich es für sinnvoll einen Zeiger von der Funktion zurückzubekommen und ihn wieder mit delete [ ] freizugeben (wo die Initialisierung nur ein paar Zeilen höher steht)
Noch steht er in unmittelbarer Nähe, aber es ist wahrscheinlich, dass er das nicht immer tun wird.
Die Rückgabe von innerhalb Funktionen allozierten Objekten, kombiniert mit Übertragung der Verantwortung auf den User, ist eine gefährliche, schlechte Angewohnheit, und gerade einem Neuling, der es nicht besser weiss, sollte man sowas nicht vormachen. Das Argument, dass es nur für einen selbst ist, lasse ich so nicht gelten, da ich weiss, wie man nach einigen Wochen dem eigenen Code gegenübersteht... dann ist man sein eigener User und dankbar für jedes bischen Dokumentation, zum Beispiel in Form von benannten Parameternamen, der einem das Rätselraten erspart: "Hm, welcher Arrayindex war denn jetzt nochmal der mit dem Resultat der Multiplikation, und muss ich das Ding jetzt freigeben?" Wenn schon, dann wäre eventuell ein Enum dafür zu definieren.
 
Zuletzt bearbeitet:

Dudadida

Erfahrenes Mitglied
Naja, ist meiner Meinung nach nach wie vor Ansichtssache. Generell kommentiere ich meinen eigenen Code eigentlich immer ausreichend (denn das Problem mit dem "wieder reinfinden" ist mir leider durchaus bekannt :)).
Also ich finde Zeiger eigentlich ziemlich elegant in vielen Fällen und Zeiger sind einfach die eindeutigere Variante, weil man halt auch in der Benutzung einen klaren Unterschied zu den Wertparametern hat. Ich bin da wohl eher ein Freund von "C mit Schuss" :).