webentwicklung-frage-antwort-db.com.de

Warum Zeiger verwenden?

Ich weiß, dass dies eine wirklich grundlegende Frage ist, aber ich habe gerade mit einer grundlegenden C++ - Programmierung begonnen, nachdem ich einige Projekte mit Hochsprachen codiert hatte.

Grundsätzlich habe ich drei Fragen:

  1. Warum Zeiger gegenüber normalen Variablen verwenden?
  2. Wann und wo soll ich Zeiger verwenden?
  3. Wie verwendet man Zeiger bei Arrays?
335
Anonymous
  • Warum Zeiger gegenüber normalen Variablen verwenden?

Die kurze Antwort lautet: Tu es nicht. ;-) Zeiger sind dort zu verwenden, wo Sie nichts anderes verwenden können. Es liegt entweder an der fehlenden entsprechenden Funktionalität, fehlenden Datentypen oder an der reinen Leistung. Mehr unten ...

  • Wann und wo soll ich Zeiger verwenden?

Kurze Antwort hier ist: Wo Sie nichts anderes verwenden können. In C werden komplexe Datentypen wie Zeichenfolgen nicht unterstützt. Es gibt auch keine Möglichkeit, eine Variable "per Referenz" an eine Funktion zu übergeben. Hier müssen Sie Zeiger verwenden. Sie können sie auch so gut wie auf alles verweisen lassen, auf verknüpfte Listen, Mitglieder von Strukturen und so weiter. Aber darauf wollen wir hier nicht eingehen.

  • Wie verwendet man Zeiger bei Arrays?

Mit wenig Aufwand und viel Verwirrung. ;-) Wenn wir über einfache Datentypen wie int und char sprechen, gibt es kaum einen Unterschied zwischen einem Array und einem Zeiger. Diese Deklarationen sind sehr ähnlich (aber nicht gleich - z. B. gibt sizeof unterschiedliche Werte zurück):

char* a = "Hello";
char a[] = "Hello";

Sie können jedes Element im Array wie folgt erreichen

printf("Second char is: %c", a[1]);

Index 1, da das Array mit Element 0 beginnt :-)

Oder Sie könnten dies genauso tun

printf("Second char is: %c", *(a+1));

Der Zeigeroperator (*) wird benötigt, da wir printf mitteilen, dass wir ein Zeichen drucken möchten. Ohne das * würde die Zeichendarstellung der Speicheradresse selbst gedruckt. Jetzt verwenden wir stattdessen das Zeichen selbst. Wenn wir% s anstelle von% c verwendet hätten, hätten wir printf gebeten, den Inhalt der Speicheradresse zu drucken, auf die 'a' plus eins zeigt (in diesem Beispiel oben), und wir hätten das * nicht setzen müssen. vor:

printf("Second char is: %s", (a+1)); /* WRONG */

Dies hätte jedoch nicht nur das zweite Zeichen gedruckt, sondern alle Zeichen in den nächsten Speicheradressen, bis ein Nullzeichen (\ 0) gefunden wurde. Und hier wird es gefährlich. Was ist, wenn Sie versehentlich versuchen, eine Variable vom Typ Integer anstelle eines Zeichenzeigers mit dem Formatierer% s zu drucken?

char* a = "Hello";
int b = 120;
printf("Second char is: %s", b);

Dies würde alles drucken, was auf der Speicheradresse 120 gefunden wird, und weiter drucken, bis ein Nullzeichen gefunden wurde. Es ist falsch und illegal, diese printf-Anweisung auszuführen, aber es würde wahrscheinlich trotzdem funktionieren, da ein Zeiger in vielen Umgebungen tatsächlich vom Typ int ist. Stellen Sie sich die Probleme vor, die Sie verursachen könnten, wenn Sie stattdessen sprintf () verwenden und auf diese Weise ein zu langes "char array" einer anderen Variablen zuweisen, der nur ein bestimmter begrenzter Speicherplatz zugewiesen wurde. Sie würden höchstwahrscheinlich über etwas anderes im Speicher schreiben und Ihr Programm zum Absturz bringen (wenn Sie Glück haben).

