Anfänger: Unterschied Zeiger - Referenz
-
Hi Leute,
was ist eigentlich der Unterschied zwischen Zeigern und Referenzen? Wann benutzt man was?
-
Referenzen sind möglichst immer Zeiger vorzuziehen (hope so?!) - es sei denn es geht nicht anders, dies ist in manchen Fällen so:
- Du die Adresse auch vom Zeiger benötigst [Die Adresse einer Referenz kannst du nicht herausfinden]
- Du dynamisch Speicher allokierst (new/delete) [Da du einen Zeiger zurückbekommst]
- Du den Zeiger auch auf 0 setzen willst [Da Referenzen nie 0 sein können]
- Der Zeiger zu Beginn noch nicht initialisiert werden soll bzw. der Zeiger während seines Lebens verändert werden soll [Da Referenzen immer auf etwas "zeigen" müssen]MfG SideWinder
-
-
Scripta schrieb:
Hi Leute,
was ist eigentlich der Unterschied zwischen Zeigern und Referenzen? Wann benutzt man was?referenzen sind verkappte zeiger. sie schreiben sich den stern ('*') einfach immer von selber hin, wenn man ne referenz benutzt.
daher muss auch gefordert werden, daß man sie beim anlegen gleich initialisiert. späteres zuweisen kann ja nicht mehr gehen, weil man imer nur den gereferenzierten verändern würde, der stern ist ja automatisch da.naja, eigentlich steht im standard nix davon, daß referenzen zeiger sind. aber nur, um den compilerbauern noch mehr freiheiten zu lassen, zum beispiel gleiche einträge in der symboltabelle statt zeiger oder ähnliches, aber mir scheint, die ganzen details fliegen auch von alleine weg, wenn man sich nen optimierenden compiler vorstellt.
referenzen können nicht auf 0 zeigen. also
int i; int* pi=&i; int& ri=*pi;//ok
und
int* pi=0; int& ri=*pi;//verboten
normale compiler schlücken das zwar, aber verboten isses trotzdem.
hier greift ein grund für referenzen: der compiler weiß mehr details. daher kann er besser optimieren. ist aber eigentlich um, weil compiler schon recht viel von alleine rausfinden und weil jeder wie er lust hat, __assume__(p!=0) und ähnliches in seinen code einischreiben darf. der grund ist eher irrelevant und mikrooptimierung. bei der gcc kann man afair dem funktionsparameter ne zusatzdeklaration geben, die sagt, daß er ein nicht-null-zeiger ist. betrifft das testen, ob ein nullzugriff passieren wird (der compiler testet eh nur max. einmal pro funktion, beim ersten zugriff, mit zuatz-deklaration halt gar nicht).
der andere grund ist: refs dürfen nicht auf 0 zeigen, daher verwenden viele deppen sie, um das im prototyp anzugeben. also
int strlen(char& str);//*str!=0
und
int strlen(char* str);//str könnte auch 0 sein
nachteile liegen auf der hand:
- man muß immer überlegen, ob gerade 0 erlaubt ist, oder nicht und daher ref- oder zeiger-version aufrufen. dabei ist der funktion NICHT anzusehen, ob sie 0 erlaubt, weil geneu jene deppen auch dauernd sachen wieint strlen(char* str){//str könnte auch 0 sein if(str==0) return 0; ... }
schreiben. also tests ohne jede inhaltliche berechtigung.
-das debuggen wird um größenordnungen schwieriger. und da mal die zehnfachen kosten im vergleich zum reinen codieren beim debuggen liegen, ist doch das ein wichtiger punkt. stell dir vor, mit dem debugger oder testausgaben fand ich heraus, daß an der markiertren stelle x einen falschen wert hat.
{ int x=y;/hier noch guter wert f(x); cout<<x<<endl; x=p; g(x); p=x; h(&x); }
und stelle dir weiter vor, du hättest keinen programmierstil.
{ int x=y;/hier noch guter wert f(x);//kann x verändert haben cout<<x<<endl;//kann x verändert haben x=p;//kann x verändert haben g(x);//kann x verändert haben p=x; h(&x);//kann x verändert haben }
und jetzt mit ein wenig stil. einfach nur: meide refs, außer es sind const refs.
{ int x=y;/hier noch guter wert f(x); cout<<x<<endl; x=p;//kann x verändert haben g(x); p=x; h(&x);//kann x verändert haben }
-
volkard schrieb:
Scripta schrieb:
Hi Leute,
was ist eigentlich der Unterschied zwischen Zeigern und Referenzen? Wann benutzt man was?referenzen sind verkappte zeiger.
Das halte ich für eine falsche Sichtweise. Ich sehe das eher so wie Stephen Dewhurst: References Are Aliases, Not Pointers