Archiv verlassen und diese Seite im Standarddesign anzeigen : Warum Zeiger???
Mal ne ganz doofe Frage:
Warum Zeiger benutzen?? Ich kann doch auch 'ganz normal' auf eine Variable zugreifen und dessen Wert ändern...
Danke für sinnvolle Beiträge... :-k
Zum Beispiel bei zeitkritischen Anwendungen haben Zeige der Vorteil, dass sie schneller sind. Einfach dadurch, dass die Variabeln nicht erst kopiert werden müssen...
Oft will man aber auch mit einer Funktion eine Variabel direkt verarbeiten und nicht nur die Kopie... und dann gibt es sicher noch tausend andere Gründe...
Tja, das ist halt so eine Sache mit den Zeigern...
es gibt mehr als genug Probleme die sich mit Zeigern eleganter und/oder schneller lösen lassen, bzw. die ohne Zeiger nahezu unlösbar sind.
Und es gibt ja nicht nur Zeiger auf Variablen, sondern auch Funktionszeiger...
mit denen kann man ein Programm herrlich flexibel gestalten, da man über einen Zeiger (also mit dem gleichen "Namen") auf viele unterschiedliche Funktionen zugreifen kann.
Leider ist es schwer Jemandem zu vermitteln wo bei der ganzen Sache der Sinn liegen soll, denn Beispiele für den Einsatz von Zeigern gibt es zwar reichlich, aber bei vielen erkennt man als Anfänger einfach nicht warum Zeiger in einer konkreten Situation zu eleganterem, schnellerem oder besser lesbarem Code führen sollen (besonders letzteres wirkt auf Jemandem der keine Erfahrung mit dem Einsatz von Zeigern hat meist genau umgekehrt).
Ich hatte früher auch keinen besonderen Sinn in diesem Sprachkonstrukt gesehen, und hielt Zeiger eher für störenden Ballast. Diese Meinung hat sich bei mir auch nicht schlagartig geändert, sondern ich habe mich einfach langsam an diese seltsamen Dinger gewöhnt, und sie mit der Zeit immer häufiger eingesetzt.
hallo,
in folgendem buch wird das thema umfassend besprochen:
http://dollywood.itp.tuwien.ac.at/~edv2/Manuals/schmaranz.pdf
lg
Danke für die Beiträge!
Ich bin kein wirklicher Anfänger, habe schon einige Sachen programmiert, teils auch umfangreicher, aber dennoch in überschaubarem Umfang. Deshalb konnte ich bisher auf den Einsatz von Zeigern verzichten.
Was ein Zeiger grundsätzlich ist, bzw. was man mit ihm anstellen kann, auch im Bezug auf Funktionspointer, das ist mir klar.
Nur die grundsätzlichen Vorteile sind mir noch etwas unklar.
Aber werde mal das Buch bezüglich den Zeigern durchlesen!
Mein jetziger Wissensstand der Vorteile:
- flexibler mit Funktionspointer
- schnellerer Zugriff auf Variablen
- auch wird grundsätzlich der Code kleiner (zumindest nach dem compilieren), wenn man mit zeigern arbeitet
Gruß u. schönes WE!
bei statischen arrays, zB char buffer[256]; muss man zur programmierzeit wissen, dass es nie mehr als 256 chars werden, und wenn es weniger sind, ist speicher verschenkt. da bietet es sich an, mit char *buffer=malloc(size); zur laufzeit soviel speicher zu reservieren, wie benötigt wird.
bei funktionen gerät man mit einem return x; in die verlegenheit, nur einen wert zurückgeben zu können. auch da ist es bequemer, zeiger zu übergeben, um mehrere variablen zu verändern, ohne sie global definieren zu müssen.
gruesse
Stimmt das sind zwei Paradebeispiele für den Einsatz von Zeigern...
verkettete Listen oder ähnliche Konstrukte mit denen man einen Speicher mit variabler Größe programmieren kann, dürften ohne Zeiger kaum zu realisieren sein.
Und bei Funktionen arbeite ich oft selbst dann mit Zeigern, wenn sie nur einen Wert zurückgeben. Genauer gesagt tue ich das immer wenn bei einer Funktion die Möglichkeit besteht daß sie nicht fehlerfrei ausgeführt wird, dann liefere ich per return nur einen Fehlercode, und verwende für den eigentlichen Rückgabewert dann eben einen Zeiger.
Mir ist auch gerade noch ein schönes Beispiel für den Einsatz von Funktionspointern eingefallen...
Angenommen man hat irgendwelche Daten die z.B. in einer verketteten Liste gespeichert sind, und mit diesen Daten möchte man nun verschiedene Dinge anstellen. Vielleicht möchte man nach einem bestimmten Wert suchen, oder die Liste sortieren oder jeden Wert irgendwie verändern. Dann kann man natürlich mehrere Funktionen schreiben, die dann eben die ganze Liste durchgehen, und dann für jeden Wert jeweils das tun was sie eben tun sollen.
ooooder man schreibt sich eine Funktion die den Teil der Arbeit übernimmt der immer gleich bleibt (die Liste durchgehen und für jedes Element irgendetwas tun), und übergibt dieser Funktion dann jeweils einen Funktionspointer auf eine Funktion die mit einem Element der Liste eben genau das tut was man in diesem konkreten Fall tun möchte.
kurz gesagt:
wenn man eine Menge von Funktionen mit deutlichen Gemeinsamkeiten hat, also Funktionen die alle fast das Gleiche machen, dann geht man eben her und fasst das was bei allen gleich ist in einer Funktion zusammen. Der Vorteil dabei ist natürlich, daß man nicht mehrfach den gleichen Code hat, was ansonsten bei Fehlern und Änderungen immer problematisch ist (da man daran denken muss diesen Code überall dort zu ändern wo er vorkommt).
hallo Felix G,
das ist sehr interessant mit den function-pointern. bisher war mir das ein buch mit sieben siegeln, deshalb habe ich 1-2 möglicherweise triviale fragen und einen batzen code.
#include<stdio.h>;
#include<malloc.h>;
#include<conio.h>; // fuer getch
// die listenstruktur
struct LISTELEM
{
int nr;
struct LISTELEM *next;
};
/************************************************** ***************
weist dem uebergebenen element eine nummer zu
************************************************** ***************/
void number(struct LISTELEM *elem)
{
elem->nr=1;
}
/************************************************** ***************
gibt daten des uebergebenen elements aus
************************************************** ***************/
void output(struct LISTELEM *elem)
{
printf("element %d an adresse %x\r\n",elem->nr,elem);
}
/************************************************** ***************
crawled durch die liste "chain" und ruft die funktion fct() auf
************************************************** ***************/
void crawl(struct LISTELEM *chain,void fct(struct LISTELEM *elem),int delete)
{
struct LISTELEM *old; // fuer loeschen von listenelementen
while(chain!=NULL)
{
if(fct)fct(chain);
if(delete)
{
old=chain;
printf("*");
}
chain=chain->next;
if(delete)free(old);
}
}
/************************************************** ***************
einsprungspunkt main
************************************************** ***************/
int main(void)
{
int i;
struct LISTELEM *list=NULL;
struct LISTELEM *chain;
// liste anlegen
for(i=0;i<10;i++)
{
chain=(struct LISTELEM *)malloc(sizeof(struct LISTELEM));
chain->nr=i;
chain->next=list;
list=chain;
}
// aufrufe von crawl mit verschiedenen funktion-pointern
crawl(list,output,0);
crawl(list,number,0);
crawl(list,NULL,1);
getch();
return 0;
}
/************************************************** **************/
es wird eine verkettete liste angelegt (in main) und dann die funktion crawl aufgerufen, die sich durch die liste hangelt und die übergebene funktion (number oder output) darauf anwendet. das scheint soweit ganz gut zu klappen, allerdings kann ich der funktion output keinen weiteren parameter (einen wert, der zugewiesen werden soll zB) übergeben, ohne dass ich der output funktion quasi als dummy auch einen wert übergebe, obwohl sie ihn nicht benötigt(?). bräuchte ich da variable parameter? :-s
zum anderen fällt mir keine funktion ein, die ein element löscht, (weil dann crawl ja das nächste element (chain->next) nicht mehr findet. deshalb das workaround mit "if(delete)...".
scheinbar sind functionpointer ein sehr mächtiges werkzeug, das ich aber hier recht ungeschickt anwende.. :roll:
vielleicht kannst du mir ja bisschen auf die sprünge helfen.
gruesse von der katze
Also das Problem mit dem löschen könnte man lösen, indem man die Struktur Listelem noch durch einen Pointer auf das vorherige Element ergänzt. Dann hätte eine delete-Funktion alles was sie braucht um ein Element korrekt zu löschen.
Was die Parameter betrifft, so ist das natürlich ein ganz zentrales Problem bei der Verwendung von Funktionspointern. Man muss eine sinnvolle Schnittstelle definieren, über die man die Funktionen mit allen nötigen Informationen versorgen kann, und das möglichst ohne zu viel Ballast. Denkbar wären vielleicht zwei Parameter "input" und "output" (als void*), zur Übergabe von funktionsspezifischen Daten. Vielleicht gibt es da aber auch noch elegantere Lösungen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.