Oh, und wenn Sie dem char-Array/Zeiger beim Deklarieren keinen Zeichenfolgewert zuweisen, MÜSSEN Sie ihm genügend Speicher zuweisen, bevor Sie ihm einen Wert zuweisen. Mit malloc, calloc o.ä. Dies liegt daran, dass Sie nur ein Element in Ihrem Array/eine einzelne Speicheradresse als Zeiger deklariert haben. Hier sind einige Beispiele:

char* x;
/* Allocate 6 bytes of memory for me and point x to the first of them. */
x = (char*) malloc(6);
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* Delete the allocation (reservation) of the memory. */
/* The char pointer x is still pointing to this address in memory though! */
free(x);
/* Same as malloc but here the allocated space is filled with null characters!*/
x = (char *) calloc(6, sizeof(x));
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* And delete the allocation again... */
free(x);
/* We can set the size at declaration time as well */
char xx[6];
xx[0] = 'H';
xx[1] = 'e';
xx[2] = 'l';
xx[3] = 'l';
xx[4] = 'o';
xx[5] = '\0';
printf("String \"%s\" at address: %d\n", xx, xx);

Beachten Sie, dass Sie die Variable x weiterhin verwenden können, nachdem Sie free () für den zugewiesenen Speicher ausgeführt haben, aber nicht wissen, was sich dort befindet. Beachten Sie auch, dass die beiden Befehle printf () möglicherweise unterschiedliche Adressen enthalten, da nicht garantiert wird, dass die zweite Speicherzuweisung im selben Bereich wie die erste durchgeführt wird.

167
Tooony

Ein Grund für die Verwendung von Zeigern besteht darin, dass eine Variable oder ein Objekt in einer aufgerufenen Funktion geändert werden kann.

In C++ ist es besser, Referenzen als Zeiger zu verwenden. Obwohl Referenzen im Wesentlichen Zeiger sind, verbirgt C++ diese Tatsache bis zu einem gewissen Grad und lässt es so erscheinen, als ob Sie an einem Wert vorbeigehen. Auf diese Weise können Sie die Art und Weise ändern, in der die aufrufende Funktion den Wert empfängt, ohne die Semantik der Übergabe ändern zu müssen.

Betrachten Sie die folgenden Beispiele:

Referenzen verwenden:

public void doSomething()
{
    int i = 10;
    doSomethingElse(i);  // passes i by references since doSomethingElse() receives it
                         // by reference, but the syntax makes it appear as if i is passed
                         // by value
}

public void doSomethingElse(int& i)  // receives i as a reference
{
    cout << i << endl;
}

Zeiger verwenden:

public void doSomething()
{
    int i = 10;
    doSomethingElse(&i);
}

public void doSomethingElse(int* i)
{
    cout << *i << endl;
}
49
trshiv
  1. Mit Zeigern können Sie von mehreren Stellen aus auf denselben Speicherbereich verweisen. Dies bedeutet, dass Sie den Speicher an einem Ort aktualisieren können und die Änderung an einem anderen Ort in Ihrem Programm sichtbar ist. Sie sparen außerdem Platz, indem Sie Komponenten in Ihren Datenstrukturen gemeinsam nutzen können.
  2. Sie sollten Zeiger an jeder Stelle verwenden, an der Sie die Adresse abrufen und an eine bestimmte Stelle im Speicher weitergeben möchten. Sie können auch Zeiger zum Navigieren in Arrays verwenden:
  3. Ein Array ist ein zusammenhängender Speicherblock, dem ein bestimmter Typ zugewiesen wurde. Der Name des Arrays enthält den Wert des Startpunkts des Arrays. Wenn Sie 1 hinzufügen, gelangen Sie zum zweiten Punkt. Auf diese Weise können Sie Schleifen schreiben, die einen Zeiger inkrementieren, der sich über das Array bewegt, ohne dass ein expliziter Zähler für den Zugriff auf das Array vorhanden ist.

