Diskussion:Referenzparameter

Letzter Kommentar: vor 10 Jahren von Redeemer in Abschnitt „Sonderfall“ Java

Korrektes C?

Bearbeiten

Grund: Wenn ich mich recht entsinne, müssen seit ISO-C99 alle Variablen im Funktionskopf einen Typen aufweisen; alles andere ist nicht erlaubt bzw. deprecated.

Beispiel:

/*ILLEGAL / DEPRECATED */
int main(argc, argv)
         int argc, char** argv
    {
    /*...*/
    return 0;
    }
/* LEGAL */
int main(int argc, char** argv)
    {
    /*...*/
    return 0;
    }

Anmerkung: Natürlich wäre char* argv[] noch besser (und korrekter).

K&R C ist auch (und insbesonders!) korrektes C, von den Ideen von C her für eine Enzyklopädie besser geeignet. Im Artikel ist die main()-Zeile natürlich irrelevant, könnte also geändert werden. --Hubi 07:17, 5. Feb 2005 (CET)
Das stimmt nicht. Bei Widersprüchen zwischen K&R und der aktuellen Fassung gilt die aktuelle Fassung.
Und warum sollte K&R für eine Enzyklopädie besser geeignet sein? Poldi 13:44, 5. Feb 2005 (CET)
und was ist denn die "aktuelle Fassung"? Das was aktuelle Compiler verarbeiten, das was ISO definiert oder wie genau? Wenn die ISO eine neue aktuelle Fassung rausbringt, verarbeiten alle modernen C-Compiler möglicherweise instantan inkorrektes C. K&R ist die Urfassung von C, verfolgt einfache Konzepte. Aber ist ja auch egal, da sich bei Referenzparametern nichts geändert hat. --Hubi 15:29, 5. Feb 2005 (CET)#

Der (kurze) Abschnitt über C++ ist/war voler Feler. Zunächst wurde behauptet, C++ würde"im Gegensatz zu C" Wertparameter übergeben. Das ist falsch, da Felder und Funktionen wie in der C-Semantik natürlich Referenzparameter übegeben. Dann wird ständig behauptet, in C++ würde nicht die Adresse übergeben. Hier wird die Notation und die tatsächliche Verfahrensweise verwechselt. Selbstverständlich benötigt die Prozedur mit dem Referenzparameter die Adresse der Veriablen x, um sie inkrementieren zu können. Parameterübergabe heisst Zuweisung des aktuellen an den formalen Parameter. Da wird auch in C++ die Adresse übergeben, der Compiler erkennt aufgrund der Deklaration den Referenzparameter. Außerdem behauptet der Artikel vorher korrekt, dass Referenzparameter die Adresse übergeben. C++ ist hier keine Ausnahme. Sollte es eine sein, müsste dies näher ausgeführt werden. --Hubi 08:46, 7. Feb 2005 (CET)

