4 Funktionen mit bzw. ohne Referenz
-
Grundsätzlich kann eine Referenz auch ins Nichts zeigen, z.B.:
int& f() { int bla = rand(); return bla; }Der Compiler erzwing allerdings, dass die Refernz mit etwas gültigem initalisiert wird und man muss (kann) auch nicht auf NULL prüfen.
-
Ich hab mir nun diesen kurzen Code geschrieben. Ich möchte nun das ganze mit Referenzen lösen. Ich hab schon versucht die Pointer-Sternchen gegen den &-Operator in der Parameterliste der Funktion auszutauschen, aber da meckert der Compiler dann... Geht das hier dann überhaupt?
#include<iostream> using namespace std; void addiere(int *a, int *b, int *c) { for(int i=0; i<5; i++) { c[i] = a[i] + b[i]; } } int main() { int a[5], b[5], c[5]; for(int i=0; i<5; i++) { a[i] = 1; b[i] = 1; c[i] = 0; } addiere(a, b, c); for(int i=0; i<5; i++) { cout << c[i]; } }
-
Man sollte nie ein lokales Objekt als Referenz zurückgeben.
-
EOutOfResources schrieb:
Mann sollte nie ein lokales Objekt als Referenz zurückgeben.
Ich denke, dass war an Oberon gemeint, oder? Ich geb ja kein lokales Objekt per Referenz zurück...
-
vip@r schrieb:
[...] Geht das hier dann überhaupt? [...]
Hier liegen die Dinge etwas anders. Wenn du ein Array übergibst, so hast du einen Pointer auf das erste Element des Arrays. Um dann auf die darauffolgenden Elemente zuzugreifen, brauchst du Pointerarithmetik. Heisst also, du musst zur Anfangsadresse etwas hinzuzählen, damit du das nächste Element erreichen kannst.
Das hier dürfte eine etwas genauere Erklärung sein: http://www.cplusplus.com/doc/tutorial/arrays/
Grundsätzlich solltest du aber keine rohe Arrays brauchen, sondern std::vector.
-
Stimmt, du hast Recht. Der []-Operator eines Arrays ist ja quasi nix anderes als ein Pointer. Dass hier dann die Referenz ins Gras beißt is ja klar; hätt ich selber auch drauf kommen können...
-
vip@r schrieb:
Der []-Operator eines Arrays ist ja quasi nix anderes als ein Pointer.
Nein, der Indexoperator ist vielmehr eine Addition und Dereferenzierung eines Zeigers.
p[i] == *(p+i)
-
Einfaches Modell: Stell Dir eine Refrenez einfach als eine Umbenennung des selben Objekts vor:
void funktion(irgendein_typ & r) { } //... irgendein_typ obj; //neues objekt mit namen 'obj' funktion(obj); //'obj' heisst in 'funktion' 'r', aber beide sind das gleiche objekt unter verschiedenen namen... irgendein_typ & renamed = obj; //ab hier kannst du 'obj' auch unter dem namen 'renamed' ansprechen std::cout << std::booalpha << (&obj == &renamed) << std::endl; //true -> gleiche adressen weil gleiches objekt nur mit verschiedenen namen
-
vip@r schrieb:
Stimmt, du hast Recht. Der []-Operator eines Arrays ist ja quasi nix anderes als ein Pointer. Dass hier dann die Referenz ins Gras beißt is ja klar; hätt ich selber auch drauf kommen können...
Lustigerweise ist das nicht so, das lässt sich auch per Referenz lösen.
Angenommen dein Array sieht so aus:`
+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+
`
dann kann man folgendes machen:
void f( int& a ) { // weist dem nächsten integer im Speicher den Wert 5 zu. Dazu wird die // Adresse der Variable bestimmt, per Zeigerarithmetik die Adresse des // nächsten Integers bestimmt und diesem Integer per Dereferenzierung der // Wert 5 zugewiesen. int* VarAddress = &a; VarAddress = VarAddress +1; *VarAddress = 5; } int main() { int a[5] = { 0 }; f( a[1] ); // setzt a[2] auf 5 f( *a ); // setzt a[1] auf 5 }Eine Referenz ist ein Alias für eine Variable, egal ob sie benannt ist oder nicht. Sie ist in jeder Hinsicht identisch mit dem Original.
int a = 5; int ar[5] = {0}; int& RefA = a; // RefA und a sind dieselbe Variable int& RefAr = ar[2] // RefAr und a[2] sind dieselbe Variable
-
Ich möchte auf zwei Punkte eingehen:
& und Referenzen: Da ein C++-Programm mit einem begrenzten Satz an Zeichen geschrieben wird und keiner eine bessere Idee zur Deklaration von Referenzen hatte, wurde die Bedeutung von & abermals überladen. Je nach Kontext ist es entweder der unäre Adress-Operator, ein "Referenz-Deklarator", oder ein binäres Und.
Die Parameterübergabe an eine Funktion ist auch nur eine "Kopier-Initialisierung". Soll heißen:
void foo(int x1, int & y1); int main() { int z = 3; foo(z+1,z); int x2 = z+1; int & y2 = z; }...dass die Initialisierung von x1 beim Funktionsaufruf genau dieselbe ist wie die von x2. Dasselbe gilt für y1 und y2. Wenn du verstanden hast, was y2 ist, verstehst Du auch, was y1 ist -- eine Referenz auf ein int-Objekt. Das & ist hier jeweils Teil des Deklarators und macht aus y1 bzw y2 eine Referenz. Was eine Referenz ist, kann man auch in einem C++ Buch nachlesen...
Ich stelle mir eine Referenz immer als einen sich selbst dereferenzierenden Zeigers vor:
int z = 3; int z = 3; int &ref = z; int *ptr = &z; ref += 1; *ptr += 1; cout << z; cout << z;Links siehst Du & einmal als Teil des Deklarators. Er macht aus ref eine Referenz. Rechts siehst Du & als Adress-Operator. Er liefert die Adresse von z, mit der der Zeiger ptr initialisiert werden kann. Das erste Sternchen ist Teil des Deklarators, der aus ptr einen Zeiger macht. Das zweite Sternchen ist der Dereferenzierungs-Operator. Der ganze Ausdruck *ptr bezieht sich wieder auf das Objekt mit der Adresse, die in ptr gespeichert wird.
-
Ich denke, Referenzen sind als Aliase einfacher zu verstehen für einen Anfänger.
-
314159265358979 schrieb:
Ich denke, Referenzen sind als Aliase einfacher zu verstehen für einen Anfänger.
Wenn ich "Alias" lese, denke ich an Namen. Es gibt aber auch namenlose Referenzen. Diese werden von Funktionen zurück gegeben.
-
lalelula schrieb:
314159265358979 schrieb:
Ich denke, Referenzen sind als Aliase einfacher zu verstehen für einen Anfänger.
Wenn ich "Alias" lese, denke ich an Namen. Es gibt aber auch namenlose Referenzen. Diese werden von Funktionen zurück gegeben.
Diese Funktionen geben aber wieder nur einen Alias einer bestimmten internen Variable zurück.
-
Ich würde zumindest bei einer benannten Referenz sagen, dass der Name der Referenz ein Aliasname für ein bestimmtes Objekt ist. Ich weiß jetzt nicht, wie das jemanden weiterbringen soll. Ich komme mit dem "sich selbst dereferenzierender, konstanter Zeiger"-Gedankenmodell einer Referenz wunderbar klar.