2013-07-28 32 views
5

Mã này tôi đang sử dụng có tuyên bố này:Tuỳ chọn dấu hoa thị trong con trỏ hàm?

typedef void (udp_data_notify)(OS_FIFO * pfifo, WORD port); 

này trông giống như một lời tuyên bố của một con trỏ hàm cho udp_data_notify, tuy nhiên không có *. Nó vẫn có thể là con trỏ hàm không có dấu sao?

Đây là một tuyên bố rằng sử dụng udp_data_notify:

void RegisterUDPFifoWithNotify(WORD dp, OS_FIFO *pnewfifo , udp_data_notify * nudp) 

Bất kỳ sự giúp đỡ như những gì đang xảy ra sẽ được đánh giá!

+0

Dereferencing con trỏ hàm có thể tạo ra byte đầu tiên của lệnh mã máy đầu tiên của hàm. Câu hỏi lớn là những gì bạn muốn làm với điều đó một cách di động. –

+0

có thể trùng lặp của [typedef với dấu ngoặc đơn như "typedef int (f) (void)" có nghĩa là gì? Nó là một nguyên mẫu chức năng?] (http://stackoverflow.com/questions/3674200/what-does-a-typedef-with-parenthesis-like-typedef-int-fvoid-mean-is-it-a) –

Trả lời

0

typedef bạn hiển thị tuyên bố udp_data_notify làm bí danh cho loại chức năng. Sau đó khai báo tham số udp_data_notify *nudp khai báo nudp làm con trỏ đến hàm của loại đó. Không có cuộc gọi chức năng nào ở đây.

Liên quan đến toán tử gọi hàm (postfix ()), biểu thức chỉ định hàm được gọi phải là con trỏ đến hàm. Khi bạn gọi một hàm bình thường, không có con trỏ, chẳng hạn như sqrt(2), hàm sẽ tự động được chuyển đổi thành con trỏ cho bạn. Vì vậy, sqrt(2) thực sự là (&sqrt)(2). Khi bạn gọi một hàm với một con trỏ, cuộc gọi ở dạng đúng.

+0

Hàm được chuyển đổi thành con trỏ có hành vi C99 mới mà tôi tin. Trong C89 và K & R, với các hàm ẩn, dạng không được đặt dấu ngoặc đơn 'f()' cho các cuộc gọi hàm dường như thực sự là một trường hợp đặc biệt. Lưu ý rằng '(f)()' không hợp lệ nếu 'f' không được khai báo, ngay cả trong C89. –

4

Một typedef như:

typedef void name(int); 

(ngoặc xung quanh name là dư thừa) sẽ xác định name như loại một chức năng, không phải là một con trỏ hàm. Đó sẽ là:

typedef void (*pname)(int); 

Có thể bạn đang tự hỏi điều gì là tốt cho họ. Vâng, các loại chức năng không phải là rất hữu ích, khác hơn so với con trỏ tuyên bố:

name *pointer_to_function; 

Và đó có thể được thực hiện cho là dễ đọc hơn với typedef khác:

pname pointer_to_function; 

Đó là bởi vì bạn không thể xác định một biến loại hàm. Nếu bạn cố gắng, bạn sẽ chỉ cần viết nguyên mẫu của một hàm, nhưng trong một cú pháp khá khó hiểu:

name foo; //declaration (prototype), not variable 
void foo(int x) //definition 
{ 
} 

Nhưng lưu ý rằng bạn không thể sử dụng typedef để xác định các chức năng:

name foo {} //syntax error! 
+0

"các loại chức năng không phải là rất hữu ích? Có bất kỳ trường hợp nào trong đó nó hữu ích? – onmyway133

+1

@ onmyway133: Không phải là tôi biết. Trừ khi bạn đếm obfuscation là hữu ích. – rodrigo

+0

Tôi nghe nhiều người nói rằng" không khai báo "là tự động chuyển thành "khai báo dấu hoa thị", – onmyway133

3

Như đã đã nói, typedef khai báo một bí danh cho kiểu hàm. Khi bạn muốn sử dụng nó để khai báo một con trỏ hàm, dấu hoa thị là bắt buộc (udp_data_notify* x). Một tuyên bố không có dấu hoa thị (udp_data_notify x) sẽ là một khai báo hàm, ngoại trừ trong một trường hợp đặc biệt. Khi được sử dụng trong một tham số, một loại chức năng được tự động chuyển thành loại con trỏ chức năng tương ứng:

typedef void F(void); 
void foo(F a, F* b) // special case; a and b are both function pointers 
{ 
    F c; // function declaration 
    F* d; // function pointer 
} 
Các vấn đề liên quan