2015-02-27 16 views
14

Czy ktoś może wyjaśnić, co to jest int ((*foo(int)))(int)?Co oznacza ta deklaracja funkcji dziwnej funkcji w C?

int (*fooptr)(int); 
int ((*foo(int)))(int); // Can't understand what this does. 

int main() 
{ 
    fooptr = foo(0); 
    fooptr(10); 
} 

.

+1

Ponieważ nikt o tym nie wspomniał, http://c-faq.com/decl/spiral.anderson.html. Zapamiętywanie niektórych prostych zasad pozwala łatwo rozwikłać każdą deklarację. – chris

+2

@chris; Nie uniwersalna zasada. W niektórych przypadkach nie działa. – haccks

+0

@haccks: Nie mogę wymyślić przykładów, w których zawodzi z mojej głowy ... Czy mógłbyś rozwinąć? – wolfPack88

Odpowiedz

6

Według cdecl, foo jest:

deklaruje foo jako funkcja (int) powrót wskaźnika do funkcji (int) powrocie int

+3

Często widzę na SO, że łącze cdecl jest dostarczane w odpowiedziach jako rozwiązanie do wyjaśnienia złożonych deklaracji wskaźnika. Myślę, że to problem sam w sobie, a nie rozwiązanie. Programista C, C++ powinien zrozumieć podstawową logikę kryjącą się za złożoną deklaracją, a następnie po użyciu narzędzi takich jak cdecl. – haccks

+5

W przeciwnym razie, jeśli zamierzasz zakodować "int ((* foo (int))) (int)' możesz to skomentować lub skomponować z bardziej zrozumiałym typem. Gdybym zobaczył to w recenzji kodu, prawdopodobnie oskarżyłbym programistę o popisywanie się. Jeśli nie jest to oczywiste, popisywanie się w kodzie to Zła, Głupia Rzecz. – msw

36
int ((*foo(int)))(int); 

Ten deklaruje foo jako funkcja, która spodziewa argument typu int i zwraca wskaźnik do funkcji, która oczekuje argumentu typu int i zwraca wartość int.

Aby być bardziej jasne:

  foo       -- foo 
     foo( )      -- is a function 
     foo(int)       -- taking an int argument 
     *foo(int)       -- returning a pointer 
    (*foo(int))()      -- to a function that 
    (*foo(int))(int)      --  takes an int argument 
    int (*foo(int))(int)      --  and returning an int 

Here jest dobrym wytłumaczeniem dla tego samego.

+10

Albo ukraść notację z innej części świata, jest to funkcja 'int -> (int -> int)' – hobbs

+0

@hobbs; Dobry. Ale nie dla początkujących :) – haccks

12
foo 

jest tym, co deklarujemy.

foo(int) 

Jest to funkcja, która przyjmuje pojedynczy int argumentu

*foo(int) 

i zwraca wskaźnik

((*foo(int)))(int) 

do funkcji, która pobiera pojedynczy int argumentu

int ((*foo(int)))(int) 

i zwraca wartość int.

Jedna para () jest zbędna. To samo można wyrazić jako

8

Odpowiedzi już na to, ale chciałem podejść do tego w odwrotny sposób.

Deklaracja funkcji wygląda tak samo jak deklaracja zmiennej, z tym że nazwa zmiennej jest zamieniana przez nazwę funkcji i parametry.

Więc ta deklaruje bar jako wskaźnik do funkcji, która zajmuje się int i zwraca int:

int (*bar)(int); 

jeśli zamiast zmiennej bar, to funkcja foo(int) z tej wartości powrotnej, wymienić bar z foo(int) i otrzymujemy:

int (*foo(int))(int); 
// ^^^^^^^^ 
// this was "bar" before 

Dodaj niepotrzebnego parę nawiasów i masz:

int ((*foo(int)))(int); 
// ^  ^
// extra parentheses