2013-04-17 25 views
12

Ich versuche, diesen Code zu verstehen, die aus ist Tcl documentationVerständnis C typedef

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

Als ich den Zweck der typedef wissen, ist, alternative Namen zu bestehenden Typen zuzuordnen, also warum benötigt wird int Funktion typedef? Wie kann das genutzt werden?

+0

Es wird verwendet, um [Funktionszeiger] zu deklarieren (http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work) in TCL_CHANNELTYPE – alexrider

+0

Was halten Sie von das (typedef int (* hallo) (void);)? – MYMNeo

Antwort

16

Ich weiß, dass der Zweck der typedef ist zu den bestehenden Typen

alternative Namen zuweisen Genau. Funktionen haben Typen und weisen diesem Funktionstyp den Namen Tcl_DriverOutputProc zu. Der Funktionstyp selbst ist wie eine Funktion mit dem Namen geschrieben fehlt:

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

und wie bei einer Funktionsdeklaration können Sie Namen für die Parameter umfassen, oder lassen Sie sie heraus, wie Sie wählen.

Wie kann dies verwendet werden?

Sie können Zeiger auf Funktionen verwenden, um das Verhalten zur Laufzeit festzulegen. zum Beispiel:

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" 
} 

In diesem Fall erlaubt es Ihnen, eine Funktion zu schreiben, einige Aspekte von TCL Ausgabe zu handhaben, und TCL sagen, diese Funktion zu nutzen.

+0

Wow, ich wusste nicht, dass Sie einen Typdef für einen tatsächlichen Funktionstyp (im Gegensatz zu dem üblichen Zeiger-zu-Funktion typedef) in * C * machen können. Aber ich denke, der einzig mögliche Anwendungsfall in * C * ist in der Tat, Zeigervariablen zu erzeugen (und daher ist es üblich, den Zeigertyp an erster Stelle zu schreiben). Aber immer noch nett zu wissen. –

+2

@ChristianRau: Sie können auch eine Funktion typedef verwenden, um eine Funktion zu deklarieren, obwohl Sie bei der Definition die normale Funktionsdeklarationssyntax benötigen. und in C++ werden Funktionstypen oft als Vorlagenargumente verwendet (z.B. 'std :: function '). –

+0

Ja, am Ende macht * C++ * viel mehr Gebrauch von * Typen *, sei es Überladung, Vorlagen, ...Und ich dachte, diese * Funktionstyp-Syntax sei ein Novum von * C++ 11 *, eingeführt mit Dingen wie 'std :: result_of' und' std :: function'. Noch etwas zu lernen über gute alte * C * heute;) –

0

Die Syntax von typedefs für Funktionstypen ist wierd - der Typname, den Sie erstellen, erscheint in der Mitte. Wie Mike Seymour bereits sagte, weist dies dem Funktionstyp int(ClientData, const char *, int, int *) den Namen Tcl_DriverOutputProc zu.

+2

Nun, seltsam ... es erscheint genau an der gleichen Stelle, an der der Funktionsname in einer nicht-typedef-Deklaration erscheint. – Angew

3

typedef kann auch verwendet werden, um eine Funktion zu deklarieren, sagen wir "Funktionsname" und dieser "Funktionsname" kann verwendet werden, um eine andere Funktion mit ähnlichen Typen und Parametern zu deklarieren.

typedef function_name(int, int); 

function_name function1; 
function_name *function2; 

Hier In Ihrem Fall ist die typedef-Anweisung für die Deklaration „Tcl_DriverOutputProc“ -Funktion verwendet. Und "Tcl_DriverOutputProc" wird in "struct Tcl_ChannelType" verwendet, um "* outputProc" zu deklarieren.

"struct Tcl_ChannelType" ist in der letzten Tcl-Dokumentation.

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;