Zeiger als Rückgabetyp einer Funktion oder als Parameter?

Gast #5070519
Lesenswert?

Moin,

ich habe ene Frage zu zeigern in C/C++. Macht es einen Unterschied, ob 
ich für eine Struktur oder ein anderes großes Objekt eine der folgenden 
beiden Methoden verwende: Zeiger als Funktionsparameter oder Zeiger als 
Rückgabetyp einer Funktion?

Für beide muss ich mir in der main() eine Instanz erstellen. Ob ich nun 
die Anfangsadresse dieser Strukturinstanz als Parameter an eine Funktion 
übergebe oder aber einen Zeiger als Rückgabetyp einer Funktion nehme, 
spielt doch keine Rolle oder gibt es da Unterschiede? Zeiger als 
Parameter einer Funktion dienen ja in erster Linie dazu, dass man nicht 
lokal an Funktionsvariablen gebunden ist und mehr als einen Rückgabewert 
hat. Aber Zeiger als Funktionsparameter sind auch praktisch, wenn man 
eben die Adresse eine Struktur übergibt und dann mittels Zeiger die 
Strukturelemente ändern kann. Also wozu dann Zeiger als Rückgabetyp 
einer Funktion?
Gast #5070523
Lesenswert?

Du kannst dann z.B. in der Funktion auf dem Heap eine Instanz von einem 
Objekt erstellen und die Addresse davon zurückgeben. Es gibt da immer 
mehrere Möglichkeiten für das gleiche Problem. Oder man möchte die 
Funktion so bauen, dass das Ursprungsobjekt prinzipiell nicht geändert 
wird (const), aber trotzdem die Möglichkeit haben ein neues Objekt 
gleichen Types mit veränderten Einstellungen zurückzugeben.
Ich persönlich finde Zeiger als Rückgabewert von einer Funktion nicht 
soo schön, auch wenn ich es schon einige Male genutzt habe.

Es ist aber vom prinzip her etwas ganz anderes!
#5070534
Lesenswert?

Pointer als Rückgabetypen sollten genau dann verwendet werden wenn die 
Funktion die Adresse eines bereits existierenden Objekts an den 
Aufrufenden zurückgeben soll, weil der irgendwas damit machen will. Wenn 
du den Speicher für das Objekt in der Funktion erst reservierst, gibt 
man besser einen shared / uniqe pointer zurück.
Gast #5070658
Lesenswert?

Irgendwie bin ich zu böd die Frage bzw. die Antworten zu verstehen...

Wenn man einen Zeiger auf ein Objekt/Struktur aus einer Funktion 
zurückgeben möchte, dann kann man entweder den Zeiger als return Wert 
zurückgeben oder einen Zeiger auf einen Zeiger als Pameter nutzen.
(Referenzen mal unbetrachtet...)

Der feine Unterschied

* "ich teile der Funktion mit, wo das Objekt liegt" (Parameter Zeiger 
auf Objekt) und der Variante

* "ich teile der Funktion mit, wo sie mir ihren Zeiger auf das Objekt 
zurückliefern kann" (Parameter Zeiger auf Zeigerauf Objekt)
fehlt mir hier.
Gast #5070784
Lesenswert?

Tobi schrieb:
> Wo also liegt ein Unterschied?

Beim Pointer auf eine Struktur bekommst du genau einen Pointer
umkopiert, bei der Übergabe einer Struktur wird eine grössere
Datenmenge (entsprechend der Grösse der Struktur) umkopiert.
Bei zeitkritischen Dingen also ein Thema.

Ist es das was du wissen woltest?
Gast #5070825
Lesenswert?

Mitlesa schrieb:
> Beim Pointer auf eine Struktur bekommst du genau einen Pointer
> umkopiert, bei der Übergabe einer Struktur wird eine grössere
> Datenmenge (entsprechend der Grösse der Struktur) umkopiert.
> Bei zeitkritischen Dingen also ein Thema.
>
> Ist es das was du wissen woltest?

Ich glaube, dass er
- Zeiger auf Zeiger als Parameter
und
-Zeiger als Rückgabewert
meint.
So ganz verstehe ich seine Frage aber auch nicht.

@Tobi

"Aber Zeiger als Funktionsparameter sind auch praktisch, wenn man
eben die Adresse eine Struktur übergibt und dann mittels Zeiger die
Strukturelemente ändern kann. Also wozu dann Zeiger als Rückgabetyp
einer Funktion?"

Mir ist nicht ganz klar, wie die beiden Sätze logisch zusammenhängen 
("Also wozu ..."). Das eine ist die Übergabe eines Zeigers (Effizienz), 
das andere die Rückgabe eines Ergebnisses (z.B. Zeiger, wenn in der 
Funktion Speicher allokiert wurde). Es gibt Funktionen, die den 
übergebenen Zeiger wieder zurückgeben, weil der aufrufende Code dann 
u.U. eleganter geschrieben werden kann, aber ich denke nicht, dass du 
das meinst.
Gast #5070929
Lesenswert?