Hier ist ein Beispiel in C:

char hello[] = "hello";

char *p = hello;

while (*p)
{
    *p += 1; // increase the character by one

    p += 1; // move to the next spot
}

printf(hello);

druckt

ifmmp

denn es nimmt den Wert für jedes Zeichen und erhöht ihn um eins.

37
Kyle Cronin

Zeiger sind eine Möglichkeit, einen indirekten Verweis auf eine andere Variable zu erhalten. Anstatt den Wert einer Variablen zu speichern, teilen sie Ihnen die Adresse mit . Dies ist besonders nützlich, wenn Sie mit Arrays arbeiten, da Sie mithilfe eines Zeigers auf das erste Element in einem Array (seine Adresse) schnell das nächste Element finden können, indem Sie den Zeiger inkrementieren (auf die nächste Adressposition).

Die beste Erklärung für Zeiger und Zeigerarithmetik, die ich gelesen habe, ist in K & Rs The C Programming Language . Ein gutes Buch für den Einstieg in C++ ist C++ Primer .

24
Bill the Lizard

Lassen Sie mich das auch versuchen und beantworten.

Zeiger ähneln Referenzen. Mit anderen Worten, es handelt sich nicht um Kopien, sondern um eine Art, sich auf den ursprünglichen Wert zu beziehen.

Vor allem ist ein Ort, an dem normalerweise müssen Sie Zeiger verwenden viel, wenn Sie es zu tun haben mit eingebetteter Hardware. Möglicherweise müssen Sie den Status eines digitalen IO pin umschalten. Möglicherweise verarbeiten Sie einen Interrupt und müssen einen Wert an einem bestimmten Ort speichern. Sie erhalten das Bild. Ich beschäftige mich nicht direkt mit Hardware und frage mich nur, welche Typen ich verwenden soll. Lies weiter.

Warum Zeiger im Gegensatz zu normalen Variablen verwenden? Die Antwort wird klarer, wenn Sie sich mit komplexen Typen wie Klassen, Strukturen und Arrays befassen. Wenn Sie eine normale Variable verwenden würden, könnten Sie am Ende eine Kopie erstellen (Compiler sind klug genug, dies in einigen Situationen zu verhindern, und C++ 11 hilft auch, aber wir werden uns vorerst von dieser Diskussion fernhalten).

Was passiert nun, wenn Sie den ursprünglichen Wert ändern möchten? Sie könnten so etwas verwenden:

MyType a; //let's ignore what MyType actually is right now.
a = modify(a); 

Das funktioniert einwandfrei und wenn Sie nicht genau wissen, warum Sie Zeiger verwenden, sollten Sie sie nicht verwenden. Hüten Sie sich vor dem Grund "Sie sind wahrscheinlich schneller". Führen Sie Ihre eigenen Tests durch und verwenden Sie sie, wenn sie tatsächlich schneller sind.

Angenommen, Sie lösen ein Problem, bei dem Sie Speicher zuweisen müssen. Wenn Sie Speicher zuordnen, müssen Sie die Zuordnung aufheben. Die Speicherzuweisung kann erfolgreich sein oder nicht. Hier kommen Zeiger zum Einsatz - sie ermöglichen es Ihnen, die Existenz des Objekts zu testen, das Sie zugewiesen haben, und sie ermöglichen Ihnen den Zugriff auf das Objekt, für das der Speicher zugewiesen wurde durch De-Referenzieren des Zeigers.

MyType *p = NULL; //empty pointer
if(p)
{
    //we never reach here, because the pointer points to nothing
}
//now, let's allocate some memory
p = new MyType[50000];
if(p) //if the memory was allocated, this test will pass
{
    //we can do something with our allocated array
    for(size_t i=0; i!=50000; i++)
    {
        MyType &v = *(p+i); //get a reference to the ith object
        //do something with it
        //...
    }
    delete[] p; //we're done. de-allocate the memory
}

