[C++]Funktionen (call by value, call by reference)

mosquito87

Lieutenant
Registriert
Aug. 2006
Beiträge
980
Hi Forumbasae,

ich habe ein paar Fragen zu Funktionen in C++.
Und zwar geht es um die Unterscheidung von "call by value" und "call by reference".

Soweit ich weiß, werden bei der "call by value" Methode die Daten, die aus dem Hauptprogramm an die Funktion übergeben werden, kopiert, d. h. sie sind im Prinzip 2x da.

Bei "call by reference" ist das nicht der Fall, ein "Zeiger" weist dann quasi auf die anderen Daten.

Ist das bisher vom Verständnis her so richtig?

Dann noch eine Frage:

Wenn ich eine Funktion so aufrufe, dann benutze ich die call by value Methode, oder? Wie benutze ich die "call by reference" Methodik?

PHP:
int berechnung(string name,float zahl)
{
//Inhalt der Funktion ...
}

Danke im Voraus für eure Hilfe.
Michael
 
Ja, das ist soweit richtig. Call By Reference ginge dann so:

PHP:
int berechnung(string &name,float &zahl)
{
//Inhalt der Funktion ...
}

Man beachte & in der Signatur. In der Funktion kannst Du "name" und "zahl" ohne besondere Notation verwenden.
 
el guapo schrieb:
Ja, das ist soweit richtig. Call By Reference ginge dann so:

PHP:
int berechnung(string &name,float &zahl)
{
//Inhalt der Funktion ...
}

Man beachte & in der Signatur. In der Funktion kannst Du "name" und "zahl" ohne besondere Notation verwenden.

Das ist vollkommen falsch! In der Signatur muss statt nem & ein * stehen. Beim aufruf kann man dann das & benutzen um statt der Variable selbst den Zeiger auf sie zu übergeben.
 
ich3k schrieb:
Das ist vollkommen falsch! In der Signatur muss statt nem & ein * stehen. Beim aufruf kann man dann das & benutzen um statt der Variable selbst den Zeiger auf sie zu übergeben.

DAS ist jetzt mal völlig falsch.

Semantisch ganz pedantisch betrachtet ist nur & call by reference, da bei * der Zeiger by value übergeben wird, auch wenn es indirekt by reference ist.
 
7H3 N4C3R schrieb:
DAS ist jetzt mal völlig falsch.

Semantisch ganz pedantisch betrachtet ist nur & call by reference, da bei * der Zeiger by value übergeben wird, auch wenn es indirekt by reference ist.

Ok muss mich entschuldigen, hab nicht richtig gesehen das es hier um C++ geht. Da ich so gut wie nur Hardware nah programmiere benutze ich C und da geht das mit dem & defintiv nicht, sondern nur mit *. Wobei sich mir dann natürlich die interessante Frage stellt, warum das so ist. Ist mir grad erst bewusst geworden der unterschied.
 
Da fängt das Problem mit den Zeiger-Konzept an :D

Also: C und damit auch C++ benutzt normalerweise "call by value". Es wird also das zu manipulierende Objekt kopiert und mit der lokalen Kopie gearbeitet. Das bringt natürlich seine Probleme mit großen Daten. Du kannst aber auch "by reference" (geht glaube ich nur in Verbindung mit C++) aufrufen. Dabei wird die Adresse (per &...) übergeben und dort direkt manipuliert. Für den Einstieg vielleicht wiki. Oder man benutze einfach eine Suchmaschine mit "call by reference" ;)

@ich3k
Warum das mit "&" in C nicht geht, sollte daran liegen, dass das erst mit C++ implementiert wurde...
 
Götterwind schrieb:
Warum das mit "&" in C nicht geht, sollte daran liegen, dass das erst mit C++ implementiert wurde...

Ja gut, dass ist ja wohl ziemlich offensichtlich. Die eigentlich Frage ist doch aber, warum das so ist, dass die das & neu implementiert haben. Aber ich denke mal das es daran liegt, dass man mit nem einfachen Zeiger probleme bei Objekten bekommt.
 
ich3k schrieb:
Ja gut, dass ist ja wohl ziemlich offensichtlich. Die eigentlich Frage ist doch aber, warum das so ist, dass die das & neu implementiert haben. Aber ich denke mal das es daran liegt, dass man mit nem einfachen Zeiger probleme bei Objekten bekommt.

Meines Wissens ist der Hauptgrund dafür, dass das *-Konzept zu fehleranfällig ist. Der Programmierer ist ja gezwungen, in der Funktion immer weiter mit z. B. *irgendwas zu arbeiten. Bei Call by Value genügt nur das & in der Signatur und man arbeitet in der Funktion schön normal, wie es sich gehört. ;)
 
