2013-04-17 16 views
12

Próbuję zrozumieć ten kod, który jest od Tcl documentationZrozumienie C typedef

typedef int Tcl_DriverOutputProc(
     ClientData instanceData, 
     const char *buf, 
     int toWrite, 
     int *errorCodePtr); 

Jak znam cel typedef jest przypisanie nazw alternatywnych do istniejących typów, więc dlaczego jest potrzebna do typedef int do funkcji? Jak można tego użyć?

+0

To służy do deklarowania [wskaźników funkcji] (http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work) w TCL_CHANNELTYPE – alexrider

+0

Co myślisz this (typedef int (* hello) (void);)? – MYMNeo

Odpowiedz

16

Wiem celem typedef jest przypisanie nazw alternatywnych do istniejących typów

Dokładnie. Funkcje mają typy, a to przypisuje nazwę Tcl_DriverOutputProc do tego typu funkcji. Typ sama funkcja jest napisane jak funkcja o nazwie brakującego:

int(ClientData, const char *, int, int *) 

i, podobnie jak w przypadku deklaracji funkcji, można dołączyć do nazwy parametrów, albo zostawić je, jak wybrać.

Jak to może być wykorzystane?

można wykorzystywać wskaźniki do funkcji w celu określenia zachowań w czasie wykonywania; na przykład:

typedef void function(); 
void hello() {printf("Hello\n");} 
void goodbye() {printf("Goodbye\n");} 

int main() { 
    function * pf = hello; 
    pf(); // prints "Hello" 
    pf = goodbye; 
    pg(); // prints "Goodbye" 
} 

W tym przypadku, pozwala napisać funkcję do obsługi jakiś aspekt produkcji TCL i powiedzieć TCL używać tej funkcji.

+0

Wow, nie wiedziałem, że można wprowadzić typedef dla rzeczywistego typu funkcji (w przeciwieństwie do typowego wskaźnika typ-funkcja) w * C *. Ale domyślam się, że jedynym możliwym przypadkiem użycia w * C * jest rzeczywiście utworzenie zmiennych wskaźnikowych (a zatem zwykłym sposobem jest typowanie typu wskaźnika w pierwszej kolejności). Ale nadal miło wiedzieć. –

+2

@ ChristianRau: Możesz także użyć funkcji typedef, aby zadeklarować funkcję, chociaż nadal potrzebujesz składni normalnej deklaracji funkcji podczas jej definiowania; a w funkcjach C++ często używane są jako argumenty szablonu (np. 'std :: function '). –

+0

Tak, na koniec * C++ * w ogóle znacznie wykorzystuje * typy *, czy to przeciążanie, szablony, ...I myślałem, że ta * składnia funkcji * jest nowością * C++ 11 *, wprowadzoną z myślą o takich rzeczach jak 'std :: result_of' i' std :: function'. Jeszcze kilka rzeczy do nauczenia się o stare dobre * C * dzisiaj;) –

0

Składnia typedefs dla typów funkcji jest dziwna - nazwa typu, którą tworzysz, pojawia się w środku. Jak już powiedział Mike Seymour, przypisuje ono nazwę Tcl_DriverOutputProc do typu funkcji int(ClientData, const char *, int, int *).

+2

Cóż, dziwne ... pojawia się dokładnie w tym samym miejscu, w którym nazwa funkcji pojawia się w deklaracji non-typedef. – Angew

3

typedef może być również stosowany do deklarowania funkcją powiedzieć „function_name” i jest „function_name” można zadeklarować inną funkcję o podobnym rodzaju i parametrów.

typedef function_name(int, int); 

function_name function1; 
function_name *function2; 

tu, w twoim przypadku oświadczenie typedef służy do uznającej funkcji „Tcl_DriverOutputProc”. I "Tcl_DriverOutputProc" jest używany w "struct Tcl_ChannelType" do deklarowania "* outputProc".

"struct Tcl_ChannelType" jest ostatnim z dokumentacji Tcl.

typedef struct Tcl_ChannelType { 
    const char *typeName; 
    Tcl_ChannelTypeVersion version; 
    Tcl_ DriverCloseProc *closeProc; 
    Tcl_DriverInputProc *inputProc; 
    Tcl_DriverOutputProc *outputProc; // <-- DriverOutputproc is used here. 
    Tcl_DriverSeekProc *seekProc; 
    Tcl_DriverSetOptionProc *setOptionProc; 
    Tcl_DriverGetOptionProc *getOptionProc; 
    Tcl_DriverWatchProc *watchProc; 
    Tcl_DriverGetHandleProc *getHandleProc; 
    Tcl_DriverClose2Proc *close2Proc; 
    Tcl_DriverBlockModeProc *blockModeProc; 
    Tcl_DriverFlushProc *flushProc; 
    Tcl_DriverHandlerProc *handlerProc; 
    Tcl_DriverTruncateProc *truncateProc; 
}Tcl_ChannelType;