Dies ist der Schlüssel für die Verwendung von Zeigern - Referenzen setzen voraus, dass das Element, auf das Sie verweisen, bereits vorhanden ist. Ein Zeiger nicht.

Der andere Grund, warum Sie Zeiger verwenden würden (oder sich zumindest damit befassen müssten), ist, dass es sich um einen Datentyp handelt, der vor Verweisen existierte. Wenn Sie am Ende Bibliotheken verwenden, um die Dinge zu tun, von denen Sie wissen, dass sie besser sind, werden Sie feststellen, dass viele dieser Bibliotheken überall Zeiger verwenden von ihnen wurden vor C++) geschrieben.

Wenn Sie keine Bibliotheken verwenden, können Sie Ihren Code so gestalten, dass Sie sich von Zeigern fernhalten. Da Zeiger jedoch zu den Grundtypen der Sprache gehören, können Sie sie umso schneller verwenden portabel wären deine C++ Kenntnisse.

Unter dem Gesichtspunkt der Wartbarkeit sollte ich auch erwähnen, dass Sie, wenn Sie Zeiger verwenden, entweder auf ihre Gültigkeit prüfen und den Fall behandeln müssen, wenn sie nicht gültig sind, oder einfach davon ausgehen, dass sie gültig sind und die Tatsache akzeptieren, dass Ihre Zeiger gültig sind Programm wird abstürzen oder schlimmer, wenn diese Annahme gebrochen ist. Anders ausgedrückt: Ihre Wahl bei Zeigern besteht darin, entweder Code-Komplexität einzuführen oder mehr Wartungsaufwand zu betreiben, wenn etwas kaputt geht und Sie versuchen, einen Fehler zu finden, der zu einer ganzen Klasse von Fehlern gehört, die Zeiger einführen. wie Speicherbeschädigung.

Wenn Sie also Ihren gesamten Code kontrollieren, halten Sie sich von Zeigern fern und verwenden Sie stattdessen Verweise, um sie möglichst konstant zu halten. Dies zwingt Sie dazu, über die Lebensdauer Ihrer Objekte nachzudenken, und führt dazu, dass Ihr Code leichter zu verstehen ist.

Denken Sie nur an diesen Unterschied: Eine Referenz ist im Wesentlichen ein gültiger Zeiger. Ein Zeiger ist nicht immer gültig.

Also sage ich, dass es unmöglich ist, eine ungültige Referenz zu erstellen? Nein, es ist absolut möglich, denn mit C++ können Sie fast alles tun. Es ist nur schwieriger, es ungewollt zu tun, und Sie werden erstaunt sein, wie viele Fehler ungewollt sind :)

21
Carl

Hier ist eine etwas andere, aber aufschlussreiche Darstellung, warum viele Funktionen von C sinnvoll sind: http://steve.yegge.googlepages.com/tour-de-babel#C

Grundsätzlich handelt es sich bei der Standard-CPU-Architektur um eine Von-Neumann-Architektur, und es ist äußerst nützlich, auf einer solchen Maschine auf den Speicherort eines Datenelements verweisen und mit diesem rechnen zu können. Wenn Sie eine Variante der Assemblersprache kennen, werden Sie schnell erkennen, wie wichtig dies auf der niedrigen Ebene ist.

C++ macht Zeiger etwas verwirrend, da es sie manchmal für Sie verwaltet und ihre Wirkung in Form von "Referenzen" verbirgt. Wenn Sie gerade C verwenden, ist die Notwendigkeit von Zeigern viel offensichtlicher: Es gibt keine andere Möglichkeit, Call-by-Reference durchzuführen, es ist die beste Möglichkeit, eine Zeichenfolge zu speichern, es ist die beste Möglichkeit, ein Array zu durchlaufen usw.

