2014-11-27 1 views
7

Soweit ich weiß, sind Referenzen nur ein anderer Name für eine Variable, während Zeiger ihre eigene Variable sind. Zeiger nehmen Platz ein. Leute sagen oft "benutzen Sie einen Hinweis oder Zeiger", aber sie sagen nicht, was besser ist. Wenn Referenzen keine eigene Erinnerung aufnehmen, gewinnen Referenzen in dieser Abteilung. Was ich nicht weiß ist, wenn der Compiler zwischen Referenzen und normalen Variablen unterscheidet. Wenn Sie Operationen für eine Referenz ausführen, kompiliert es den gleichen Code wie die normale Variable?Sind Referenzen oder Zeiger schneller?

+1

w.r.t. Leistung, wahrscheinlich nicht viel (führen Sie einige Messungen auf Ihrer Plattform überprüfen). Ich denke, es ist wichtiger, die Semantik, die Sie wollen, zu klären - beachten Sie, Zeiger können NULL sein, so kann argumentiert werden, sind optional. – Niall

+3

Referenzen sind Zeiger in der Verkleidung, die einzige Performance-Vorteil von einigen zusätzlichen Annahmen kommen kann der Compiler über sie machen können (sie rechtlich nicht neu eingesetzt werden kann, noch kann NULL sein). –

+0

Umgekehrt kann ein Benutzer zu viel Angst haben, den NULL-Zeiger zu übergeben, auch wenn der Zeigerparameter als optional definiert ist. –

Antwort

3

Intern Referenzen sind auch in Bezug auf den Zeiger umgesetzt. Also ist es schwierig zu sagen, welcher Zeiger/Referenz schneller ist.

Es ist eine Verwendung dieser beiden, die einen Unterschied macht.

Zum Beispiel möchten Sie durch Bezugnahme einen Parameter an die Funktion zu übergeben.

void func(int& a) case_1 
{ 
    //No need to check for NULL reference... 
} 
void func(int* a) case_2 
{ 
    //Need o check if pointer is not NULL 
} 

In case_2 haben Sie explizit zu überprüfen, ob Zeiger vor dereferncing es nicht NULL ist, während das mit Referenzen nicht der Fall ist, weil Verweise auf etwas initialisiert werden.

Annahme ist, dass man ähnliches Spiel in zivilisierter Art und Weise, dh

Sie sind nicht etwas zu tun, spielen: -

int*p = NULL; 
int &a = *p; 
+0

Der erste Teil ist absolut richtig. In der Praxis sind jedoch viele NULL-Prüfungen nicht erforderlich. Dokumentieren Sie einfach im Funktionskommentar, dass Sie einen Nicht-NULL-Zeiger erwarten, und lassen Sie die Nullseite das Programm zum Absturz bringen, wenn diese Voraussetzung nicht erfüllt ist. – cmaster

+0

In der Praxis erhalten Sie viele Segmentierungsfehler wegen schlechten Pointerzugriffs. – ravi

+1

In der Praxis Sie nur so viele segfaults wegen schlechten Referenz Zugang bekommen kann ... – cmaster

1

Es ist die gleiche, Referenzen sind nur eine Sprache Mechaniker, der ein Zeiger ist, dass kann nicht Null sein. Der Unterschied bleibt nur in der Kompilierungsphase, in der Sie eine Beschwerde erhalten, wenn Sie versuchen, etwas Illegales zu tun.

+0

Sie können in der Praxis NULL sein, obwohl der Sprachstandard bei der Erstellung einer NULL-Referenz ein nicht definiertes Verhalten aufruft. Der Effekt ist der gleiche wie bei einem NULL-Zeiger. Nur schwieriger zu debuggen, da viele Leute unter der Illusion arbeiten werden, dass Referenzen nicht NULL sein können und folglich nicht verstehen, was in ihrem Code passiert. – cmaster

+0

Sie können sein, aber der Code kann immer davon ausgehen, dass sie nicht sind. – mukunda

+0

Sie können dieselbe Annahme für einen Zeiger verwenden, mit den gleichen Konsequenzen. – cmaster

1

Hier sind meine zwei Testprogramme:

Referenz:

int i = 0; 
int& r = i; 
++r; 
int j = 0; 
++j; 

Zeiger:

int i = 0; 
int* r = &i; 
++(*r); 
int j = 0; 
++j; 

Mein Compiler die EXACT gleichen Assembler-Code für beide geschrieben.

movl $0, -16(%rbp) #, i 
leaq -16(%rbp), %rax #, tmp87 
movq %rax, -8(%rbp) # tmp87, r 
movq -8(%rbp), %rax # r, tmp88 
movl (%rax), %eax # *r_1, D.31036 
leal 1(%rax), %edx #, D.31036 
movq -8(%rbp), %rax # r, tmp89 
movl %edx, (%rax) # D.31036, *r_1 
movl $0, -12(%rbp) #, j 
addl $1, -12(%rbp) #, j 
movl $0, %eax #, D.31036 
+0

Können Sie die Baugruppe mit Optimierungsflags wie '-O3' oder '-O2' ausgeben und erneut vergleichen. –

+0

Besseres Dump mit '-Os', es liefert den lesbarsten Assembler Code. – cmaster

+0

Ich möchte das nicht tun, weil es den gesamten Code entfernt, was nicht hilfreich ist. – user4298783