2014-08-29 15 views
6

Ich war ein (C++) Code, wo Arrays übergeben werden, mitWarum Array als "int * & name" übergeben?

void fun(int *& name){...} 

gegeben, aber was ist die Idee dahinter? Ich denke, es bedeutet "ein Array von Referenzen", aber wenn Sie nur einen Zeiger auf das erste Element übergeben, wäre das in Ordnung, nicht wahr? Was ist die Motivation dafür?

+3

Es bedeutet Verweis auf eine Zeigervariable. Der Zweck besteht darin, die übergebene Zeigervariable zu ändern. –

+3

Arrays? Es ist nicht möglich, tatsächliche Array-Objekte durch einen solchen Parameter zu übergeben. Was Sie übergeben können, ist ein * Zeiger *, der auf ein Array-Element zeigt, aber nicht auf das Array selbst. Zum Beispiel können Sie ein 'int a [10] '- Array nicht direkt an diese Funktion übergeben. – AnT

+0

Es ist wichtig zu wissen, dass ** Arrays keine Zeiger sind und Zeiger nicht Arrays ** sind. Sehen Sie [** diesen Beitrag **] (http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) für mehr dazu. – juanchopanza

Antwort

5

Die Funktion empfängt einen Verweis auf einen Zeiger. Dies bedeutet, dass die Funktion nicht nur die int ändern kann, auf die name zeigt, sondern auch, dass Änderungen am Zeiger selbst innerhalb des Funktionsaufrufs auch außerhalb sichtbar sind.

Beispiel:

#include <iostream> 

int* allocate() 
{ 
    return new int(); 
} 

void destroy(int*& ptr) 
{ 
    delete ptr; 
    ptr = NULL; 
} 

int 
main(int argc, char *argv[]) 
{ 
    int* foo = allocate(); 

    std::cout << foo << std::endl; 

    destroy(foo); 

    std::cout << foo << std::endl; 

    return 0; 
} 

Ausgang ist:

0x82dc008 
0 
1

Es bedeutet, dass die Funktion den Wert des Zeigers in dem Anrufer ändern kann.

d.h.

myName* foo; /* ToDo - initialise foo in some way*/ 
fun(foo); 
/* foo might now point to something else*/ 

Ich halte das als Anti-Muster. Der Grund dafür ist, dass Leute, die Ihren Code lesen, nicht erwarten, dassfoo so geändert wird, da die aufrufende Syntax nicht von der normaleren Funktion void anotherFun(int * name){...} zu unterscheiden ist.

Die Stabilität eines solchen Codes kann leiden. Daher würde ich Ihnen empfehlen, void fun(int ** name){...} zu verwenden. Die aufrufende Syntax wird dann fun(&foo), was dem Funktionsbenutzer anzeigt, dass foo möglicherweise geändert wird.

+1

Ich würde sagen, es ist ein Anti-Pattern, einen Zeiger zu verwenden, wenn Sie eine Referenz verwenden können. Aber ich würde auch etwas anderes machen: 'int * fun (int * name);', und den neuen Wert zurückgeben. – juanchopanza

+0

Nun, ich persönlich mag den Zeiger auf Pointer-Syntax nicht, wo es nicht wirklich benötigt wird. Es kommt also auf persönliche Vorlieben an. Ich stimme jedoch zu, dass es für den Aufrufer im Allgemeinen unerwartet sein kann, dass der Zeiger geändert werden kann. Eine Alternative zur Verwendung von "int **", wie Sie vorschlagen, ist eine übersichtliche und gut dokumentierte API mit gut gewählten Namen für die Funktionen, z. 'deleteAndSetNull (int * & ptr)' für eine Funktion, die einen Zeiger löscht und auf NULL setzt. – oxygene

+0

Es ist lustig, wie trennscharf das ist: Ich respektiere offensichtlich deine Meinung und mag den Vorschlag, 'int * fun (int * name)' zu verwenden. Ich mag keine Referenzen, die in der Art verwendet werden, wie das OP es hat, da sie Code schwer lesbar machen und Bugs von Junioren eingeführt werden können, die an kollaborativen Projekten arbeiten. Benutzen Sie zumindest eine 'const &' wenn möglich. – Bathsheba

Verwandte Themen