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?
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!
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.
Bei Parameter Übergabe kann ich in der Main die Instanz der Struktur auch ändern. Auch ohne Zeiger als Rückgabe typ.
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.
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?
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?
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.
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. ?
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
:
Bearbeitet durch User
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.
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?
Der Unterschied ist dass das zweite abstürzt weil der Pointer uninitialisiert ist und auf keinen reservierten Speicher zeigt. Das geht so nicht.
Beitrag #5073663 wurde von einem Moderator gelöscht.
Dein zweites Beispiel würde funktionieren, wenn Du den Zeiger vorher auf eine Variable zeigen lässt:
1 | int i; |
2 | int *ptr = &i; |
3 | *ptr = 5; |
4 | |
5 | printf("%d", i); |
Ergibt:
1 | 5 |
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.
http://www.peacesoftware.de/ckurs12.html http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/012_c_zeiger_002.htm
Pointer als Returnwert nimmt man vorzugsweise für Stringfunktionen. Z.B. gibt jeder Aufruf von strtok() den Pointer auf das nächste Token zurück.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.