Der ursprüngliche Verfasser ist noch Wiki-Neuling. Da darf er ein paar Fehler machen. Den Satz mit den Wertparametern finde ich auch nicht so gut. Vielleicht hätte ich mehr ändern sollen. Vor allem: Was heißt "normalerweise"? Mit der Sprachwahl "Referenzparameter" auch für Zeiger bin ich nicht ganz glücklich. Ist zwar nicht falsch, führt aber für den unkundigen Leser sicher zu Verständnisschwierigkeiten, da es "Referenzen" außerdem noch im engeren Sinne gibt.
Zu den "internen" "Adressen": Ist Implementierungssache (kann der Optimierer rausschmeißen). Poldi 19:19, 8. Feb 2005 (CET)
Jetzt steht zum 3. Mal Müll da. Im Gegensatz zu C wird bei C++ nicht die Adresse übergeben. Was bedeutet das wohl? Dass niemals die Adresse übergeben wird. Muss man jedenfalls so lesen. Absolut lächerlich. Dass ein Optimierer die Adresse evtl. durch den Wert ersetzen kann, was im übrigen nur bei kleinen, unstrukturierten Typen sinnvoll ist und daher wohl kaum vorkommt, steht so nicht im Artikel. Ein Optimierer würde bei grossen Strukturen eher Wertparameter durch Referenzparameter ersetzen. So, wie's dasteht absoulut falsch. Auch im Beispiel kann man wohl kaum den Wert übergeben! --Hubi 06:22, 9. Feb 2005 (CET)
So, jetzt mal Butter bei die Fische: Ob auf Maschinenebene eine Adresse übergeben wird, oder nicht, ist ein Implementierungsdetail. Das macht der eine Compiler so, und der andere macht es anders, und das ggf. auch noch von Fall zu Fall unterschiedlich. Wie es intern gemacht wird, ist ein Detail, das an dieser Stelle irrelevant ist. Deshalb sehe ich nicht ein, warum man hier etwas dazu schreiben soll. - Die in diesem Zusammenhang interessierende Bedeutung des Wortes "Adresse" (aha, das Wort hat mehrere Bedeutungen!) ist die auf Hochsprachenebene, und wie man deutlich sehen kann, kommt bei der C++-Variante nicht der Adressoperator zur Anwendung. Allein darum geht es. Er ist einfach nicht da.
Es geht doch in diesem Artikel nicht um Optimierungstechniken! Im Übrigen irrst du dich: Compiler führen die genannte Optimierung sehr wohl durch. Sowohl Maschinen-Adresse durch Wert ersetzen, als auch die andere Optimierung, nämlich statt Struktur Maschinen-Adresse übergeben. Und darüber hinaus gibt es noch weitere Transformationen, bei denen intern die Adresse rausfliegt, aber darum geht es hier wie gesagt nicht.
Und noch mal: Du willst immer darauf abheben, was intern passiert, und das ist einfach nicht vorgeschrieben. Ich zitiere dich: "Referenzparameter übergeben in Lowlevel immer die Adresse, oder?)". Und das ist einfach falsch. Referenzparameter übergeben Lowlevel nicht immer die Adresse. Außerdem hast du geschrieben "Ein Compiler muss jedoch aufgrund der Deklaration die Adresse des Parameters an die Prozedur übergeben.", was ebenfalls falsch ist. Poldi 18:05, 9. Feb 2005 (CET)


Nein, ich störe mich an der Formulierung: Bei C++ wird im Gegensatz zu C nicht die Adresse übergeben. Erstens besteht kein grundsätzlicher Gegensatz zu C und wenn der Satz lautete: Bei C++ wird im Gegensatz zu C nicht unbedingt die Adresse übergeben, wäre ich schon einverstanden. Im Beispiel kann aber nicht der Wert übergeben werden kann, da die Lokation für das Inkrementieren erforderlich ist. Daher meine Formulierung, die aus dem Zusammenhang (Beispiel) gerissen nicht richtig ist.
Dass es nicht um Optimierung geht (was ich niemals behauptet habe), ist mir klar. C++ kann aufgrund weitergehender Informationen besser optimiert werden, die Referenz (=typisierte Adressen)-Semantik muss aber eingehalten werden. --Hubi 06:39, 12. Feb 2005 (CET)
Ich habe jetzt noch einmal die Beispiele überarbeitet. Ich habe dabei nicht so sehr auf die Unterschiede zwischen C und C++ gesetzt, denn darum geht es ja hier gar nicht, sondern die verschiedenen Notationen (Zeiger / Referenz) hervorgehoben. So besser? Poldi 19:40, 14. Feb 2005 (CET)
Na ja, jetzt ist kein grober Fehler mehr drin, also akzeptiert. Der Unterschied Referenzen/Zeiger wird nicht so klar, dass C keine Referenzparameter hat und eigentlich mE emuliert, sollte besser hervorgehoben werden. Dass Referenzparameter als Referenz übergeben werden ist fast eine Tautologie, hier müsste Referenz erklärt werden (Typ+Location etc.). C++ sollte aus erklärungstechnischen (didaktischen) Gründen vor C stehen. --Hubi 07:35, 16. Feb 2005 (CET)

unterschied

Bearbeiten

am ende des artikels ist das c++ beispiel mit "Referenzparameter in Form von Referenzen" geben.

