2014-05-24 21 views
10

Tôi muốn hiểu sự khác biệt giữa 2 tờ khai, f1f2, dưới đây là những gì: Trong f1 Tôi tuyên bố tham số là một con trỏ đến một chức năng của loại void(), làm thế nào là f2 khai khác với f1 ? Các khai báo có tương đương không? Trong main Tôi có thể gọi cả hai người trong số họ với các chức năng của nguyên mẫu void(). Tôi hiểu khái niệm truyền theo giá trị/con trỏ/tham chiếu, tuy nhiên đây là các hàm và không thực sự hiểu sự khác biệt. Nó không giống như tôi có thể "sửa đổi" các chức năng thông qua như tham số trong f1 ... Cảm ơn!Con trỏ để tham số chức năng tham số vs chức năng?

PS: đi ngang qua câu hỏi này khi chạm vào vấn đề gây nhiều tranh cãi Hầu hết Parsing nổi tiếng :)

#include <iostream> 

using namespace std; 

void f1(void (*x)()) 
{ 
    x(); 
} 

void f2(void x()) 
{ 
    x(); 
} 

void g1() 
{ 
    cout << "Invoking f1(g1())" << endl; 
} 

void g2() 
{ 
    cout << "Invoking f2(g2())" << endl; 
} 


int main() 
{ 
    f1(g1); 
    f2(g2); 
} 

Chương trình biên dịch và đầu ra là

Invoking f1(g1()) 
Invoking f2(g2()) 
+0

Cảm ơn tất cả, đã nhận nó :) – vsoftco

Trả lời

7

Họ tương đương. Bạn đang bị lẫn lộn bởi chuyển đổi con trỏ tiềm ẩn xảy ra với các đối số.

Vì bạn không thể chuyển hàm thành đối số cho hàm (bạn không thể làm bất cứ điều gì với hàm trong C ngoài gọi hoặc lấy địa chỉ của chúng), trình biên dịch sẽ thay đổi đối số thành con trỏ thành chức năng. Điều này cũng giống như xảy ra với mảng - bạn không thể vượt qua mảng như đối số chức năng, vì vậy bất cứ khi nào bạn khai báo một đối số hàm dưới dạng mảng, nó âm thầm được thay đổi thành một con trỏ.

+0

Ok, cảm ơn, biết đó là những gì đã xảy ra với mảng, tuy nhiên không biết về các công cụ chức năng. Rất cám ơn, sẽ chấp nhận câu trả lời của bạn vì nó nhanh hơn một chút :) – vsoftco

2

Chúng là cú pháp thay thế cho cùng một điều. Trong cả hai trường hợp, một con trỏ hàm được truyền, nhưng bạn được phép sử dụng cú pháp không trỏ trong danh sách tham số. Sử dụng tên hàm luôn phân rã thành con trỏ để hoạt động (và điều này có thể xảy ra đệ quy).

13

Trong cả C và C++, nếu bạn khai báo tham số hàm để có loại hàm, loại của nó sẽ được điều chỉnh thành con trỏ hàm.

C99, §6.7.5.3/8

Một tuyên bố của một tham số là '' chức năng trở về gõ '' sẽ được điều chỉnh để '' con trỏ đến chức năng trở về gõ '', như trong 6.3. 2.1.

C++ 11, §8.3.5/5

... Sau xác định kiểu của mỗi tham số, bất kỳ tham số có kiểu “mảng của T” hay “chức năng trở về T” là điều chỉnh là “con trỏ đến T” hay “con trỏ đến hoạt động trở lại T,” tương ứng ...

như vậy, trong C++, ví dụ, chúng ta có thể viết các loại của cả hai f1f2 như void(void(*)()).

+0

Cảm ơn bạn đã chỉ ra đoạn quan trọng từ tiêu chuẩn! – vsoftco

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