Tobi schrieb:
> Irgendwie hilft mir das nicht weiter. Ob Zeiger als Rückgabetyp
> oder
> Zeiger als Parameter,am Ende landet das Ergebnis trotzdem in der
> MainFunktion. Wo also liegt ein Unterschied?

Das hängt von dir ab und was du machen willst.

Schau dir die beiden Funktionen printf() und strcpy() an. ?
(Firma: privatfrickler.de) #5071149
Lesenswert?

Hallo Tobi,

ich glaube mittlerweile habe ich die Frage verstanden. Alles was zur 
Antwort gehört wurde hier schon gepostet, vielleicht würde es Dir 
helfen, wenn ich es noch mal zusammenfasse.

Ich gehen mal davon aus, dass es um C geht und es nur die beiden Fälle 
1. Pointer übergeben, aber keinen liefern und 2. Pointer liefern aber 
keinen übernehmen. Von Zeigern auf Zeiger steht in Deiner Frage nichts, 
den Fall schließe ich auch aus. Ferner schließe ich den Zugriff auf den 
globalen Scope aus.

Pointer wird übergeben

möglich:
• In die Struktur, auf die der Pointer zeigt schreiben
• Aus der Struktur, auf die der Pointer zeigt lessen
• mehrfacher Aufruf mit der selben Struktur (akkumulieren)

Die Funktion kann zum Beispiel ein Member der Struktur erhöhen.

nicht möglich:
• Neue Struktur erzeugen und zurückgeben
• Zerstörungsfreie Rückgabe der Struktur

Die Funktion kann zum Beispiel nichts zurückgeben ohne die Struktur, auf 
die der Pointer zeigt, zu verändern.

Pointer wird zurückgegeben

zwingend erforderlich
• Es muss ein neuer Speicherbereich allokiert werden

nicht möglich:
• mehrfacher Aufruf mit der selben Struktur
• mehrfacher Aufruf, ohne dass Speicher allokiert wird
• Zugriff auf bestehende Daten in einer Struktur

ohne Anspruch auf Vollständigkeit :-)

vlg

Timm
Gast #5071467
Lesenswert?

Ein Beispiel wäre:

FILE* fopen(const char *filename, const char *mode);
int fprintf(FILE *stream, const char *format, ... );
int fclose (FILE *stream);

fopen() allokiert einen Speicherbereich und liefert einen Zeiger zurück.
fprintf() und fclose() bekommen diesen Zeiger als Parameter. Verändern 
über den Zeiger die Daten.

Heutzutage schreibt man const char *format, damit jeder sofort sieht, 
fprintf() verändert nur *stream, nicht aber *format.
Gast #5073616
Lesenswert?

Besten Dank für die Infos. Denke ich habe es verstanden. Eine kurze 
Frage noch.

Was ist vorteilhafter:
1
int i = 5;
2
int *ptr = &i;

Oder direkt
1
int *ptr;
2
*ptr = 5;

Der Wert steht so oder so an einer Adresse, egal ob diese einen Namen 
hat wie "i" oder wo liegt der Unterschied?
Beitrag #5073663 wurde von einem Moderator gelöscht.
#5073703
Lesenswert?

Tobi schrieb:
> Besten Dank für die Infos. Denke ich habe es verstanden. Eine kurze
> Frage noch.
>
> Was ist vorteilhafter:
> int i = 5;
> int *ptr = &i;
>
> Oder direkt
> int *ptr;
> *ptr = 5;
>
> Der Wert steht so oder so an einer Adresse,

"An einer Adresse" reicht aber nicht. Er muss schon auch an der Adresse 
stehen, wo er hingehört.

> egal ob diese einen Namen hat wie "i" oder wo liegt der Unterschied?

Im ersten Fall wird eine Variable angelegt, der offiziell der Speicher 
zugeordnet ist. Dann holst du dir die Adresse dieser Speicherstelle und 
schreibst da eine 5 rein.
Im zweiten Fall hast du einen Zeiger, der uninitialisiert ist, also 
irgendwo in den Speicher auf eine mehr oder weniger zufällige Adresse 
verweist. Danach nimmst du diesen und schreibst damit deine 5 irgendwo 
"ins Gemüse". Nach ISO C ist das Verhalten dieser Zeile undefiniert, da 
man uninitialisierte Zeiger nicht dereferenzieren darf.
Gast #5074675
Lesenswert?

Peter D. schrieb:
> Pointer als Returnwert nimmt man vorzugsweise

Wenn man einen Zeiger zurück geben mochte. :-P

Das macht hauptsächlich Sinn, wenn es sich um größere Datenmengen 
handelt, die direkt weiterverarbeitet werden. z. B. als Parameter.

Bei Strings passen die Bedingungen auch und wer mit mehrschichtiger 
Kommunikation zu tun hat,weiss Bescheid.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren