Tôi muốn tạo một hàm thực hiện một hàm được truyền theo tham số trên một tập hợp dữ liệu. Làm thế nào để bạn vượt qua một chức năng như một tham số trong C?Làm thế nào để bạn vượt qua một hàm như một tham số trong C?
Trả lời
Tuyên bố
Một nguyên mẫu cho một chức năng mà phải mất một tham số chức năng trông giống như sau:
void func (void (*f)(int));
này khẳng định rằng các tham số f
sẽ là một con trỏ đến một chức năng trong đó có một void
kiểu trả về và có một tham số int
. Các chức năng sau (print
) là một ví dụ của một hàm có thể được truyền cho func
như một tham số vì nó là loại thích hợp:
void print (int x) {
printf("%d\n", x);
}
Chức năng Gọi
Khi gọi một hàm với một chức năng tham số, giá trị được truyền phải là con trỏ tới hàm. Sử dụng tên của hàm (không có dấu ngoặc đơn) cho điều này:
func(print);
sẽ gọi func
, chuyển chức năng in cho nó.
Function Body
Như với bất kỳ tham số, func bây giờ có thể sử dụng tên của tham số trong các cơ quan chức năng để truy cập giá trị của tham số. Giả sử rằng hàm func sẽ áp dụng hàm được truyền cho các số 0-4. Xem xét, đầu tiên, những gì các vòng lặp sẽ trông như thế để gọi in trực tiếp:
for (int ctr = 0 ; ctr < 5 ; ctr++) {
print(ctr);
}
Kể từ func
's tuyên bố tham số nói rằng f
là tên cho một con trỏ đến các chức năng mong muốn, chúng ta nhớ lại lần đầu tiên rằng nếu f
là một con trỏ sau đó *f
là điều mà f
trỏ đến (tức là hàm print
trong trường hợp này). Kết quả là, chỉ thay thế mỗi lần xuất hiện in trong vòng lặp trên với *f
:
void func (void (*f)(int)) {
for (int ctr = 0 ; ctr < 5 ; ctr++) {
(*f)(ctr);
}
}
Từ http://math.hws.edu/bridgeman/courses/331/f05/handouts/c-c++-notes.html
Trong ví dụ mã đầu tiên và cuối cùng của bạn, * không bắt buộc. Cả định nghĩa tham số hàm và lệnh gọi hàm 'f' có thể lấy' f' giống như không có *. Nó có thể là một ý tưởng tốt để làm điều đó như bạn làm mặc dù, để làm cho nó rõ ràng rằng tham số f là một con trỏ hàm. Nhưng nó dễ bị tổn thương khá thường xuyên. – Gauthier
Xem [c99, 6.9.1§14] để biết các ví dụ. Cả hai đều chính xác tất nhiên, tôi chỉ muốn đề cập đến sự thay thế. – Gauthier
Thật sao? Câu trả lời được đánh giá cao nhất không tạo ra một tham chiếu đơn lẻ để sử dụng một 'typedef' cho các con trỏ hàm? Xin lỗi, phải bỏ phiếu xuống. –
Bạn cần phải vượt qua function pointer. Cú pháp hơi cồng kềnh, nhưng nó thực sự mạnh mẽ khi bạn làm quen với nó.
Câu hỏi này đã có câu trả lời cho việc xác định chức năng gợi ý, tuy nhiên họ có thể nhận được rất lộn xộn, đặc biệt là nếu bạn sẽ chuyển chúng xung quanh ứng dụng của bạn. Để tránh sự khó chịu này, tôi khuyên bạn nên gõ con trỏ hàm vào một cái gì đó dễ đọc hơn. Ví dụ.
typedef void (*functiontype)();
Khai báo hàm trả về void và không có đối số.Để tạo ra một con trỏ hàm để loại hình này bây giờ bạn có thể làm:
void dosomething() { }
functiontype func = &dosomething;
func();
Đối với một hàm trả về một giá trị int và mất một char bạn sẽ làm gì
typedef int (*functiontype2)(char);
và sử dụng nó
int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');
Có các thư viện có thể giúp chuyển các con trỏ hàm thành các loại có thể đọc được tốt đẹp. Thư viện boost function thật tuyệt vời và rất đáng để bạn nỗ lực!
boost::function<int (char a)> functiontype2;
đẹp hơn nhiều so với ở trên.
Nếu bạn muốn "biến một con trỏ hàm thành một loại", bạn không cần thư viện tăng. Chỉ cần sử dụng 'typedef'; nó đơn giản hơn và không yêu cầu thêm bất kỳ thư viện nào. – wizzwizz4
Vì C++ 11 bạn có thể sử dụng functional library để thực hiện việc này theo cách ngắn gọn và chung chung. Cú pháp là, ví dụ,
std::function<bool (int)>
nơi bool
là kiểu trả về đây của một hàm một đối số mà số đầu tiên là loại int
.
tôi đã bao gồm một chương trình ví dụ dưới đây:
// g++ test.cpp --std=c++11
#include <functional>
double Combiner(double a, double b, std::function<double (double,double)> func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
Đôi khi, tuy nhiên, nó là thuận tiện hơn để sử dụng một mẫu chức năng:
// g++ test.cpp --std=c++11
template<class T>
double Combiner(double a, double b, T func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
Câu hỏi là về C; C++ không áp dụng ở đây. –
Câu hỏi cho C++ (http://stackoverflow.com/questions/6339970/c-using-function-as-parameter) được nhắc đến ở đây, vì vậy tôi nghĩ câu trả lời này được đặt ra. –
đèo địa chỉ của một hàm như tham số khác chức năng như được hiển thị bên dưới
#include <stdio.h>
void print();
void execute(void());
int main()
{
execute(print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void f()) // receive address of print
{
f();
}
Ngoài ra chúng tôi có thể vượt qua chức năng như tham số sử dụng chức năng con trỏ
#include <stdio.h>
void print();
void execute(void (*f)());
int main()
{
execute(&print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void (*f)()) // receive address of print
{
f();
}
- 1. Làm thế nào để bạn vượt qua một Container.DataItem như một tham số?
- 2. Vượt qua một hàm làm tham số trong jQuery?
- 3. Làm thế nào để vượt qua một phương pháp học như một tham số trong Scala
- 4. Có thể vượt qua một lớp như một tham số cho một hàm trong C++?
- 5. Làm thế nào để vượt qua một tham chiếu thông qua một gói tham số?
- 6. Làm thế nào để vượt qua MethodName như tham số của một thủ tục trong VBNET
- 7. Vượt qua một hàm thành viên lớp như một tham số chức năng
- 8. Làm thế nào để bạn vượt qua một mảng :: ::?
- 9. Danh sách vượt qua C++ làm tham số cho hàm
- 10. vượt qua một loại như một tham số thuộc tính
- 11. Làm thế nào để vượt qua std :: bản đồ như một tham số constructor mặc định
- 12. Làm thế nào để vượt qua GridView như một ConverterParameter
- 13. Làm thế nào để bạn vượt qua các đối số từ một hàm này sang hàm khác?
- 14. const char * như một tham số hàm trong C++
- 15. Làm thế nào để bạn vượt qua một mảng bằng cách tham chiếu trong Delphi?
- 16. Làm thế nào tôi có thể vượt qua một chức năng C thành viên ++ để một API C như một tham số
- 17. Làm thế nào để vượt qua một phương pháp tùy ý (hoặc ủy nhiệm) làm tham số cho một hàm?
- 18. C#: Làm thế nào để vượt qua null cho một hàm mong đợi một ref?
- 19. Làm thế nào để vượt qua ENUM làm đối số hàm trong C
- 20. Làm thế nào để vượt qua sự kiện dưới dạng tham số trong hàm JQuery
- 21. Làm thế nào để bạn vượt qua một con trỏ hàm thành viên?
- 22. Làm thế nào vượt qua một tham số để IN Operator trong NHibernate?
- 23. Làm thế nào để vượt qua một tập tin văn bản như một đối số?
- 24. Làm thế nào để vượt qua một tham số giữa hai hình thức trong Axapta?
- 25. làm thế nào để vượt qua danh sách như tham số trong chức năng
- 26. Làm thế nào để vượt qua một thành viên cấu trúc như một con trỏ trong một hàm
- 27. Làm thế nào để vượt qua mảng như tham số trong phương thức java?
- 28. Trong C# 3.5, Làm thế nào để bạn vượt qua phương thức nào để gọi trên một đối tượng dưới dạng tham số
- 29. C++: Có tốt hơn để vượt qua một enum như một giá trị hoặc như một tham chiếu const?
- 30. Làm thế nào tôi có thể vượt qua một mảng const hoặc một mảng biến cho một hàm trong C?
Nếu bạn đang sử dụng chức năng/mảng như các biến, luôn luôn sử dụng 'typedef'. –
Chúng tôi gọi nó là [Hàm con trỏ] (http://en.wikipedia.org/wiki/Function_pointer#Example_in_C) – AminM
Tên hàm phải là một trình tìm kiếm hàm. Hầu hết mọi người học C bao gồm qsort sớm hay muộn mà thực hiện chính xác điều này? – mckenzm