macht das programmmäßich denn einen unterschied, oder ist es total egal, ob ich es nach version a oder version b schreibe?

danke, --Abdull 14:42, 16. Feb 2005 (CET)

Das Ergebnis ist das gleiche. Aber es kann sein, dass ein Programmierer mit einer der beiden Formen besser zurecht kommt.

Referenzparameter in C++

Bearbeiten

In C++ gibts neben "normalen Referenzparametern" ja noch "konstante Referenzparameter". Und da kann man sehr wohl beliebige Ausdrücke übergeben:

 void foo(const std::string& s)
 { ... }
 
 void rufe_foo()
 {
    std::string h("Hello");
    std::string w("world");
    foo(a + ", " + w + '!');
 }

Ich weiß nicht, ob dieses Feature nun zu speziell ist, um im Artikel erwähnt zu werden, aber so wie es jetzt im Artikel steht, ist es jedenfalls nicht korrekt. :-( --RokerHRO 09:59, 30. Mär 2006 (CEST)

Java ist call by value

Bearbeiten

Java ist "call by value"-only. Bei einem Call wird die Value übergeben, sei es eine "Adresse" oder ein primitiver Datentyp. Das verdeutlicht ja auch schon der Artikel, warum wird das dann nicht gesagt?

"In der Sprache Java wird bei primitiven Datentypen automatisch ein Wertparameter verwendet. Bei Objekten wird die Objektreferenz als Wertparameter durch Kopie übergeben." Das ist verwirrend und irreführend, warum nicht einfach: "In der Sprache Java werden primitive Datentypen, genau wie Objektreferenzen, als Werte gespeichert. Bei Funktionsaufrufen werden die Werte übergeben."

Ehrlich gesagt bin ich dafür diesen Abschnitt ersatzlos zu streichen. Wenn nicht, bin ich dafür für alle Sprachen, die kein Call-By-Reference haben, solche Abschnitte zu schreiben. Das wären quasi fast alle Sprachen. :D

Nein, im Ernst: Sicher lohnt sich ein Abschnitt, der den weitverbreiteten Irrglauben beschreibt, dass Java (und Javascript) "Call by Reference" für Objekte unterstützen sollen. Tragischerweise ist das ja sogar in vielen einigermaßen seriösen Dokus falsch beschrieben, im Falle von Javascript sogar in den Mozilla-Dokus. --hasta luego 18:03, 5. Jan. 2011 (CET)Beantworten

Es werden in Java Objekte generell nur über Referenzen angesprochen. Man merkt dies als Programmierer aber halt nicht, da man (wenn man von C kommt) bei foo.bar sich dessen vielleicht nicht so bewusst ist wie bei einem expliziten foo->bar. :-/
Entweder man bläut den Java-Programmieren ein: "Ihr habt keine Objekte, nur Objektreferenzen; letztere werden by-value übergeben, nicht aber die Objekte selbst" oder man schreibt es wie in den meisten Java-Lehrbüchern: "Primitive Datentypen werden by-value, Objektdatentypen by-reference übergeben".
--RokerHRO 20:13, 5. Jan. 2011 (CET)Beantworten
In Java macht die Bezeichnung „by value“ gar nicht so viel Sinn, weil nicht-primitive Datentypen überhaupt keine Wertesemantik besitzen können. --Chricho ¹ 18:06, 9. Jun. 2011 (CEST)Beantworten
Per se besitzen nicht-primitive Datentypen (z.B. eine Komplexe Zahl, ein einfaches geometrisches Objekt wie ein Punkt od. Ä., das einfach aus 2…4 Zahlen besteht) schon eine Wertsemantik und können "by value", sprich: als Kopie, übergeben werden. In C und C++ (und sicher noch vielen anderen Programmiersprachen) geht das auch. Aber in Java geht das halt nicht. --RokerHRO 21:10, 9. Jun. 2011 (CEST)Beantworten
"Immutable" ist das Zauberwort: Wenn eine Klasse immutable ist, ist eine Zeigerkopie semantisch gleichwertig zu einer tieferen Kopie, und effizienter, wenn die Objekte groß genug sind... Insofern kann man durchaus Wertsemantik verwenden, wenn man das will.
Und zum Artikel und "Sonderfall Java", und ob das hier reingehört: in Java fehlt überhaupt das primitive Konzept "Referenz auf Variable" und verwandte. Das ist der Knackpunkt, wo sich Java am deutlichsten von C++ oder auch C# (!) unterscheidet. --Daniel5Ko 21:55, 9. Jun. 2011 (CEST)Beantworten
Aber nicht von Ruby o.ä. (PHP auch, nur bei ein paar wenigen Typen kann mans sich aussuchen) Das mit immutable Klassen macht Java nicht gerade schöner (inkonsistent zu integrierten Datentypen, und effizienter ist das nicht, man verzichtet ja etwa in C++ auch auf ständiges Kopieren), aber ja, das macht Sinn… --Chricho ¹ 22:02, 9. Jun. 2011 (CEST)Beantworten
Ja, irgendwie scheint das wirklich das mehr oder weniger entscheidende zu sein: Ein Referenzparameter ist ein Referenzparameter gdw. man beim Aufruf an seiner Stelle einen beliebigen (typmäßig passenden) L-value angeben kann. Java hat dann beispielsweise soetwas nicht. Hmm... --Daniel5Ko 22:42, 9. Jun. 2011 (CEST) Das passt zumindest einigermaßen auf alles, was mir grad so einfällt, wo man Referenzparameter explizit als solche markiert: C++/C#/PascalBeantworten

Kurz: Eigentlich müsste man die Abschnitte "Simulation von Referenzparametern durch Zeiger" und "Sonderfall Java" wegen Sachfremdheit löschen und "Verwendende Programmiersprachen" zumindest um Java kürzen. Die Inhalte der Argumente können natürlich möglicherweise als Referenzen interpretiert werden - das hat dann aber nichts mehr mit der Eigenschaft, Referenzparameter zu sein, zu tun. --Daniel5Ko 23:27, 9. Jun. 2011 (CEST)Beantworten

Simulation von Referenzparametern durch Zeiger

Bearbeiten

Dieser Abschnitt ist meiner Meinung nach ebenfalls problematisch. Man kann call-by-reference auch simulieren, indem man eine Klasse schreibt:

class Container {
  public Object o;
}

Das kann man in so gut wieder jeder verbreiteten imperativen Sprache machen, die Objekte kennt. Ich finde der Code in dem Abschnitt gehört eher in die Kategorie "Beispiele, die Call-by-Reference näher erläutern."

Wenn keiner Einspruch erhebt, werde ich das demnächst in Angriff nehmen. --hasta luego 18:10, 5. Jan. 2011 (CET)Beantworten

„Sonderfall“ Java

Bearbeiten

Das ist ja wohl lange nicht die einzige Programmiersprache, in der das so ist, Ruby, PHP, C#, D… --Chricho ¹ 18:06, 9. Jun. 2011 (CEST)Beantworten

Siehe Diskussion „Java ist call by value“. --Chricho ¹ 22:05, 11. Jun. 2011 (CEST)Beantworten
Ich füge noch Delphi hinzu. Alles, was instanziiert werden muss, funktioniert so, weil nur ein Pointer übergeben wird. Man hätte Java-Entwicklern echt sagen sollen, dass es Pointer gibt. --Яedeemer 13:49, 1. Aug. 2014 (CEST)Beantworten

Beispiele unverständlich

Bearbeiten

Die Beispiele im Text sind schwer verständlich. Im Gegensatz zu Wertparameter#Beispiel sind sie unnötig kompliziert und im Artikel fehlt die Ausgabe.

Ist die Benutzerabfrage beim Pascal Beispiel wirklich nötig? Zeilennummern wären hilfreich, wenn man sich darauf bezieht. Würde mich freuen wenn es jemand ergänzen können, der das Thema besser verstanden hat. Vielen Dank.--Flegmon (Diskussion) 15:47, 21. Mai 2013 (CEST)Beantworten