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!
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“.
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];
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.
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