Show
Forum: Compiler & IDEs Unterschied zwischen Zeiger und ReferenzHallo Leute, mir ist der Unterschied zwischen einem Zeiger und einer Referenz nicht so ganz klar. Ein Beispiel: (siehe hier: http://www.highprogrammer.com/alan/rants/mutable.html )
von Torsten Robitzki (Gast) 19.12.2014 12:55 Technisch sind beide gleich. Wenn ich anzeigen möchte, dass eine Referenz optional ist. Also entweder auf ein gültiges Objekt zeigt, oder aber auf nichts zeigt, dann verwendet man einen Zeiger ansonsten eine Referenz. Eine Referenz referenziert immer ein gültiges Objekt (wenn nicht, hat man undefiniertes Verhalten; also ein Fehler in der SW). Das ist auch der Grund, warum ich eine Referenz immer initialisieren muss, einen Zeiger aber nicht. Eine Referenz kann ich später auch nicht mehr ändern. Sprich die Identität des Objekt, auf das ich referenziere bleibt immer die selbe. Es gibt sicher noch ein paar Spezialfälle, wo es sinnvoller ist, einen Zeiger zu verwenden, der dann eben nicht 0 sein darf. Z.B. wenn man einer Funktion einen Puffer übergeben möchte. Dann verwendet man in der Regel einen Zeiger auf das erste Element eines Arrays und das sollte man auch weiter so beibehalten, weil es einfach idiomatisch ist. mfg Torsten von Kaj G. (Firma: RUB) (bloody) 23.12.2014 10:53 Ok, vielen dank fuer die Antwort. :) von Sebastian V. (sebi_s) 23.12.2014 23:06 Einige Sachen funktionieren aber nur mit References. Zum Beispiel kann man mit Pointern nur Arrays übergeben indem man auf das erste Element zeigt. Dabei geht die Größe des Arrays verloren (array to pointer decay). Mit References kann man tatsächlich eine Reference auf ein Array haben (wahlweise mit der Größe als Template Parameter). Ein Unterschied zwischen Pointer und Reference ist natürlich auch, dass man bei References kein & (Address Operator) vor die Parameter zu schreiben braucht. Das ist spätestens bei Operator Overloading praktisch. Ich glaube niemand wollte Code wie
von mem (Gast) 24.12.2014 07:58 Wie sieht dass denn im Speicher aus? Wieviel Speicher belegt ein pointer und wieviel eine Referenz? von Ralf G. (ralg) 24.12.2014 09:48 mem schrieb: > Wieviel Speicher belegt ein pointer und wieviel eine Referenz? Torsten Robitzki schrieb: > Technisch sind beide gleich. mem schrieb: > Wie sieht dass denn im Speicher aus? > Wieviel Speicher belegt ein pointer und wieviel eine Referenz? Offiziell (also laut ISO-Norm) ist eine Referenz selbst kein Objekt, sondern nur ein anderer Name für ein bereits bestehendes Objekt und belegt daher keinen eigenen Speicher. Deshalb kann man mit sizeof nicht die Größe einer Referenz ermitteln und auch nicht eine mit dem operator new dynamisch erzeugen. Auch die Adresse einer Referenz läßt sich nicht ermitteln. Um eine Referenz zu implementieren, wird aber je nach Anwendungsfall ein gewisser zusätzlicher Platz im Speicher benötigt. Unter der Haube werden Referenzen dann typischerweise genau wie Zeiger implementiert. Das ist dann aber ein Implementierungsdetail des Compilers. 24.12.2014 10:08: Bearbeitet durch User von mem (Gast) 24.12.2014 12:39 Aha, gut das ich gefragt habe. ;-) Rolf Magnus schrieb: > Offiziell (also laut ISO-Norm) ist eine Referenz selbst kein Objekt, > sondern nur ein anderer Name für ein bereits bestehendes Objekt und > belegt daher keinen eigenen Speicher. Deshalb kann man mit sizeof nicht > die Größe einer Referenz ermitteln und auch nicht eine mit dem operator > new dynamisch erzeugen. Zur Klarstellung: Man kann sehr wohl den Adressoperator auf eine Referenz anwenden und bekommt die Adresse des referenzierten Objekts, analog mit sizeof. Was du wohl meinst, ist daß man an eventuelle Hilfsdaten (heimlicher Zeiger o.ä.) nicht herankommt. von mem (Gast) 24.12.2014 14:07 Was erhalte ich vom Adressoperator bei einem pointer und was bei einer Referenz? mem schrieb: > Was erhalte ich vom Adressoperator bei einem pointer und was bei einer > Referenz?
24.12.2014 14:21: Bearbeitet durch User von mem (Gast) 24.12.2014 15:21 sizeof ist zwar nicht der Adressoperator, aber du hast die Lunte gerochen. ;-) Eine Referenz ist nur ein anderer Name. Und ein pointer ein eigener Datentyp. Für mich sind das zwei völlig verschiedene Dinge, auch wenn sie nach aussen gleich erscheinen. Ein array ist ja auch kein pointer. Aber das ist eine gaaannnzzz andere Sache. ;-) Frohes Fest! von Rufus Τ. F. (rufus) 24.12.2014 15:23 Karl Heinz schrieb: > VOn daher bin ich mit der Aussage, dass Referenzen und Pointer technisch > identisch sind eher unglücklich. Inhaltlich aber ist das nicht ganz falsch, wenn so etwas an eine Funktion übergeben wird. Aber auch nicht komplett synonym ...
24.12.2014 15:23: Bearbeitet durch User Rufus Τ. Firefly schrieb: > In C (das keine Referenzen kennt) kann man bei alleiniger > Betrachtung der Funktion "machwas" klar sehen, daß "i" als 0 > ausgegeben werden wird, da der Funktionsaufruf von "blafusel" die > Variable nicht verändern kann. Es sei denn, "blafusel" ist ein Makro oder i ist en Array. Das tolle an C ist, daß es bei allen Regeln Ausnahmen gibt. Generell ist es keine gute Idee, Funktionen aufzurufen, ohne zu wissen, was sie mit den Parametern machen, egal ob in C oder C++. Da gibt es noch viel mehr Stolperfallen, als eine den übergebnen Wert ändernde Funktion. Es ist halt nur anfangs ungewohnt, daß das in C++ mit Referenzen möglich ist. von Rufus Τ. F. (rufus) 25.12.2014 00:42 Rolf Magnus schrieb: > Es sei denn, "blafusel" ist ein Makro oder i ist en Array. Welchen Typ i hat, sieht man in diesem Fall, da es hier in der Nähe des Aufrufs von "blafusel" definiert wird. "blafusel" sollte kein Makro sein, sofern der Programmierer sich an die Konventionen gehalten hat -- Makronamen werden in VERSALIEN geschrieben. Allerdings ist das bei fremden Quelltexten keine Annahme, von der man unbedingt ausgehen kann. Insofern hast Du natürlich recht. von Hans (Gast) 25.12.2014 11:50 In manchen Coderichtlinien (u.a. Google C++ Style Guide) wird deshalb empfohlen, Parameter an Funktionen nur per Value, per Const-Referenz oder per (Non-Const-)Zeiger zu übergeben. Wenn man sich daran hält, ist beim Aufruf auf einen Blick ersichtlich, was als Ein- und Ausgabeparameter gedacht ist. Ich nutzte außerdem Zeiger statt Referenzen, wenn sich die Funktion die Adresse über den Funktionsaufruf hinweg merkt. Pass-by-Const-Reference ist dann einfach eine effizientere Form von Pass-by-Value, die sich aber semantisch und syntaktisch gleich verhält. von Willi Wampe (Gast) 25.12.2014 14:46 > Pass-by-Const-Reference ist dann einfach eine effizientere Form von > Pass-by-Value Aber auch nur bei größeren Objekten ("größer" ist hier natürlich relativ und von der Umgebung abhängig). Ich habe schon "const long&" u.ä. als Parameter gesehen ... > die sich aber semantisch und syntaktisch gleich verhält. void hmmm(int x) { x = 42; } void hmmm(const int& x) { const_cast<int&>(x) = 42; } Willi Wampe schrieb: >> die sich aber semantisch und syntaktisch gleich verhält. > > void hmmm(int x) > { > x = 42; > } > > void hmmm(const int& x) > { > const_cast<int&>(x) = 42; > } Und was willst du damit sagen, außer daß const_cast immer im Zusammenhang mit einem Programmierfehler auftaucht? von Torsten Robitzki (Gast) 28.12.2014 17:05 Hans schrieb: > In manchen Coderichtlinien (u.a. Google C++ Style Guide) wird > deshalb > empfohlen, Parameter an Funktionen nur per Value, per Const-Referenz > oder per (Non-Const-)Zeiger zu übergeben. > > Wenn man sich daran hält, ist beim Aufruf auf einen Blick ersichtlich, > was als Ein- und Ausgabeparameter gedacht ist. In komplexeren Beispielen ist dies aber meist schon sehr schnell nicht mehr anwendbar:
von N.R. (Gast) 03.01.2015 21:58 N'abend, browse gerade durch die Threads und kann mich nicht zurück halten... 1. Cool bei Referenzen ist die Funktionsübergabe von fixed sized arrays (compile time checked) also etwas wie "int (&array)[100]". Das geht nicht in C. ... 2. Schön bei Referenzen als Parameter ist der implizite Ausschlus von NULL Pointern (wenn man nicht gerade castet)... 3. Const References als Funktionsparameter sind ok (im Sinn von Punkt 2)... 4. Non-Const References als Funktionsparameter oder Rückgabewerte sind verwirrend, wenn man nur die Caller-Side sieht: Soll heißen, man sieht nicht ob das ein Value oder eine "Reference" ist und weiß somit nicht ob bei Modifikationen das Urpsungsobjekt oder eine Kopie verändert wird... (ich habe eine Zeitlang statt dessen Pointer benutzt, ist aber auch keine optimale Lösung)... 5. Eine Reference als Object Variable ist interessant... (don't do it unless you know what you do). Grüße btw: Ich mag Karl Heinz' Beiträge! von Yalu X. (yalu) (Moderator) 04.01.2015 12:24 Sebastian V. O. schrieb: > Einige Sachen funktionieren aber nur mit References. Zum Beispiel kann > man mit Pointern nur Arrays übergeben indem man auf das erste Element > zeigt. Dabei geht die Größe des Arrays verloren (array to pointer > decay). Mit References kann man tatsächlich eine Reference auf ein Array > haben N.R. schrieb: > 1. Cool bei Referenzen ist die Funktionsübergabe von fixed sized arrays > (compile time checked) also etwas wie "int (&array)[100]". Das geht > nicht in C. ... Man kann doch in C auch einen Zeiger auf ein Array übergeben (nicht nur einen auf dessen erstes Element). Man muss diesen Zeiger halt an den Stellen, wo man das Array benutzen möchte, mit dem *-Operator dereferenzieren. Das ist aber immer so, wenn man C++Referenzen durch Zeiger nachbildet. Eine Referenz in C++ ist im Wesentlichen ein selbstdereferenzierender Zeiger mit ein paar durch diese automatische Dereferenzierung bedingten Einschränkungen (z.B. keine Zuweisung möglich, deswegen Initialisierung immer erforderlich). Man kann praktisch alles, was mit Referenzen möglich ist, mit gewöhnlichen Zeigern nachbilden, allerdings entsteht dabei etwas mehr Schreibarbeit, da man häufiger die *- und &-Operatoren bemühen muss. von Sebastian V. (sebi_s) 04.01.2015 12:56 Yalu X. schrieb: > Man kann doch in C auch einen Zeiger auf ein Array übergeben (nicht nur > einen auf dessen erstes Element). Stimmt, da hast du recht. Mir ist gerade aber noch eine andere Eigenheit von References in C++ eingefallen. Wenn man const References als Parameter von Funktionen hat, dann verhält es sich ziemlich genau wie wenn ich direkt den Wert übergeben hätte. Insbesondere ist auch sowas erlaubt:
04.01.2015 12:56: Bearbeitet durch User von Nase (Gast) 04.01.2015 15:20 Rufus Τ. Firefly schrieb: > Makronamen werden in VERSALIEN > geschrieben. Die intention ist schön, wird aber schon in der Standard-C-Bibliothek nicht eingehalten... N.R. schrieb: > Cool bei Referenzen ist die Funktionsübergabe von fixed sized arrays Cool ist auch, dass man in c++ einen vector verwenden kann. Der hat eine Größeninformation und braucht kaum mehr Speicher. Sebastian V. O. schrieb: > Bei einer normalen Reference wird > das temporäre Objekt in der Regel vorm Funktionsaufruf wieder zerstört. An eine normale Reference darfst du mit einem gescheiten Compiler garkeine temporären Werte übergeben. Da sollte wenigstens eine Warnung rausspringen. Eine Referenz ist ungefähr so viel Zeiger, wie ein Hardlink eine symbolische Verknüpfung ist... Antwort schreibenDie Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an. Wichtige Regeln - erst lesen, dann posten!
Formatierung (mehr Informationen...)
Wann benutzt man Pointer in C?Pointer ermöglichen es, das Funktionen ihre beim Aufruf übergebenen Variablen verändern können. dynamische Verwaltung von Speicherplatz, memory managment, funktioniert immer über Pointer. wenn man sein Programm optimieren will, Geschwindigkeit, Speicherbedarf sind Pointer immer sehr beliebt.
Für was braucht man Pointer?Damit du z.B. in einer Funktion ein ganzes Array beschreiben kannst und du nur ein Wert übergeben musst(Adresse des ersten Speicherplatzes). Oder um in einer Unterfunktion die Variable, die im main definiert ist, zu verändern. Pointer sind hilfreich, um globale Variablen zu vermeiden.
Was ist eine Referenz in C++?Referenzen sind interne Zeiger auf Variablen. Sie werden also genau so verwendet wie gewöhnliche Variablen, verweisen jedoch auf das Objekt, mit dem sie initialisiert wurden. Die Zeigerverwendung wird vor dem Programmierer verborgen.
|