2012-06-06 11 views
8

Ich habe Schwierigkeiten zu verstehen, was die folgende Erklärung bedeutet. Ist diese Deklaration Standard?Was bedeutet double * (* p [3]) (void * (*)()); bedeuten?

double* (*p[3]) (void* (*)()); 

Kann mir jemand helfen, die Bedeutung dieser Erklärung zu verstehen?

+1

Ich bin froh, in der Java-Welt zu gehen ... –

+7

... im Gegensatz in der C-Welt zu laufen? ;-) –

+0

Oli Charlesworth lieferte eine allgemein nützliche Antwort. Schließ nicht. – DevSolar

Antwort

9

Regel für haarige Erklärungen zu lesen: die linke Kennung finden und arbeitet nach außen , erinnern, dass () und [] bind vor *, so T *a[N] ist ein Array von Zeigern auf T, T (*a)[N] ein Zeiger auf ein Feld von T ist, ist T *f() eine Funktion einen Zeiger auf T zurückkehrt, und T (*f)() ist ein Zeiger auf eine Funktion, die T zurückgibt. Da ein Funktionsprototyp Parameternamen auslassen kann, sehen Sie unter Umständen T *[N] oder T (*)(). Die Bedeutung ist meistens die gleiche , nur so tun, als ob es eine Kennung von 0 Länge ist.

So

  p      -- p 
      p[3]     -- is a 3-element array 
     *p[3]     -- of pointers 
     (*p[3]) (   ) -- to functions 
     (*p[3]) (  (*)()) -- taking a pointer to a function 
     (*p[3]) ( * (*)()) -- returning a pointer 
     (*p[3]) (void* (*)()) -- to void 
     * (*p[3]) (void* (*)()) -- returning a pointer 
double* (*p[3]) (void* (*)()); -- to double 

Die wichtige Sache weg hier zu nehmen ist, dass Sie p als Array von ..., keine Funktion ... Rückkehr deklarieren.

Wie würde solch ein Biest in der Praxis aussehen? Nun, zuerst brauchen Sie drei Funktionen, auf die Sie zeigen können.Jede dieser Funktionen nimmt einen einzigen Parameter, der ein Zeiger auf eine Funktion zurückgibt einen Zeiger auf void:

double *foo(void *(*)()); 
double *bar(void *(*)()); 
double *bletch(void *(*)()); 

double *(*p[3]) (void *(*)()) = {foo, bar, bletch}; 

Jede foo, bar und bletch nennen würde die Funktion an sie übergeben und irgendwie einen Zeiger auf double.

Sie würden wollen, auch eine oder mehr Funktionen definieren, die den Parametertyp für jeden foo erfüllen, bar und bletch:

void *blurga() {...} 

also, wenn Sie foo direkt genannt, können Sie es wie

nennen würden
double *pv; 
... 
pv = foo(blurga); 

So konnten wir einen Anruf wie

double *pv = (*p[0])(blurga); 
vorstellen


1 - der Unterschied ist, dass Erklärung im Zusammenhang mit der Funktionsparameter, T a[] und T a[N] identisch sind zu T *a; In allen drei Fällen ist a ein Zeiger aufT, kein Array von T. Beachten Sie, dass dies in einer Funktionsparameterdeklaration nur wahr ist. Somit ist T *[] identisch mit T **.

+0

vielen Dank! – Nick

10

Verwenden Sie einfach http://cdecl.org:

declare p als Array 3 von Zeiger auf Funktion (Zeiger auf Funktion Zeiger Rückkehr auf void) Zeiger Rückkehr

Für weitere Informationen zu verdoppeln finden Sie in diesem MSDN-Artikel : Interpreting more complex declarators.

Aber typedefs würde helfen:

typedef void *(*foo)();   // foo is a function-pointer type 
typedef double *(*bar)(foo); // bar is also a function-pointer type 
bar p[3]; 

(Offensichtlich, entsprechende Namen anstelle von foo und bar!)

+2

Ich habe diese Seite nie zuvor gesehen +1 –

+0

Beachten Sie, dass Sie auch 'Cdecl' als ein Befehlszeilenprogramm erhalten können . –

+1

+1 für die Verbindung der Quelle Ihrer Weisheit, anstatt es so aussehen zu lassen, als ob Sie es selbst heraufbeschworen hätten. ;-) – DevSolar

2

Ihre p ist ein Array von 3 Zeiger auf eine Funktion, eine double Rückkehr Zeiger, und als Argument einen Zeiger auf eine andere Funktion nehmen, die einen void Zeiger zurückgibt und der keine Argumente benötigt.

Aber verwenden diese Syntax nicht, versuchen Sie stattdessen mit typedef.

+0

+1, denn für mich ist es die klarste Beschreibung – Nick

+0

Ich auch, aber ich mag Olis Link, die "sprichwörtlich lehrte mich zu fischen" :) –

1

Es ist Array (der Größe 3) von Funktionszeigern, die Zeiger auf double zurückgibt und einen anderen Funktionszeiger als Argument verwendet.

Art der Funktion, deren Zeiger in dem Array gespeichert werden: double *(func)(void* (*)())
Art der Funktion, deren Zeiger als Argument func übergeben werden: void *(func1)(void)

+0

+1 weil dies ist die am leichtesten zu verstehende Beschreibung (für mich). – ArjunShankar