Definieren Sie eine Funktion, die den Strukturzeiger zurückgibt

8

Bitte ertragen Sie mich, ich bin von anderer Sprache und Neuling zu c und lerne es von Ссылка

%Vor%

Ich verstehe, dass die zweite Person_create-Funktion einen Zeiger von struct Person zurückgibt. Ich verstehe nicht (ist vielleicht weil ich aus einer anderen Sprache, Erlang, Ruby), warum definiert es als

%Vor%

nicht

%Vor%

und gibt es eine andere Möglichkeit, eine Funktion zum Zurückgeben einer Struktur zu definieren?

Tut mir leid, wenn diese Frage zu einfach ist.

    
allenhwkim 04.05.2012, 15:50
quelle

5 Antworten

11

Es ist so definiert, weil es einen Zeiger auf eine Struktur und nicht auf eine Struktur zurückgibt. Sie weisen den Rückgabewert einem struct Person * zu, nicht einem struct Person .

Es ist möglich, eine vollständige Struktur wie folgt zurückzugeben:

%Vor%

Aber es wird nicht sehr oft verwendet.

    
MByD 04.05.2012 15:52
quelle
3

Die Funktion gibt who zurück, was ein struct Person * - ein Zeiger auf eine Struktur ist. Der Speicher, der die Struktur enthält, wird von malloc() zugewiesen, und die Funktion gibt einen Zeiger auf diesen Speicher zurück.

Wenn die Funktion deklariert wurde, um struct Person und nicht als Zeiger zurückzugeben, könnte who auch als Struktur deklariert werden. Bei der Rückkehr wird die Struktur kopiert und an den Aufrufer zurückgegeben. Beachten Sie, dass die Kopie weniger effizient ist als einfach einen Zeiger auf den Speicher zurückgeben.

    
Adam Liss 04.05.2012 15:52
quelle
2

Structs sind in C / C ++ standardmäßig keine Zeiger (oder Referenzen), wie sie zum Beispiel in Java sind. Struct Person Function () würde daher struct selbst (nach Wert, eine Kopie) keinen Zeiger zurückgeben.

Sie möchten oft keine Kopien von Objekten erstellen (standardmäßig flache Kopien oder Kopien, die mit Kopierkonstruktoren erstellt wurden), da dies bald ziemlich zeitaufwändig werden kann.

    
dbrank0 04.05.2012 15:52
quelle
2

Die Funktion Person_create gibt einen Zeiger auf ein struct Person zurück, so dass Sie den Rückgabewert als einen Zeiger definieren müssen (indem Sie das * hinzufügen). Um den Grund für das Zurückgeben eines Zeigers zu einer Struktur und nicht die Struktur selbst zu verstehen, muss man verstehen, wie C Speicher verarbeitet.

Wenn Sie eine Funktion in C aufrufen, fügen Sie einen Datensatz dafür in den Aufruf-Stack ein. Am unteren Rand des Aufruf-Stacks befindet sich die main -Funktion des Programms, das Sie ausführen. Oben ist die aktuell ausgeführte Funktion. Die Datensätze auf dem Stapel enthalten Informationen wie die Werte der Parameter, die an die Funktionen übergeben werden, und alle lokalen Variablen der Funktionen.

Es gibt einen anderen Speichertyp, auf den Ihr Programm Zugriff hat: Heap-Speicher. Hier vergeben Sie Speicherplatz mit malloc und sind nicht mit dem Aufruf-Stack verbunden.

Wenn Sie von einer Funktion zurückkehren, wird der Aufruf-Stack aufgerufen und alle mit dem Funktionsaufruf verbundenen Informationen gehen verloren. Wenn Sie eine Struktur zurückgeben möchten, haben Sie zwei Möglichkeiten: Kopieren Sie die Daten innerhalb der Struktur, bevor sie aus dem Aufruf-Stack herausgeholt werden, oder bewahren Sie die Daten im Heapspeicher auf und geben Sie einen Zeiger darauf zurück. Es ist teurer, das Datenbyte für Byte zu kopieren, als einfach einen Zeiger zurückzugeben, und daher würden Sie dies normalerweise tun, um Ressourcen zu sparen (sowohl Speicher- als auch CPU-Zyklen). Es kommt jedoch nicht ohne Kosten; Wenn Sie Ihre Daten im Heap-Speicher behalten, müssen Sie daran denken, free zu verwenden, wenn Sie aufhören zu verwenden Andernfalls wird das Programm Speicher verlieren.

    
Baldur Þór Emilsson 04.05.2012 17:10
quelle
1

Das Kopieren der gesamten Struktur und nicht nur des Zeigers ist weniger effizient, da die sizeof eines Zeigers normalerweise viel kleiner ist als sizeof einer ganzen Struktur selbst.

Außerdem kann eine Struktur Zeiger auf andere Daten im Speicher enthalten und blindes Kopieren, das für dynamisch zugewiesene Daten gefährlich sein könnte (würde ein Code, der eine Kopie behandelt, ihn freigeben, würde die andere Kopie einen ungültigen Zeiger hinterlassen).

Eine seichte Kopie ist fast immer eine schlechte Idee, es sei denn, Sie sind sicher, dass das Original den Gültigkeitsbereich verlässt - und warum würden Sie nicht einfach einen Zeiger auf die Struktur zurückgeben (eine Struktur, die natürlich auf dem Heap dynamisch zugeordnet ist) , so wird es nicht zerstört werden, wie die stack-allokierten Entitäten bei der Rückkehr von einer Funktion zerstört werden.

    
Will Ness 04.05.2012 16:31
quelle

Tags und Links