Eine Referenz ist ein Aliasname für eine bereits existierende Variable. Eine Referenz existiert also nicht allein. Sie ist immer an eine Variable gebunden. Ändert man eine Referenz, so ändert man dadurch die Variable die durch die Referenz referenziert wird. Eine Referenz muss bei ihrer Erzeugung an eine Variable gebunden werden. Einmal gebunden, kann eine Referenz nicht mehr von der Variable die sie referenziert gelöst werden. Um das nochmal zu betonen: Steht eine Referenz auf der linken Seite einer Zuweisung, so wird nicht die Referenz selbst sondern die Variable die sie referenziert geändert! Eine Referenz muss schon bei der Deklaration an eine Variable gebunden werden.
#include<iostream>
using namespace std;
int main()
{
int a;
int& ref=a; //int& ist eine Referenz auf einen int
//waehrend type& eine Referenz auf 'type' waere
//eine referenz muss IMMER auf etwas 'zeigen'
a=4;
cout<<"ref = "<<ref<<"\n";
ref=2;
cout<<"a = "<<a<<"\n";
}Aber Referenzen kann man für andere Sachen verwenden. zB bei Funktionsparametern: bisher haben wir immer ein "call by value" gehabt, die Parameter wurden kopiert. Mit Referenzen gibt es dann ein "call by reference". Was ist der Unterschied? Die Parameter sind keine Kopien mehr, sondern alias Namen für diese. dh wenn wir in der Funktion diese Variablen ändern, ändern sie auch in der aufrufenden Funktion ihren Wert.
#include<iostream>
using namespace std;
void tausche(int&, int&); //wie gehabt int& ist eine referenz
int main()
{
int a=2;
int b=5;
cout<<"a = "<<a<<"\nb = "<<b<<"\n";
tausche(a,b);
cout<<"a = "<<a<<"\nb = "<<b<<"\n";
}
void tausche(int& a, int& b)
{
int temp=a;
a=b;
b=temp;
}Das, was wir in tausche() machen, nennt sich Dreieckstausch. Dieser Tausch wird oft verwendet, wenn man 2 Werte austauschen will. Allerdings sollte man dafür lieber die C++ Funktion swap() verwenden.
Auch bei Referenzen gibt es const. Wenn wir uns einmal folgendes ansehen:
#include <iostream>
using namespace std;
void addiere(int&,int&,int&);
int main()
{
int erg;
addiere(1,2,erg);
cout<<erg<<"\n";
}
void addiere(int& a, int& b, int& ergebnis)
{
ergebnis=a+b;
}Wir bekommen einen Compilerfehler in der Art "Konnte const int nicht in int& konvertieren". Nun ja, er hat recht. 1 ist eine konstante Zahl und wenn wir 1 by reference übergeben, dann haben wir theoretisch die Möglichkeit 1 zu ändern, was aber nicht möglich ist (1 ist nunmal immer 1 und kann nicht in 2 geändert werden). Somit kommt const& ins Spiel. Eine konstante Referenz kann man nicht verändern.
#include <iostream>
using namespace std;
void addiere(int const&,int const&,int&);
int main()
{
int erg;
addiere(1,2,erg);
cout<<erg<<"\n";
}
void addiere(int const& a, int const& b, int& ergebnis)
{
ergebnis=a+b;
}Wie bei const int und int const kann man bei Referenzen auch das int und const tauschen. int const& ist äquivalent zu const int&. Allerdings tritt hier die "von rechts nach links lesen" Regel in Kraft: int const& ref liest sich wie "ref ist eine referenz, welche const ist, auf int".
Wo liegt dann aber der Sinn von konstanten Referenzen bei Funktionsaufrufen (im Vergleich zu "call by value")? Ganz einfach: bei einer Referenz wir keine Kopie der originalen Variablen erstellt. Das hat vorallem dann Sinn, wenn wir mit Variablen hantieren, die viele Daten beinhalten. Momentan können wir const type& ganz getrost links liegen lassen, denn int, char, float,... sind sehr klein, so dass das kopieren der Werte sehr schnell ist.
Bei Referenzen gibt es eine kleine Falle:
#include <iostream>
using namespace std;
int& foo();
int main()
{
int& i=foo();
cout<<i<<"\n";
}
int& foo()
{
int lokal=7;
return lokal;
}Wir wissen, dass lokal nach dem return zu existieren aufhört. Folglich referenziert i eine tote Variable. Dies führt zu undefinierten Verhalten. Also Merksatz: "Returne nie eine Referenz auf eine lokale Variable".
Deine Aufgabe ist es, eine Funktion divide() zu schreiben. Diese Funktion soll 2 Zahlen dividieren und Ergebnis und Rest dem Aufrufer mitteilen.