13
Dan Lenski

Ein Verwendungszweck von Zeigern (ich werde nicht auf Dinge eingehen, die bereits in den Posts anderer Leute behandelt wurden) ist der Zugriff auf Speicher, den Sie nicht zugewiesen haben. Dies ist für die PC-Programmierung nicht besonders nützlich, wird jedoch bei der eingebetteten Programmierung verwendet, um auf speicherzugeordnete Hardwaregeräte zuzugreifen.

Früher war es unter DOS möglich, direkt auf den Grafikspeicher der Grafikkarte zuzugreifen, indem Sie einen Zeiger auf Folgendes deklarieren:

unsigned char *pVideoMemory = (unsigned char *)0xA0000000;

Viele eingebettete Geräte verwenden diese Technik noch.

11
MrZebra

Zeiger sind größtenteils Arrays (in C/C++) - sie sind Adressen im Speicher und können wie ein Array aufgerufen werden, wenn dies gewünscht wird (in "normalen" Fällen).

Da sie die Adresse eines Elements sind, sind sie klein: Sie belegen nur den Platz einer Adresse. Da sie klein sind, ist es günstig, sie an eine Veranstaltung zu senden. Und dann lassen sie diese Funktion auf das eigentliche Objekt anstatt auf eine Kopie wirken.

Wenn Sie eine dynamische Speicherzuweisung durchführen möchten (z. B. für eine verknüpfte Liste), müssen Sie Zeiger verwenden, da dies die einzige Möglichkeit ist, Speicher aus dem Heap zu holen.

10
warren

Zeiger sind in vielen Datenstrukturen wichtig, deren Entwurf die Fähigkeit erfordert, einen "Knoten" effizient mit einem anderen zu verknüpfen oder zu verketten. Sie würden nicht einen Zeiger über einen normalen Datentyp wie float "wählen", sie haben einfach unterschiedliche Zwecke.

Zeiger sind nützlich, wenn Sie eine hohe Leistung und/oder einen kompakten Speicherbedarf benötigen.

Die Adresse des ersten Elements in Ihrem Array kann einem Zeiger zugewiesen werden. Auf diese Weise können Sie direkt auf die zugrunde liegenden zugewiesenen Bytes zugreifen. Der springende Punkt eines Arrays ist jedoch, zu vermeiden, dass Sie dies tun müssen.

9
Ash

Eine Möglichkeit, Zeiger über Variablen zu verwenden, besteht darin, den erforderlichen doppelten Speicher zu beseitigen. Wenn Sie beispielsweise ein großes komplexes Objekt haben, können Sie einen Zeiger verwenden, um für jede Referenz, die Sie erstellen, auf diese Variable zu verweisen. Bei einer Variablen müssen Sie den Speicher für jede Kopie duplizieren.

9
Jason

Weil das Kopieren großer Objekte überall Zeit und Gedächtnis kostet.

5
Andrew Medico

Wenn Sie in C++ den Subtyp Polymorphismus verwenden möchten, müssen Sie have Zeiger verwenden . Siehe diesen Beitrag: C++ - Polymorphismus ohne Zeiger .

Wirklich, wenn Sie darüber nachdenken, ist dies sinnvoll. Wenn Sie den Subtyp-Polymorphismus verwenden, wissen Sie letztendlich nicht im Voraus, welche Klassen- oder Unterklassenimplementierung der Methode aufgerufen wird, da Sie die tatsächliche Klasse nicht kennen.

Diese Idee, eine Variable zu haben, die ein Objekt einer unbekannten Klasse enthält, ist nicht kompatibel mit C++ 's Standardmodus (ohne Zeiger) zum Speichern von Objekten auf dem Stapel, bei dem der zugewiesene Speicherplatz direkt der Klasse entspricht. Hinweis: Wenn eine Klasse 5 Instanzfelder gegenüber 3 enthält, muss mehr Speicherplatz zugewiesen werden.


