Forum: Mikrocontroller und Digitale Elektronik Pointer: Anwendungsbeispiele


von newbo (Gast)


Lesenswert?

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.

von Stefan R. (srand)


Lesenswert?

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.

von Christian V. (michse)


Lesenswert?

Wenn irgendwas übergeben wird, das nicht einfach nur eine Variable ist 
(Arrays), auch Verkettete Listen und Bäume werden mit Pointern 
implementiert.

von Falk B. (falk)


Lesenswert?

@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

von Frank (Gast)


Lesenswert?

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?

von Falk B. (falk)


Lesenswert?

@ 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 ;-)

von Balu der Bär (Gast)


Lesenswert?

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.

von newbo (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Paul B. (paul_baumann)


Lesenswert?

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

von Nobody (Gast)


Lesenswert?

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.

von Sebastian V. (sebi_s)


Lesenswert?

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
Noch kein Account? Hier anmelden.