int * (*) (int *, int * (*)())Typ int * (*) (int *, int * (*)())
Ich möchte, was wissen Typ ist das? Kann jemand ein Beispiel für eine Deklaration geben, die diesen Typ verwendet?
jede Hilfe wäre toll.
danke.
int * (*) (int *, int * (*)())Typ int * (*) (int *, int * (*)())
Ich möchte, was wissen Typ ist das? Kann jemand ein Beispiel für eine Deklaration geben, die diesen Typ verwendet?
jede Hilfe wäre toll.
danke.
Es ist ein Zeiger auf Funktion, die int*
und akzeptiert int*
und Zeiger auf Funktion gibt, die int*
zurückgibt (und nimmt unbestimmte Anzahl von Parametern; siehe Kommentar).
#include <stdio.h>
static int a = 10;
int* f1() {
return &a;
}
static int b;
int* f2(int *j, int*(*f)()) {
b = *j + *f();
// this is just for demonstrational purpose, such usage
// of global variable makes this function not thread-safe
return &b;
}
int main(int argc, char *argv[]) {
int * (*ptr1)();
int * (*ptr2) (int * , int * (*)());
ptr1 = f1;
ptr2 = f2;
int i = 42;
int *pi = ptr2(&i, ptr1);
printf("%d\n", *pi);
return 0;
}
// prints 52
Genau da dies mit C markiert ist, akzeptiert es eine undefinierte Anzahl von Parametern. In C++ und leere Parameterliste bedeutet keine Parameter, in C müsste es (void) sein, um dies zu spezifizieren. Arcane aber wahr ;-) – Clifford
tatsächlich denke ich, dass die Parameter unspezifiziert sind, vorausgesetzt, das ist C. "(void)" würde keine Parameter akzeptieren, wie "()" in C++. – aib
typedef int* (*fptr)();
int* foo(int* p1, fptr p2);
Sie foo
in dieser Art setzen kann:
Einige Beispiele (sieht nicht sehr schön, ist es nur die genannte Erklärung enthalten, konstruiert).
cdecl
ist dein Freund:
$ cdecl explain 'int * (*x) (int * , int * (*)())'
declare x as pointer to function (pointer to int, pointer to function returning pointer to int) returning pointer to int
yeah, außer es funktioniert nicht, dass 'x' Sie hinzugefügt haben und wenn Sie die Aussage an erster Stelle verstehen, würden Sie nicht wissen, das' x' hinzuzufügen;) – ezpz
Wenn es keine Kennung (die leicht zu erkennen sein sollte), dann Sie können 'cdecl' erhalten, um es zu erklären, indem Sie ihm' '' 'voranstellen und mit' 'x' suffizitieren. Es sagt dann "' strecke x in ... '", gefolgt von der Erklärung des Typs. – caf
Hmmm ... nach cdecl.org, die einen Syntaxfehler war - mir
int * (*) (int *,int *(*)())
Also: Es ist ein funktions Zeiger, der die beiden Parameter hat, die der erste Parameter ein Zeiger auf int und die anderen Zeiger-zu-Funktion-with-no-Parameter-Rückkehr-pointer-to -int und its-returning-pointer-to-int.
Edit: Die C-Deklaration, die ich in dieser Website verwendet - ich nicht wie in
int *(*x)(int *,int *(*)())
die zurück in einem Variablennamen gesetzt hat: declare x als Zeiger auf Funktion (Zeiger auf int , Zeiger auf Funktion Rückkehr Zeiger auf int) Zeiger
hoffe, das hilft, Mit freundlichen Grüßen, Tom int zurück.
Es gibt eine Technik namens "Rechts-Links-Regel", mit der Sie komplexe Deklarationen wie diese entschlüsseln können. Die Regel funktioniert, indem die in der Deklaration angezeigten Attribute durch englische Schlüsselwörter ersetzt werden. Wenn Sie die Schlüsselwörter zusammenfügen, beschreibt der konstruierte Satz die Deklaration.
hier die Attribute und die Keywords, die Sie verwenden sollten:
Jetzt ist hier die "rechts-links-Regel":
Hier einige Beispiele:
int n[10];
Die Kennung n ist. Das Attribut auf der rechten Seite ist [10]
, verwenden Sie also das Schlüsselwort "Array of 10". Als nächstes erreichen Sie den Datentyp int
. Also,
n ist ein "Array von 10 ganzen Zahlen".
int *n[10];
Der Bezeichner ist n. Das Attribut auf der rechten Seite ist [10]
, verwenden Sie also das Schlüsselwort "Array of 10". Schau nach links und das Attribut ist *
, also benutze das Schlüsselwort "pointer to". Es gibt keine Attribute mehr. Alles, was übrig bleibt, ist der Datentyp int
. Setzen Sie die Schlüsselwörter zusammen, um zu erhalten:
n ist ein "Array von 10 Zeigern zu ganzen Zahlen".
int (*pf)();
Die Kennung ist pf. Es gibt kein Attribut direkt rechts von pf. Auf der linken Seite von pf ist *
. Also das erste Schlüsselwort ist "Zeiger auf". Als nächstes gehe zurück nach rechts und das Attribut ist ()
. Das bedeutet, das nächste Schlüsselwort ist "Funktion, die zurückkehrt". Jetzt gehe zurück nach links zum Datentyp int
. Setzen Sie die Schlüsselwörter zusammen zu bekommen:
pf ein „Zeiger auf eine Funktion, die einen int zurückgibt“ ist
int *(*pf)();
pf ist die Kennung. Es gibt keine Attribute rechts von pf. Auf der linken Seite ist *
, so das erste Schlüsselwort ist "Zeiger auf". Zurück nach rechts ist ()
, so das nächste Schlüsselwort ist "Funktion, die zurückkehrt". Zurück nach links ist *
, also das nächste Schlüsselwort ist "Zeiger auf". Als nächstes erreichen Sie den int
Datentyp:
pf ist ein "Zeiger auf eine Funktion, die einen Zeiger auf ein int zurückgibt".
Das nächste Beispiel ist genau wie das vorherige, aber dieses Mal gibt es einige Argumente für die PF-Funktion. Die Argumente sind int *x
und int *(*y)()
. Sie sollten in der Lage sein, jedes dieser Argumente basierend auf dem bisher Gesagten zu beschreiben. Und wenn Sie das tun Sie in der Lage sein werde, die ganze Sache zu beschreiben:
int *(*pf)(int *x, int *(*y)());
pf ist ein Zeiger auf eine Funktion, die einen Zeiger auf einen int zurückgibt. pf nimmt zwei Argumente. Das erste Argument x ist ein Zeiger auf einen int. Das zweite Argument y ist ein Zeiger auf eine Funktion, die einen Zeiger auf einen int zurückgibt.
Solche Deklarationen werden wirklich verwendet! Betrachten wir die Signalfunktion der Standard-C-Bibliothek:
void (*
signal(int sig, void (*func)(int)))(int);
das Signal Manpage erklärt es folgende typedef'd Version entspricht:
typedef void (*sig_t) (int);
sig_t signal(int sig, sig_t func);
Eine Funktion, die zwei Argumente nimmt und int und eine sig_t-Funktion, die die alte sig-Funktion zurückgibt.
Welche Sprache ist das überhaupt? C++? –
Ich vermutete, dass es C ist und markierte es so. –
wow, das ist ziemlich sadistisch ... –