Ein Array durch Referenz in C übergeben?

Wie kann ich ein Array von Strukturen durch Verweis in C übergeben?

Als Beispiel:

struct Coordinate { int X; int Y; }; SomeMethod(Coordinate *Coordinates[]){ //Do Something with the array } int main(){ Coordinate Coordinates[10]; SomeMethod(&Coordinates); } 

In C werden Arrays als pointers auf das erste Element übergeben. Sie sind das einzige Element, das nicht wirklich nach Wert übergeben wird (der pointers wird als Wert übergeben, aber das Array wird nicht kopiert). Dadurch kann die aufgerufene function den Inhalt ändern.

 void reset( int *array, int size) { memset(array,0,size * sizeof(*array)); } int main() { int array[10]; reset( array, 10 ); // sets all elements to 0 } 

Wenn Sie nun das Array selbst ändern möchten (Anzahl der Elemente …), können Sie es nicht mit Stack- oder globalen Arrays tun, sondern nur mit dynamisch zugewiesenem Speicher im Heap. Wenn Sie in diesem Fall den pointers ändern möchten, müssen Sie einen pointers darauf übergeben:

 void resize( int **p, int size ) { free( *p ); *p = malloc( size * sizeof(int) ); } int main() { int *p = malloc( 10 * sizeof(int) ); resize( &p, 20 ); } 

In der Fragebearbeitung fragen Sie gezielt nach einem Array von Strukturen. Sie haben zwei Lösungen: Deklarieren Sie einen typedef, oder machen Sie explizit, dass Sie eine Struktur übergeben:

 struct Coordinate { int x; int y; }; void f( struct Coordinate coordinates[], int size ); typedef struct Coordinate Coordinate; // generate a type alias 'Coordinate' that is equivalent to struct Coordinate void g( Coordinate coordinates[], int size ); // uses typedef'ed Coordinate 

Sie können den Typ eingeben, wie Sie es deklarieren (und es ist ein allgemeines Idiom in C):

 typedef struct Coordinate { int x; int y; } Coordinate; 

Um ein wenig auf einige der Antworten hier zu erweitern …

Wenn in C ein Array-Bezeichner in einem anderen Kontext als als ein Operand für & oder die Größe von erscheint, wird der Typ des Bezeichners implizit von “N-Element-Array von T” in “pointers zu T” konvertiert, und sein Wert ist wird implizit auf die Adresse des ersten Elements im Array gesetzt (das ist die Adresse des Arrays selbst). Wenn Sie den Array-Bezeichner als Argument an eine function übergeben, empfängt die function daher einen pointers auf den Basistyp und nicht auf ein Array. Da Sie nicht erkennen können, wie groß ein Array ist, indem Sie nur den pointers auf das erste Element betrachten, müssen Sie die Größe als separaten Parameter übergeben.

 struct Coordinate { int x; int y; }; void SomeMethod(struct Coordinate *coordinates, size_t numCoordinates) { ... coordinates[i].x = ...; coordinates[i].y = ...; ... } int main (void) { struct Coordinate coordinates[10]; ... SomeMethod (coordinates, sizeof coordinates / sizeof *coordinates); ... } 

Es gibt verschiedene Möglichkeiten, Arrays an functionen zu übergeben.

Es gibt so etwas wie einen pointers auf ein Array von T im Gegensatz zu einem pointers auf T. Sie würden einen solchen pointers als deklarieren

 T (*p)[N]; 

In diesem Fall ist p ein pointers auf ein N-Element-Feld von T (im Gegensatz zu T * p [N], wobei p ein N-Element-Feld eines pointerss auf T ist). So könnten Sie einen pointers auf das Array im Gegensatz zu einem pointers auf das erste Element übergeben:

 struct Coordinate { int x; int y }; void SomeMethod(struct Coordinate (*coordinates)[10]) { ... (*coordinates)[i].x = ...; (*coordinates)[i].y = ...; ... } int main(void) { struct Coordinate coordinates[10]; ... SomeMethod(&coordinates); ... } 

Der Nachteil dieses Verfahrens besteht darin, dass die Array-Größe fest ist, da ein pointers auf ein 10-Element-Array von T ein anderer Typ als ein pointers auf ein 20-Element-Array von T ist.

Eine dritte Methode besteht darin, das Array in eine Struktur zu schreiben:

 struct Coordinate { int x; int y; }; struct CoordinateWrapper { struct Coordinate coordinates[10]; }; void SomeMethod(struct CoordinateWrapper wrapper) { ... wrapper.coordinates[i].x = ...; wrapper.coordinates[i].y = ...; ... } int main(void) { struct CoordinateWrapper wrapper; ... SomeMethod(wrapper); ... } 

Der Vorteil dieser Methode ist, dass Sie nicht mit pointersn herumspielen. Der Nachteil besteht darin, dass die Array-Größe fest ist (wiederum ist ein 10-Element-Array von T ein anderer Typ als ein 20-Element-Array von T).

Die C-Sprache unterstützt keine Weitergabe als Referenz irgendeiner Art. Die nächste Entsprechung besteht darin, einen pointers auf den Typ zu übergeben.

Hier ist ein künstliches Beispiel in beiden Sprachen

C ++ – API

 void UpdateValue(int& i) { i = 42; } 

C-Äquivalent

 void UpdateValue(int *i) { *i = 42; } 

Beachten Sie auch, dass Sie ein Array nicht innerhalb einer Methode erstellen können, wenn Sie es erstellen. Wenn Sie einen pointers darauf zurückgeben, würde es vom Stapel entfernt werden, wenn die function zurückkehrt. Sie müssen dem Heap Speicher zuweisen und einen pointers darauf zurückgeben. z.B.

 //this is bad char* getname() { char name[100]; return name; } //this is better char* getname() { char *name = malloc(100); return name; //remember to free(name) } 

In Plain C können Sie eine Pointer / Size-Kombination in Ihrer API verwenden.

 void doSomething(MyStruct* mystruct, size_t numElements) { for (size_t i = 0; i < numElements; ++i) { MyStruct current = mystruct[i]; handleElement(current); } } 

Die Verwendung von pointersn ist dem in C verfügbaren Call-by-Reference am nächsten.

Arrays werden standardmäßig per Referenz übergeben. Tatsächlich wird der Wert des pointerss an das erste Element übergeben. Daher kann die function oder Methode, die dies empfängt, die Werte im Array ändern.

 void SomeMethod(Coordinate Coordinates[]){Coordinates[0].x++;}; int main(){ Coordinate tenCoordinates[10]; tenCoordinates[0].x=0; SomeMethod(tenCoordinates[]); SomeMethod(&tenCoordinates[0]); if(0==tenCoordinates[0].x - 2;){ exit(0); } exit(-1); } 

Die beiden Aufrufe sind gleichwertig und der Exit-Wert sollte 0 sein;

Hey Leute, hier ist ein einfaches Testprogramm, das zeigt, wie man ein Array unter Verwendung von New oder Malloc zuordnen und übergeben kann. Einfach ausschneiden, einfügen und ausführen. Habe Spaß!

 struct Coordinate { int x,y; }; void resize( int **p, int size ) { free( *p ); *p = (int*) malloc( size * sizeof(int) ); } void resizeCoord( struct Coordinate **p, int size ) { free( *p ); *p = (Coordinate*) malloc( size * sizeof(Coordinate) ); } void resizeCoordWithNew( struct Coordinate **p, int size ) { delete [] *p; *p = (struct Coordinate*) new struct Coordinate[size]; } void SomeMethod(Coordinate Coordinates[]) { Coordinates[0].x++; Coordinates[0].y = 6; } void SomeOtherMethod(Coordinate Coordinates[], int size) { for (int i=0; i