2013-04-17 27 views
12

Tôi cố gắng để hiểu mã này đó là từ Tcl documentationHiểu C typedef

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

Như tôi đã biết mục đích của typedef là gán tên thay thế cho các loại hiện có, vậy tại sao là cần thiết để typedef int để chức năng? Làm thế nào điều này có thể được sử dụng?

+0

Nó được sử dụng để khai báo [con trỏ chức năng] (http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work) trong TCL_CHANNELTYPE – alexrider

+0

Bạn nghĩ gì về này (typedef int (* hello) (void);)? – MYMNeo

Trả lời

16

Tôi biết mục đích của typedef là gán tên thay thế cho các loại hiện có

Chính xác. Các hàm có kiểu, và điều này gán tên Tcl_DriverOutputProc cho kiểu hàm này. Bản thân loại chức năng được viết giống như một hàm có tên bị thiếu:

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

và, như với khai báo chức năng, bạn có thể bao gồm tên cho tham số, hoặc để chúng ra, như bạn chọn.

Cách này có thể được sử dụng?

Bạn có thể sử dụng con trỏ tới các hàm để chỉ định hành vi tại thời gian chạy; ví dụ:

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

Trong trường hợp này, nó cho phép bạn viết hàm để xử lý một số khía cạnh của đầu ra TCL và yêu cầu TCL sử dụng chức năng đó.

+0

Wow, không biết bạn có thể làm cho một typedef cho một loại chức năng thực tế (trái ngược với typedef con trỏ-to-function phổ biến) trong * C *. Nhưng tôi đoán trường hợp sử dụng duy nhất có thể có trong * C * thực sự là tạo ra các biến con trỏ (và do đó cách thông thường là gõ vào kiểu con trỏ ở vị trí đầu tiên). Nhưng vẫn còn tốt đẹp để biết. –

+2

@ChristianRau: Bạn cũng có thể sử dụng hàm typedef để khai báo hàm, mặc dù bạn vẫn cần cú pháp khai báo hàm bình thường khi bạn định nghĩa nó; và trong các kiểu hàm C++ thường được sử dụng làm đối số mẫu (ví dụ: 'std :: function '). –

+0

Vâng, cuối cùng * C++ * sử dụng nhiều hơn * các loại * ở tất cả, có thể là quá tải, mẫu, ...Và tôi nghĩ rằng cú pháp * function-type * này là một novum của * C++ 11 *, được giới thiệu với những thứ như 'std :: result_of' và' std :: function' trong tâm trí. Vẫn còn một số điều cần tìm hiểu về cũ * C * ngày hôm nay;) –

0

Cú pháp của typedefs cho các loại chức năng là đáng sợ hơn - tên loại mà bạn đang tạo sẽ xuất hiện ở số giữa. Như Mike Seymour đã nói, điều này gán tên Tcl_DriverOutputProc cho loại chức năng int(ClientData, const char *, int, int *).

+2

Vâng, lạ ... nó xuất hiện ở chính xác cùng một nơi mà tên chức năng xuất hiện trong một tuyên bố không typedef. – Angew

3

typedef cũng có thể được sử dụng để khai báo một hàm nói "function_name" và "function_name" này có thể được sử dụng để khai báo một hàm khác có kiểu và tham số tương tự.

typedef function_name(int, int); 

function_name function1; 
function_name *function2; 

Ở đây, trong trường hợp của bạn, câu lệnh typedef được sử dụng để khai báo hàm "Tcl_DriverOutputProc". Và "Tcl_DriverOutputProc" được sử dụng trong "struct Tcl_ChannelType" để khai báo "* outputProc".

"struct Tcl_ChannelType" ở cuối tài liệu 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;