Yop, ich denke, dass es einfach aus Einfachheitsgründen in C++ implementiert wurde (C++ ist ja eigentlich im Großen und Ganzen nur eine Vereinfachung, bzw. Verobjektisierung), da könnte man sich dann auch fragen, wieso nicht gleich Klassen in C implementiert werden...
Der Vorteil bei Referenzen liegt zum Teil auch bei Rückgabewerten, dann lassen sich einige Sachen einfacher machen, zb:
Code:
int &func (int &i)
{
   return i;
}

int main ()
{
   int i=0;

   func(i)++;
}
Der Code ist nicht überprüft.
Aber des zeigt denke ich dass sich mit Referenzen nette Sachen anstellen lassen.

mfg DaDrivel

[EDIT]
Referenzen sind auch sehr wichtig, wenn man zb Operatoren überlädt, mit Pointern wäre das etwas undurchsichtig, denke ich
[/EDIT]
 
Zuletzt bearbeitet:
ich3k schrieb:
Die eigentlich Frage ist doch aber, warum das so ist, dass die das & neu implementiert haben.
Call by reference ist ja in erster Linie ein Konzept und keine konkrete Implementation. In C verwendet man Zeiger, aber das ist halt keine native Lösung. Diese bietet C++ mit Referenzen. Ein Vorteil ist z.B., dass eine Referenz _immer_ auf ein gültiges Objekt verweist. Ein Zeiger kann ja bekanntlich ein Nullzeiger sein, womit ein Dereferenzieren, was notwendig wird, wenn man auf den Wert hinter dem Zeiger zugreifen will, fatal wäre. Referenzen kennen dieses Problem nicht. Dafür können Referenzen z.B. nicht arithmetisch verarbeitet werden, so wie Zeiger das können. Zeiger und Referenzen sind daher nicht in ein und denselben Topf zu werfen.

Zudem macht es in C++ nur Sinn, Objekte komplexer Typen per Referenz zu übergeben, sofern das "Original" nicht verändert werden soll. Bei primitiven Typen ist das nicht notwendig. Und sofern ein Parameter übergeben als Referenz innerhalb der Funktion nicht verändert wird, sollte dieser als konstant deklariert werden. Bei call by value Parametern ist das eher weniger sinnvoll.
Code:
int berechnung(const string& name, float zahl)
 
Zuletzt bearbeitet:
Eine Referenz zeigt auch immer "ich erwarte ein gültiges Objekt". Bei Zeigern kann man immer einen Null-Zeiger übergeben. Mit Referenzen ist das nicht so einfach. Wenn da was schiefgeht, hat eigentlich immer der Aufrufer Schuld, während das bei Zeigern immer fraglich ist. Die Semantik ist eben einfach anders.

Oh und kaputte Referenzen gibt's auch immer wieder gern :) Dagegen ist kein Kraut gewachsen.

Bsp:
Code:
void f()
{
   A* a = new A;
   A& b = *a;
   delete a; // huch, b ist ungültig
}
 
Danke für eure Antworten.

Bei Call by Value können die Variablen in der Funktion ja einen völlig anderen Namen haben, als im Hauptprogramm (beim Funktionsaufruf).

Ich nehme an bei Call by reference müssen die Namen der Variablen dann aber den gleichen Namen haben, nur eben mit einem '&' vorne dran.

Stimmt das?

Noch etwas zum Datentyp, der am Anfang der Funktion steht:
Diesen brauche ich ja eigentlich nur, wenn ich am Ende der Funktion mit return etwas ans Hauptprogramm weiter geben möchte, richtig?
Wie ist das, wenn ich durch eine Funktion nur eine Ausgabe realisieren möchte?
Kann ich den Datentyp dann einfach weg lassen?

Danke für eure Antworten!
Michael
 
Zuletzt bearbeitet:
Eine Funktion, die nichts zurückgibt wird als void deklariert.
Code:
void f()
{
// ich mache nichts außer etwas auszugeben
}

Und nein die mit Call by reference übergebenen variablen müssen nicht den gleich namen haben. Ganz abgehen davon ist es glaube ich besser wenn sie DOCH den gleichen Namen haben. Dann kommst du nicht so leicht durcheinander...

PS: Ließ doch erstmal die Bücher durch, mit denen du lernst (das tust du doch oder?). Dann werden dir solche Fragen früher oder später beantwortet... :)
 
Zuletzt bearbeitet:
Zurück
Oben