2010-02-12 31 views
5

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.

+1

Welche Sprache ist das überhaupt? C++? –

+1

Ich vermutete, dass es C ist und markierte es so. –

+0

wow, das ist ziemlich sadistisch ... –

Antwort

19

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 
+6

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

+0

tatsächlich denke ich, dass die Parameter unspezifiziert sind, vorausgesetzt, das ist C. "(void)" würde keine Parameter akzeptieren, wie "()" in C++. – aib

0
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).

7

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 
+11

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

+1

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

2

Hmmm ... nach cdecl.org, die einen Syntaxfehler war - mir

 
int * (*) (int *,int *(*)()) 
  • (int * versuchen lassen, int ()()) - innerste (*)() - ein Zeiger auf Funktion int ()() - poi nter, um ohne Parameter zu arbeiten, Rückgabe Zeiger auf int
  • (int *, ...) - zwei Parameter, die eine ist ein Zeiger auf int, und die andere ist Zeiger-auf-Funktion-ohne-Parameter- returning-pointer-to-int
  • (*) (...) - ein Funktionszeiger mit den Parametern
  • int * (*) (...) - ein Funktionszeiger-Rückkehrzeiger-zu- 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.

1

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:

  • Wenn Sie das Attribut „()“ Verwendung Stichwort „Funktion, die zurückgibt“ sehen
  • Wenn Sie das Attribut finden Sie unter „[n]“ Verwendung Stichwort "Array von n"
  • Wenn Sie das Attribut "*" Keyword-Verwendung siehe "Zeiger auf"

Jetzt ist hier die "rechts-links-Regel":

  1. Beginnen Sie mit der Kennung.
  2. Suchen Sie nach einem Attribut nach rechts.
  3. Wenn keine gefunden wird, schauen Sie nach links.
  4. Sobald ein Attribut gefunden wird, ersetzen Sie das englische Schlüsselwort.
  5. Setzen Sie die Rechts-Links-Auswechslungen fort, während Sie Ihren Weg nach draußen gehen.
  6. Halten Sie an, wenn Sie den Datentyp in der Deklaration erreicht haben.

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.

0

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.

Verwandte Themen