C-Funktionszeiger-Syntax

Lesezeit: 3 Minuten

Benutzeravatar von user1941583
Benutzer1941583

Wenn Sie eine Variable deklarieren, setzen Sie normalerweise ihren Typ davor, wie zum Beispiel:

int a;

Ein Funktionszeiger kann folgenden Typ haben: int(*)(int,int), falls wir auf eine Funktion zeigen, die zwei ganze Zahlen nimmt und eine ganze Zahl zurückgibt. Aber wenn ein solcher Zeiger deklariert wird, steht sein Bezeichner nicht nach dem Typ, wie:

int(*)(int,int) mypointer;

Stattdessen müssen Sie die Kennung in die Mitte schreiben:

int(*mypointer)(int,int);

Warum ist das so?

  • Das ist nicht der einzige Fall, Sie verwenden diesen Stil auch in Array-Deklarationen.

    – effe

    1. Januar 2013 um 22:18 Uhr

  • Suchen Sie nach “Deklaration spiegelt die Verwendung wider”.

    – Herr Lister

    1. Januar 2013 um 22:19 Uhr


  • Dieses Q hilft bei der Erklärung der Typedef-Syntax typedef old-type alias-identifier aber Beispiele für Funktionszeiger wie “typedef int (*sum_func)(int,int);” stimmt nicht mit der Syntax überein… Bis jetzt!

    – Kevin

    18. September 2018 um 0:11 Uhr


  • Weil die Sprache schlecht gestaltet ist. Das ist es!

    – iono

    26. Juli um 16:12 Uhr

Benutzeravatar von detly
dezent

Ich erkläre dies in meiner Antwort auf Warum wurde die C-Syntax für Arrays, Zeiger und Funktionen auf diese Weise entworfen?und es kommt im Wesentlichen darauf an:

Die Sprachautoren zogen es vor, die Syntax variablenzentriert statt typzentriert zu machen. Das heißt, sie wollten, dass ein Programmierer sich die Deklaration ansieht und denkt: „Wenn ich den Ausdruck schreibe *func(arg)das führt zu einem int; wenn ich schreibe *arg[N] Ich werde einen Schwimmer haben, anstatt “func muss ein Zeiger auf eine Funktion sein Dies und Rückkehr das“.

Das C-Eintrag auf Wikipedia behauptet, dass:

Ritchies Idee war es, Bezeichner in Kontexten zu deklarieren, die ihrer Verwendung ähneln: “Deklaration spiegelt die Verwendung wider”.

… unter Berufung auf Seite 122 von K&R2.

Diese Struktur spiegelt wider, wie eine normale Funktion deklariert (und verwendet) wird.

Betrachten Sie eine normale Funktionsdefinition:

int foo (int bar, int baz, int quux);

Erwägen Sie nun, einen Funktionszeiger auf eine Funktion mit derselben Signatur zu definieren:

int (*foo) (int, int, int);

Beachten Sie, wie sich die beiden Strukturen spiegeln? Das macht *foo viel einfacher als Funktionszeiger zu identifizieren als als etwas anderes.

Wenn Sie es mit einer Funktion zu tun haben (nicht mit einem Zeiger auf eine), steht der Name auch in der Mitte. Es geht so: return-type function-name "(" argument-list ")" .... Zum Beispiel im int foo(int), int ist der Rückgabetyp, foo der Name und int die Argumentliste.

Ein Zeiger auf eine Funktion funktioniert ziemlich genau so – gibt den Typ zurück, dann den Namen, dann die Argumentliste. In diesem Fall müssen wir a hinzufügen * um es zu einem Zeiger zu machen, und (seit dem * für einen Zeiger ist Präfix) ein Paar Klammern, um das zu binden * auf den Namen anstelle des Rückgabetyps. Zum Beispiel, int *foo(int) würde eine Funktion namens foo bedeuten, die einen int-Parameter akzeptiert und einen Zeiger auf ein int zurückgibt. Um den * gebunden zu bekommen foo Stattdessen brauchen wir Klammern, geben int (*foo)(int).

Dies wird besonders hässlich, wenn Sie ein Array von Zeigern auf Funktionen benötigen. In einem solchen Fall finden es die meisten Leute am einfachsten, eine Typedef für den Zeigertyp zu verwenden und dann ein Array dieses Typs zu erstellen:

typedef int (*fptr)(int);

fptr array[10];

Benutzeravatar von Vikas Kumar Sinha
Vikas Kumar Sinha

Ich hatte an einigen Stellen Funktionszeiger gesehen, die als deklariert waren

int (*foo) (int a, int b);

und an einigen Stellen a und b werden nicht erwähnt und beide funktionieren noch.

Also

int (*foo) (int, int)

ist auch richtig.

Ein sehr einfacher Weg, an den ich mich erinnern konnte, ist der folgende:

Angenommen, die Funktion ist deklariert als:

int function (int a , int b);

Schritt 1: Funktion einfach in Klammern setzen:

int (function) (int a , int b);

Schritt 2: Platzieren Sie a * vor dem Funktionsnamen und ändern Sie den Namen:

int (*funcPntr) (int a , int b);

PS: Ich befolge in dieser Antwort nicht die richtigen Codierungsrichtlinien für Namenskonventionen usw.

1412880cookie-checkC-Funktionszeiger-Syntax

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy