Ich beschäftige mich aktuell mit C und Pointern. Bei mir ist hängen geblieben, dass Pointer besonders im Embedded-Bereich sinnvoll sind, wenn man keine so großen Ressourcen hat. Dann übergibt man als Übergabeparameter nur die Adresse des Zeigers anstatt den ganzen Wert ansich in eine neue Speicherstelle zu kopieren, richtig? Wenn man jetzt einen externen Speicher nimmt anstelle OnChip, büßt man dann nicht an Leistung ein? Ich wüsste jetzt spontan nicht, wann ich einen Zeiger nehmen sollte. Gibt es Daumenregeln, macht ihr das nach Gefühl, wird das üblicherweise bereits zum Zeitpunkt der Spec/Design festgelegt und nicht erst bei der Implementierung? Wovon macht ihr das abhängig? Über eine Beispiel oder Erfahrungswerte würde ich mich freuen. Danke im voraus.
Zeiger nimmt man primär, um verkettete Datenstrukturen aufzubauen. Dein Beispiel ist völlig unabhängig von Embedded oder nicht und ein vergleichsweise unwichtiges Detail. Der Hauptgrund für Zeiger ist Indirektion. Konkrete Beispiele sind Legion, insofern ist es schwierig, die zu nennen, die dich evtl. interessieren. Such mal nach verketteter Liste. B-Tree. Menüs. Plugin-Architekturen.
Wenn irgendwas übergeben wird, das nicht einfach nur eine Variable ist (Arrays), auch Verkettete Listen und Bäume werden mit Pointern implementiert.
@newbo (Gast) >Wenn man jetzt einen externen Speicher nimmt anstelle OnChip, büßt man >dann nicht an Leistung ein? Nein. >Ich wüsste jetzt spontan nicht, wann ich einen Zeiger nehmen sollte. >Gibt es Daumenregeln, macht ihr das nach Gefühl, wird das üblicherweise >bereits zum Zeitpunkt der Spec/Design festgelegt Meisten ja. > und nicht erst bei der >Implementierung? Manchmal. > Wovon macht ihr das abhängig? Einen Zeiger nimmt man wenn - die Originaldaten beschrieben werden sollen - die zu verarbeitenden Daten größer als eine normale Variable sind (große Structs oder Arrays) - Arrays werden IMMER als Zeiger übergeben
Wenn ich z.B in einer Funktion Berechnungen o.ä. durchführen möchte und deren Parameter und Ergebnisse wieder in einer Vielzahl an Funktionen verwendet werden soll, warum soll ich jedes mal bei der Übergabe an die Funktion ein Duplikat anlegen und den Rückgabewert später auch wieder umkopieren wenn ich genauso gut auch gleich mit den originalen arbeiten kann? Und noch ne andere Frage. Wie gibst di mehr als einen Wert aus einer Funktion zurück?
@ Frank (Gast) >Wenn ich z.B in einer Funktion Berechnungen o.ä. durchführen möchte und >deren Parameter und Ergebnisse wieder in einer Vielzahl an Funktionen >verwendet werden soll, warum soll ich jedes mal bei der Übergabe an die >Funktion ein Duplikat anlegen und den Rückgabewert später auch wieder >umkopieren wenn ich genauso gut auch gleich mit den originalen arbeiten >kann? Weil du das Prinzip der Kapselung noch nicht verstanden hast. Eine Funktion soll so weit wie möglich KEINERLEI unsichtbare Nebeneffekte haben. Das erreicht man u.a. durch Funktionsparameter (welche Kopien sind) und einem Rückgabeparameter. Es hat schon seinen Grund, warum es in C normale Funktionsparameter (call by value) und Zeiger (call by reference) gibt. >Wie gibst di mehr als einen Wert aus einer Funktion zurück? Mit einem Struct als Rückgabewert ;-)
Man sollte auch beachten, dass die Übergabe per Wert bei Typen mit geringer Größe in der Regel schneller ist als die Zeigeroperationen, die bei 'call by reference' nötig sind. Ich erwähne es nur mal, weil manche Anfänger gleich übertreiben und "aus Performancegründen" auch bei char, int usw. Zeiger (bzw. bei C++ auch Referenzen) verwenden.
Falk B. schrieb: > @ Frank (Gast) > >>Wenn ich z.B in einer Funktion Berechnungen o.ä. durchführen möchte und >>deren Parameter und Ergebnisse wieder in einer Vielzahl an Funktionen >>verwendet werden soll, warum soll ich jedes mal bei der Übergabe an die >>Funktion ein Duplikat anlegen und den Rückgabewert später auch wieder >>umkopieren wenn ich genauso gut auch gleich mit den originalen arbeiten >>kann? > > Weil du das Prinzip der Kapselung noch nicht verstanden hast. Eine > Funktion soll so weit wie möglich KEINERLEI unsichtbare Nebeneffekte > haben. Das erreicht man u.a. durch Funktionsparameter (welche Kopien > sind) und einem Rückgabeparameter. Es hat schon seinen Grund, warum es > in C normale Funktionsparameter (call by value) und Zeiger (call by > reference) gibt. > >>Wie gibst di mehr als einen Wert aus einer Funktion zurück? > > Mit einem Struct als Rückgabewert ;-) Also nehme ich Pointer, wenn es um die Verarbeitung großer struct und arrays geht. Ich versuche aber Pointer und die daraus resultierenden unsichtbaren Nebeneffekte weitestgehend zu vermeiden, um eine hohe Kapselung für mein Modul zu erreichen. Bei char und int prüfe ich, ob deren Übergabe nicht schneller geht als eine Zeigeroperation. Richtig? Danke für die Tipps.
newbo schrieb: > Bei mir ist hängen geblieben, dass Pointer besonders im Embedded-Bereich > sinnvoll sind, wenn man keine so großen Ressourcen hat. Die heutigen Compiler sind meistens nicht so doof, wie viele denken. Man kann oft die Indexschreibweise benutzen und der Compiler wandelt das selber in Pointer um. Außerdem macht es der Index leichter, ein Argument auf Feldüberschreitung zu testen und es ist nur ein Test nötig (Endwert). Ein Test verhindert zwar nicht den Fehler, aber er verhindert, daß sich der Fehler an einer völlig anderen Stelle auswirkt und man sich dumm und dußlig sucht. Ein falscher Pointerzugriff kann nämlich den Wert einer völlig anderen Funktion verändern, die daran total unschuldig ist. Wenn es keinen triftigen Grund dagegen gibt, sollte man die Indexschreibweise bevorzugen. Was in der Regel teuer ist, sind Pointer auf Pointer auf Pointer. Flache Strukturen sind schneller.
Peter D. schrieb: > Was in der Regel teuer ist, sind Pointer auf Pointer auf Pointer. Das wären dann praktisch Pointer Sisters: https://www.youtube.com/watch?v=K9S5EZgIJck MfG Paul
Falk B. schrieb: > Weil du das Prinzip der Kapselung noch nicht verstanden hast. Eine > Funktion soll so weit wie möglich KEINERLEI unsichtbare Nebeneffekte > haben. Das erreicht man u.a. durch Funktionsparameter (welche Kopien > sind) und einem Rückgabeparameter. Es hat schon seinen Grund, warum es > in C normale Funktionsparameter (call by value) und Zeiger (call by > reference) gibt. Naja was hindert dich daran die Übergabeparameter als const zu deklarieren: void foo(const int* const pointer1, const long* pointer2) Damit stellst sicher, dass pointer1 nirgendwo hinzeigen kann und auch dessen "Inhalt" nicht verändert werden kann... Bei pointer2 hingegen kann der "Inhalt" geändert werden.
Nobody schrieb: > Damit stellst sicher, dass pointer1 nirgendwo hinzeigen kann und auch > dessen "Inhalt" nicht verändert werden kann... > Bei pointer2 hingegen kann der "Inhalt" geändert werden. Pointer die nirgendwo hinzeigen sind sinnlos (außer NULL Pointer). Außerdem wie definierst du Inhalt? Dein pointer1 ist ein konstanter Pointer (das heißt es lässt sich nicht ändern wohin der Pointer zeigt) auf einen konstanten Wert. Und pointer2 ist nur ein Pointer auf einen konstanten Wert und ist damit ausreichend. Ob die Funktion das Ziel das Pointers ändern kann ist egal, da die Funktion sowieso eine Kopie des Pointers hat.
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.