2012-02-04 44 views
6

Trong khi nghe qua khóa học Programming Abstractions của Stanford, tôi bắt gặp một đoạn mã trông giống như sau.chức năng như tham số vs con trỏ hàm như tham số

void plot(double start, double end, double (fn)(double)) { 
    double i; 
    for (i = start; i <= end; i += 1) 
     printf("fn(%f) = %f\n", i, fn(i)); 
} 

double plus1(double x) { 
    return x + 1; 
} 

int main(void) { 
    plot(1, 10, plus1); 
    return 0; 
} 

Tôi đã biên dịch mã trên hệ thống của mình bằng GCC, sau đó là G ++; cả hai đều chạy hoàn hảo.

Tôi biết rằng đi qua một int i = 2 vào một chức năng như void func1(int a) sẽ tạo một bản sao mới của i đó cho chức năng đó trong khi đi &i để void func2(int *a) sẽ chỉ cung cấp cho các chức năng func2 địa chỉ của i.

Vì vậy, bất cứ ai cũng có thể giải thích cho tôi cơ chế để vượt qua fn đến plot và cách nó khác với truyền con trỏ hàm làm tham số?

Trả lời

7

Hoàn toàn không có sự khác biệt giữa void foo(double fn(double))void foo(double (*fn)(double)). Cả hai hàm khai báo đưa một con trỏ tới một hàm như một tham số.

Điều này tương tự như cách không có sự khác biệt giữa void bar(double arr[10])void bar(double* arr).

+0

Bạn có một tài liệu tham khảo cho tuyên bố thứ hai của bạn liên quan đến mảng? Đặc biệt khi đó là C++? – krlmlr

+0

Có một chút khác biệt, trước đây, 'fn' được ngụ ý là một con trỏ trỏ đến hàm, và trong' fn' sau đó được khai báo một cách rõ ràng đến hàm –

+3

@ user946850: '§8.3.5/5': ... Sau xác định loại của mỗi tham số, bất kỳ tham số nào của kiểu “mảng T” hoặc “hàm trả về T” được điều chỉnh là “con trỏ đến T” hoặc “con trỏ tới hàm trả về T” tương ứng. ... – Mankarse

0

xin lỗi vì lỗi của tôi.

void foo(int (fn)(int)){} 
void bar(int (*fn)(int)){} 

biên dịch trên mã như thế này:

gcc -S sample.c

bạn sẽ thấy rằng không có sự khác biệt. chỉ là kiểu mã hóa khác nhau.

bạn có thể thử để biên dịch và chạy mã này cũng như:

#include <stdio.h> 
void foo(int (fn)(int)) 
{ 
    printf("foo: %x.\n",fn); 
} 
void bar(int (*fn)(int)) 
{ 
    printf("bar: %x.\n",fn); 
} 
int main(int argc) 
{ 
    foo(main); 
    bar(main); 
    return 0; 
} 
+0

Vui lòng đọc lại câu hỏi của tôi. Tôi đã yêu cầu sự khác biệt giữa một con trỏ hàm trong một danh sách tham số và một mẫu thử nghiệm hàm trong một danh sách tham số. – MrOrdinaire

+0

lỗi của tôi. Tôi đã viết một câu trả lời mới. – for1096

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