5
Sildoreth

Hier ist meine Antwort, und ich werde nicht versprechen, ein Experte zu sein, aber ich habe in einer meiner Bibliotheken, die ich zu schreiben versuche, Hinweise für großartig befunden. In dieser Bibliothek (es ist eine Grafik-API mit OpenGL :-)) können Sie ein Dreieck mit darin übergebenen Vertex-Objekten erstellen. Die Zeichenmethode nimmt diese Dreieckobjekte und zeichnet sie basierend auf den von mir erstellten Scheitelpunktobjekten. Na ja, es geht.

Aber was ist, wenn ich eine Scheitelpunktkoordinate ändere? Verschieben Sie es oder etwas mit moveX () in der Vertex-Klasse? Nun, ok, jetzt muss ich das Dreieck aktualisieren, wodurch mehr Methoden und mehr Leistung verschwendet werden, da ich das Dreieck jedes Mal aktualisieren muss, wenn sich ein Scheitelpunkt bewegt. Immer noch keine große Sache, aber es ist nicht so toll.

Was ist, wenn ich ein Netz mit Tonnen von Eckpunkten und Tonnen von Dreiecken habe und das Netz rotiert und sich bewegt und so weiter? Ich muss jedes Dreieck aktualisieren, das diese Eckpunkte verwendet, und wahrscheinlich jedes Dreieck in der Szene, weil ich nicht weiß, welche welche Eckpunkte verwenden. Das ist enorm computerintensiv, und wenn ich mehrere Maschen auf einer Landschaft habe, oh Gott! Ich bin in Schwierigkeiten, weil ich jedes Dreieck und fast jeden Frame aktualisiere, weil sich diese Eckpunkte ständig ändern!

Mit Zeigern müssen Sie die Dreiecke nicht aktualisieren.

Wenn ich drei * Vertex-Objekte pro Dreieckklasse hätte, spare ich nicht nur Platz, weil eine Million Dreiecke nicht drei Vertex-Objekte haben, die selbst groß sind, sondern auch diese Zeiger zeigen immer auf die Vertices, für die sie bestimmt sind, egal Wie oft ändern sich die Eckpunkte? Da die Zeiger immer noch auf denselben Scheitelpunkt zeigen, ändern sich die Dreiecke nicht und der Aktualisierungsvorgang ist einfacher zu handhaben. Wenn ich Sie verwirren würde, würde ich es nicht bezweifeln, ich gebe nicht vor, ein Experte zu sein, sondern wirf nur meine zwei Cent in die Diskussion.

4
Jeremy Hahn

Die Notwendigkeit für Zeiger in C-Sprache wird beschrieben hier

Die Grundidee ist, dass viele Einschränkungen in der Sprache (wie die Verwendung von Arrays, Strings und das Ändern mehrerer Variablen in Funktionen) durch Manipulationen an den Speicherorten der Daten beseitigt werden können. Um diese Einschränkungen zu überwinden, wurden in C Zeiger eingeführt.

Darüber hinaus können Sie mithilfe von Zeigern Ihren Code schneller ausführen und Speicherplatz sparen, wenn Sie große Datentypen (z. B. eine Struktur mit vielen Feldern) an eine Funktion übergeben. Das Anfertigen einer Kopie solcher Datentypen vor dem Übergeben würde Zeit in Anspruch nehmen und Speicherplatz verbrauchen. Dies ist ein weiterer Grund, warum Programmierer Zeiger für große Datentypen bevorzugen.

PS: Eine ausführliche Erklärung mit Beispielcode finden Sie in Link angegeben .

4
vaibhav kumar

In Java und C # sind alle Objektreferenzen Zeiger. In c ++ haben Sie mehr Kontrolle darüber, wo Sie auf Zeiger zeigen. Denken Sie daran, dass mit großer Kraft große Verantwortung verbunden ist.

3
Marioh

