2009-11-06 15 views
10
void (*func)(int(*[ ])()); 
+0

Zobacz http: // stackoverflow.com/questions/1448849/jak-to-zrozumieć-skomplikowane-funkcje-deklaracje – pmg

Odpowiedz

5

Tak:

 
$ cdecl 
explain void (* x)(int (*[])()); 
declare x as pointer to function 
    (array of pointer to function returning int) returning void 
+0

Hah! Awesome! .. –

+0

Nie sądzę, że jest, cdecl po prostu nie lubi nazwy 'func'. – caf

+0

Nahhhh ... to błąd w cdecl :) – pmg

20

To nie jest stwierdzenie, że to oświadczenie.

Deklaruje func jako wskaźnik do funkcji powrocie nieważne i biorąc jeden argument typu int (*[])(), która sama jest wskaźnik do wskaźnika do funkcji powrocie int i przy stałej ale nieokreśloną liczbę argumentów.


wyjście cdecl dla małowierni:

cdecl> explain void (*f)(int(*[ ])()); 
declare f as pointer to function (array of pointer to function returning int) returning void 
+0

"ustalona ale nieokreślona liczba argumentów" - pytanie jest również oznaczone C++, w którym to przypadku drugi typ funkcji przyjmuje dokładnie zero argumentów. –

+3

Tag C++ został dodany przez kogoś innego niż oryginalny plakat, po tym jak odpowiedziałem. Posunięcie zbyt sprytne o połowę, według mojej książki. – caf

+0

Cholera, to jest podstępne. Nigdy nie jest jasne, czy ktoś mówi "C/C++", czy powiedzieli to, ponieważ uważają, że odpowiedź jest taka sama dla obu języków, ponieważ uważają, że odpowiedzi są różne między tymi dwoma ... –

2

void (*func)(blah); jest wskaźnikiem do funkcji biorąc blah jako argument, gdzie sama blah jest int(*[ ])() jest tablicą wskaźników funkcji.

31

Ogólna procedura czytania owłosione declarators jest znalezienie skrajnie lewą identyfikator i swój sposób pracy na zewnątrz, pamiętając, że [] i () wiążą przed * (tj , *a[] to tablica wskaźnika, a nie wskaźnik do tablicy). Sprawa ta jest nieco trudniejsza ze względu na brak identyfikatora na liście parametrów, ale ponownie, [] wiąże się przed *, więc wiemy, że *[] wskazuje na tablicę pozytów.

więc, biorąc pod uwagę

void (*func)(int(*[ ])()); 

łamiemy go w następujący sposób:

 func     -- func 
     *func     -- is a pointer 
    (*func)(   )  -- to a function taking 
    (*func)( [ ] )  -- an array 
    (*func)( *[ ] )  -- of pointers 
    (*func)( (*[ ])())  -- to functions taking 
           --  an unspecified number of parameters 
    (*func)(int(*[ ])())  -- returning int 
void (*func)(int(*[ ])()); -- and returning void 

Co to będzie wyglądać w praktyce byłoby coś jak poniżej:

/** 
* Define the functions that will be part of the function array 
*/ 
int foo() { int i; ...; return i; } 
int bar() { int j; ...; return j; } 
int baz() { int k; ...; return k; } 
/** 
* Define a function that takes the array of pointers to functions 
*/ 
void blurga(int (*fa[])()) 
{ 
    int i; 
    int x; 
    for (i = 0; fa[i] != NULL; i++) 
    { 
    x = fa[i](); /* or x = (*fa[i])(); */ 
    ... 
    } 
}  
... 
/** 
* Declare and initialize an array of pointers to functions returning int 
*/ 
int (*funcArray[])() = {foo, bar, baz, NULL}; 
/** 
* Declare our function pointer 
*/ 
void (*func)(int(*[ ])()); 
/** 
* Assign the function pointer 
*/ 
func = blurga; 
/** 
* Call the function "blurga" through the function pointer "func" 
*/ 
func(funcArray); /* or (*func)(funcArray); */ 
+1

+1 wystarczająco dobrze, spróbuj wyjaśnić, jak czytać takie wyrażenia i przykład. –

+0

+1, fajny :) –

+0

+1 dla parsowania bloku na początku. Miły! –

2

Geordi jest botem C++, pozwalającym na szkolenie:

<litb> geordi: {} void (*func)(int(*[ ])()); 
<litb> geordi: -r << ETYPE_DESC(func) 
<geordi> lvalue pointer to a function taking a pointer to a pointer to a nullary function 
     returning an integer and returning nothing 

Można zrobić wiele pożytecznych rzeczy, jak pokazano wszystkie parametrami deklaracji (ten, w rzeczywistości jest tylko dopasowania surowe C++ nazwy reguły gramatyki):

<litb> geordi: show parameter-declarations 
<geordi> `int(*[ ])()`. 

Zróbmy to w odwrotnym kierunku:

<litb> geordi: {} int func; 
<litb> geordi: make func a pointer to function returning void and taking array of pointer to 
     functions returning int 
<litb> geordi: show 
<geordi> {} void (* func)(int(*[])()); 

Wykonuje wszystko, co mu się podasz, jeśli o to poprosisz. Jeśli są szkoleni, ale po prostu zapomniałem niektóre z przerażających zasad nawiasach, można również mieszać C++ oraz opisy typu Geordi stylu:

<litb> geordi: make func a (function returning void and taking (int(*)()) []) * 
<geordi> {} void (* func)(int(*[])()); 

Miłej zabawy!

Powiązane problemy