2013-06-04 23 views
32

Trong C/C++, nếu tôi có một chức năng sau:Đỗ chức năng con trỏ cần một dấu

void foo(); 
void bar(void (*funcPtr)()); 

Có một sự khác biệt giữa hai cuộc gọi sau đây:

bar(foo); 
bar(&foo); 

?

+6

Để thêm nhầm lẫn, 'bar (* foo);' cũng tương đương với cả hai. Và như vậy là 'bar (***** foo);'. –

+0

Tôi thích '& foo', bởi vì điều này làm cho nó rõ ràng rằng tôi muốn có một con trỏ hàm, và không chỉ quên gọi hàm. – sp2danny

Trả lời

33

Không, không có sự khác biệt, vì hàm có thể được chuyển đổi hoàn toàn thành con trỏ thành hàm. Trích dẫn có liên quan từ tiêu chuẩn (N3376 4.3/1).

Một giá trị của loại hàm T có thể được chuyển đổi thành giá trị của loại “con trỏ thành T.” Kết quả là con trỏ tới hàm .

8

Có một sự khác biệt giữa hai cuộc gọi sau đây:

Không, không có sự khác biệt.

-2

bar(foo); được gọi là phiên bản "ngắn"

bar(&foo); là cách nó được chính thức thực hiện

Về mặt chức năng, không có sự khác biệt, tuy nhiên các tùy chọn thứ hai được coi là "thực hành tốt" bởi hầu hết vì đó cách rõ ràng hơn là foo thực sự là một con trỏ hàm và không phải là một hàm thực tế.

Điều này tương tự như với mảng. Nếu bạn có:

int foobar[10]; 

sau đó foobar là một int *, nhưng bạn cũng có thể làm & foobar cho kết quả tương tự.

+10

Tôi không đồng ý với phần "foobar" của bạn. Được định nghĩa là 'int foobar [10];', 'foobar' là một' int [10] '(mảng 10 int) nhưng có thể được chuyển đổi thành _' int * '(con trỏ thành (int đầu tiên) int) khi cần thiết ("mảng phân rã"); cụ thể, 'sizeof foobar' bằng '10 * sizeof (int)', không phải 'sizeof (int *)'. Và một thứ khác, '& foobar' là một' int (*) [10] '(con trỏ tới mảng 10 ints), là một kiểu khác hoàn toàn (_not_ convertible thành' int * '). –

+3

Chỉnh sửa: Nhưng những gì bạn "có thể làm" là '& foobar [0]' (hoặc '& (foobar [0])'), trớ trêu thay, chỉ là cú pháp thuận tiện cho '& (* (foobar + 0)) ', tức là' foobar + 0', trong đó 'foobar' được chuyển đổi hoàn toàn thành con trỏ thành phần tử đầu tiên của nó ... –

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