2012-01-04 49 views
5

Làm thế nào để khai báo một con trỏ tới một hàm trả về một con trỏ hàm khác? Vui lòng chia sẻ với tôi cú pháp và đoạn mã ví dụ.Cú pháp cho một con trỏ tới một hàm trả về một con trỏ hàm trong C

Ngoài ra, trong trường hợp nào một con trỏ hàm sẽ trả về một con trỏ hàm được sử dụng?

+3

Xin đừng thêm tên của bạn ở cuối của các bài đăng vì chữ ký của bạn sẽ tự động xuất hiện ở cuối bài đăng! http://stackoverflow.com/faq#signatures –

+0

Tôi đã tinh chỉnh tiêu đề và văn bản của bạn nhằm nỗ lực làm cho chúng dễ hiểu hơn. Dĩ nhiên, bạn có thể tự do chuyển đổi lại nếu bạn không thích những thay đổi này, nhưng tôi khuyên bạn nên xem xét sự khác biệt một cách cẩn thận vì nó có thể làm rõ vấn đề một chút. – dmckee

Trả lời

9

Đây là tầm thường với typedefs:

typedef int(*FP0)(void); 
typedef FP0(*FP1)(void); 

FP1 là kiểu của một con trỏ tới một hàm trả về một con trỏ hàm kiểu FP0.

Vì khi điều này hữu ích, tốt, rất hữu ích nếu bạn có hàm trả về một con trỏ hàm và bạn cần lấy hoặc lưu con trỏ vào hàm này.

+0

tuyên bố là tốt, nhưng bạn có thể cho tôi một đoạn mã trong đó sử dụng con trỏ hàm và trả về một con trỏ chức năng. điều đó sẽ giúp ích cho tôi để hiểu rõ ràng. Ngoài ra, hãy cho tôi cú pháp và với typedef .. – vijayanand1231

+0

Typedefs không phải lúc nào cũng khả thi. I E. khi bạn không có trình biên dịch thực hiện các biệt hiệu mẫu, và bạn muốn trả về một con trỏ hàm từ một khuôn mẫu _function_, và chữ ký trả lại phụ thuộc vào một đối số mẫu. (Bạn có thể 'làm việc xung quanh nó' bằng cách sử dụng 'đặc điểm kiểu danh tính') – sehe

+0

PS. Hoặc tất nhiên, kiểu trả về cuối C++ 11 :) 'template <...> auto foo() -> int (*) (void)' sẽ hoạt động tốt – sehe

5

Nếu bạn tránh sử dụng typedef, thật khó. Ví dụ, hãy xem xét signal() từ tiêu chuẩn C:

extern void (*signal(int, void (*)(int)))(int); 

void handler(int signum) 
{ 
    ... 
} 

if (signal(SIGINT, SIG_IGN) != SIG_IGN) 
    signal(SIGINT, handler); 

Sử dụng typedefs, nó là dễ dàng hơn:

typedef void Handler(int); 
extern Handler *signal(int, Handler *); 

void handler(int signum) 
{ 
    ... 
} 

if (signal(SIGINT, SIG_IGN) != SIG_IGN) 
    signal(SIGINT, handler); 

Lưu ý rằng đối với signal() chức năng, bạn sẽ thường chỉ cần sử dụng <signal.h> và để cho những lo lắng hệ thống về tuyên bố nó.

+1

Trong ví dụ typedef của bạn, không nên sử dụng Handler (* Handler), và sau đó tín hiệu như extern Handler tín hiệu (int, Handler)? Cú pháp con trỏ hàm trong C là một mớ hỗn độn, IMHO, nó có hai cú pháp riêng biệt hoạt động giống hệt nhau. – Spidey

+1

@Spidey: những gì bạn đề xuất là cách điển hình hơn để làm điều đó, có thể, nhưng điều đó cũng được hiển thị hoạt động chính xác. Ưu điểm là bạn có thể thấy con trỏ trong các khai báo. Cả hai đều hoạt động. –

+0

Tuyệt. Điều rắc rối nhất của tôi là (chính == & chính) là đúng. Nó có thể như thế này cho khả năng tương thích với cơ sở mã cũ hơn, nhưng nếu tôi định nghĩa một tiêu chuẩn mã, đó sẽ là điểm đầu tiên mà tôi chắc chắn sẽ làm rõ ràng ký hiệu nào sẽ được sử dụng. – Spidey

1

Nếu bạn không muốn có một typedef thứ hai,

typedef float(*(*fptr_t)(int))(double) 

này có nghĩa là "declare fptr_t as pointer to function (int) returning pointer to function (double) returning float" (fptr_t: int → (double → float))

+0

Tuyên bố có vẻ tốt, nhưng không chắc chắn về việc gán và gọi funciton bằng cách sử dụng con trỏ này. Nó giống như con trỏ hàm bình thường gọi? Ngoài ra, xin vui lòng cho tôi một đoạn mã mà làm cho tôi để underst rất rõ ràng. – vijayanand1231

Các vấn đề liên quan