In Bezug auf Ihre zweite Frage müssen Sie beim Programmieren im Allgemeinen keine Zeiger verwenden. Es gibt jedoch eine Ausnahme, und zwar dann, wenn Sie eine öffentliche API erstellen.

Das Problem mit C++ - Konstrukten, die normalerweise zum Ersetzen von Zeigern verwendet werden, hängt stark von dem verwendeten Toolset ab. Dies ist in Ordnung, wenn Sie über alle erforderlichen Steuerelemente für den Quellcode verfügen. Wenn Sie jedoch beispielsweise eine statische Bibliothek mit Visual Studio 2008 kompilieren Wenn Sie versuchen, es in einem Visual Studio 2010 zu verwenden, werden zahlreiche Linkerfehler angezeigt, da das neue Projekt mit einer neueren STL-Version verknüpft ist, die nicht abwärtskompatibel ist. Noch schlimmer wird es, wenn Sie eine DLL) kompilieren und eine Importbibliothek angeben, die die Benutzer in einem anderen Toolset verwenden, da in diesem Fall Ihr Programm früher oder später ohne ersichtlichen Grund abstürzt.

Wenn Sie also große Datenmengen von einer Bibliothek in eine andere verschieben möchten, können Sie der Funktion, die die Daten kopieren soll, einen Zeiger auf ein Array zuweisen, wenn Sie andere nicht zwingen möchten, dieselben Tools zu verwenden, die Sie verwenden . Das Gute daran ist, dass es nicht einmal ein Array im C-Stil sein muss. Sie können einen std :: vector verwenden und den Zeiger angeben, indem Sie beispielsweise die Adresse des ersten Elements & vector [0] angeben und verwenden der std :: vector, um das Array intern zu verwalten.

Ein weiterer guter Grund für die erneute Verwendung von Zeigern in C++ sind Bibliotheken. Wenn Sie also eine Importbibliothek verwenden, ist die Abhängigkeit nicht erfüllt und das Programm stürzt ab. Dies ist beispielsweise der Fall, wenn Sie eine öffentliche API in einer DLL neben Ihrer Anwendung angeben und von anderen Anwendungen aus darauf zugreifen möchten. In diesem Fall müssen Sie zum Verwenden der API die DLL von ihrem Speicherort laden (normalerweise in einem Registrierungsschlüssel) und dann einen Funktionszeiger verwenden, um Funktionen innerhalb der DLL aufrufen zu können. Manchmal sind die Leute, die die API erstellen, nett genug, um Ihnen eine .h-Datei mit Hilfsfunktionen zur Automatisierung dieses Prozesses und allen benötigten Funktionszeigern zu geben. Andernfalls können Sie LoadLibrary und GetProcAddress für Windows und dlopen und verwenden Dlsym unter Unix, um sie zu erhalten (vorausgesetzt, Sie kennen die gesamte Signatur der Funktion).

1
Radu Chivu
  • In einigen Fällen sind Funktionszeiger erforderlich, um Funktionen in einer gemeinsam genutzten Bibliothek (.DLL oder .so) zu verwenden. Dies beinhaltet das Ausführen von Inhalten in verschiedenen Sprachen, wobei häufig eine DLL Schnittstelle bereitgestellt wird.
  • Compiler erstellen
  • Erstellen Sie wissenschaftliche Taschenrechner, in denen Sie ein Array oder eine Vektor- oder String-Map von Funktionszeigern haben?
  • Der Versuch, den Videospeicher direkt zu ändern - Erstellen Sie Ihr eigenes Grafikpaket
  • API erstellen!
  • Datenstrukturen - Knotenverknüpfungszeiger für spezielle Bäume, die Sie erstellen

Es gibt viele Gründe für Hinweise. Das Mangeln von C-Namen ist besonders in DLLs wichtig, wenn Sie die sprachübergreifende Kompatibilität aufrechterhalten möchten.

1
Jim Michaels