2016-10-21 23 views
5

Tôi vừa nhận thấy rằng việc biên dịch này không có bất kỳ lỗi hoặc cảnh báo nào bằng cách sử dụng -pedantic -Wall với cả hai gccclang.Chức năng làm tham số cho hàm

#include <stdio.h> 

int x = 0; 

void func(int f(const char *)) { 
    f("func()!"); 
} 

int main(void) { 
    func(puts); 
} 

Có vẻ như tham số f được coi như con trỏ đến hàm int (*)(const char *) trong trường hợp này.

Nhưng đây là một hành vi mà tôi chưa bao giờ thấy hoặc nghe thấy bất cứ điều gì về. Đây có phải là mã C hợp pháp không? Và nếu vậy thì điều gì xảy ra khi bạn có một hàm như một tham số cho một hàm?

+1

Con trỏ hàm là tham số hợp lệ, bạn có thể chuyển qua ví dụ các hàm gọi lại khác nhau với chúng. Hàm nhận được chúng, sau đó có thể gọi hàm đó, không có vấn đề ở đó. –

+1

Trong trường hợp này, kiểu tham số được viết dưới dạng "hàm" và không phải là "con trỏ trỏ đến hàm", trong trường hợp đó nó sẽ được khai báo 'int (* f) (const char *)' thay thế. – wefwefa3

+0

Đây là cú pháp đường và được phép khai báo dễ đọc hơn. Xem nhận xét đầu tiên cho câu trả lời được chấp nhận của câu hỏi trùng lặp. –

Trả lời

2

Được phép theo tiêu chuẩn. Từ C99 tiêu chuẩn chương 6.9.1 (lấy từ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf):

VÍ DỤ 2 Để vượt qua một chức năng khác, người ta có thể nói

int f(void); 
/*...*/ 
g(f); 

Sau đó, định nghĩa của g có thể đọc

void g(int (*funcp)(void)) 
{ 
    /*...*/ 
    (*funcp)(); /* or funcp(); ... */ 
} 

hoặc tương đương,

void g(int func(void)) 
{ 
    /*...*/ 
    func(); /* or (*func)(); ... */ 
} 
Các vấn đề liên quan