2009-11-06 42 views
10
void (*func)(int(*[ ])()); 
+0

Xem http: // stackoverflow.com/questions/1448849/cách khai báo-phức tạp-chức năng-khai báo – pmg

Trả lời

5

Có:

 
$ cdecl 
explain void (* x)(int (*[])()); 
declare x as pointer to function 
    (array of pointer to function returning int) returning void 
+0

Hah! Tuyệt vời! .. –

+0

Tôi không nghĩ là vậy, cdecl không thích tên 'func'. – caf

+0

Nahhhh ... đó là một lỗi trong cdecl :) – pmg

20

Nó không phải là một tuyên bố, đó là một tuyên bố.

Nó tuyên bố func làm con trỏ đến hàm trả về void và lấy một đối số kiểu int (*[])(), mà chính nó là con trỏ trỏ tới hàm trả về int và lấy số đối số cố định nhưng không xác định.


đầu ra cdecl cho các ngươi ít đức tin:

cdecl> explain void (*f)(int(*[ ])()); 
declare f as pointer to function (array of pointer to function returning int) returning void 
+0

"cố định nhưng không xác định số đối số" - câu hỏi cũng được gắn thẻ C++, trong trường hợp đó loại chức năng thứ hai mất chính xác không đối số. –

+3

Thẻ C++ được thêm bởi một người nào đó không phải là poster gốc, sau khi tôi trả lời. Một sự chuyển động quá thông minh-by-một nửa, bởi cuốn sách của tôi. – caf

+0

Gosh, đó là lén lút. Nó không bao giờ rõ ràng khi ai đó nói "C/C++" cho dù họ đã nói nó bởi vì họ nghĩ rằng câu trả lời là như nhau cho cả hai ngôn ngữ, bởi vì họ nghĩ rằng câu trả lời là khác nhau giữa hai ... –

2

void (*func)(blah); là một con trỏ tới một hàm dùng blah như một cuộc tranh cãi, nơi blah chính nó là int(*[ ])() là một mảng của con trỏ hàm.

31

Thủ tục chung cho việc đọc declarators lông là để tìm ra định danh tận cùng bên trái và làm việc theo cách của bạn ra, nhớ rằng []() ràng buộc trước khi * (tức , *a[] là một mảng con trỏ, không phải là con trỏ tới mảng). Trường hợp này được thực hiện một chút khó khăn hơn do thiếu một số nhận dạng trong danh sách tham số, nhưng một lần nữa, [] liên kết trước *, vì vậy chúng tôi biết rằng *[] cho biết một loạt các nhà thơ.

Vì vậy, cho

void (*func)(int(*[ ])()); 

chúng ta phá vỡ nó xuống như sau:

 func     -- func 
     *func     -- is a pointer 
    (*func)(   )  -- to a function taking 
    (*func)( [ ] )  -- an array 
    (*func)( *[ ] )  -- of pointers 
    (*func)( (*[ ])())  -- to functions taking 
           --  an unspecified number of parameters 
    (*func)(int(*[ ])())  -- returning int 
void (*func)(int(*[ ])()); -- and returning void 

Điều này sẽ như thế nào trong thực tế sẽ là một cái gì đó như sau:

/** 
* Define the functions that will be part of the function array 
*/ 
int foo() { int i; ...; return i; } 
int bar() { int j; ...; return j; } 
int baz() { int k; ...; return k; } 
/** 
* Define a function that takes the array of pointers to functions 
*/ 
void blurga(int (*fa[])()) 
{ 
    int i; 
    int x; 
    for (i = 0; fa[i] != NULL; i++) 
    { 
    x = fa[i](); /* or x = (*fa[i])(); */ 
    ... 
    } 
}  
... 
/** 
* Declare and initialize an array of pointers to functions returning int 
*/ 
int (*funcArray[])() = {foo, bar, baz, NULL}; 
/** 
* Declare our function pointer 
*/ 
void (*func)(int(*[ ])()); 
/** 
* Assign the function pointer 
*/ 
func = blurga; 
/** 
* Call the function "blurga" through the function pointer "func" 
*/ 
func(funcArray); /* or (*func)(funcArray); */ 
+1

+1 cho đủ tốt, hãy thử giải thích cách đọc biểu thức và ví dụ đó. –

+0

+1, đẹp nhất :) –

+0

+1 để phân tích cú pháp khi bắt đầu. Tốt đẹp! –

2

Geordi là bot C++, cho phép huấn luyện điều này:

<litb> geordi: {} void (*func)(int(*[ ])()); 
<litb> geordi: -r << ETYPE_DESC(func) 
<geordi> lvalue pointer to a function taking a pointer to a pointer to a nullary function 
     returning an integer and returning nothing 

Nó có thể làm được nhiều điều hữu ích, như hiển thị tất cả các tham số tờ khai (điều này, trên thực tế, chỉ là phù hợp với nguyên C++ tên quy tắc ngữ pháp):

<litb> geordi: show parameter-declarations 
<geordi> `int(*[ ])()`. 

Hãy làm điều đó theo hướng ngược lại:

<litb> geordi: {} int func; 
<litb> geordi: make func a pointer to function returning void and taking array of pointer to 
     functions returning int 
<litb> geordi: show 
<geordi> {} void (* func)(int(*[])()); 

Nó thực hiện bất kỳ điều gì bạn đưa ra, nếu bạn yêu cầu. Nếu bạn được đào tạo nhưng chỉ quên một số quy tắc dấu ngoặc đơn đáng sợ, bạn cũng có thể kết hợp mô tả loại C++ và kiểu geordi:

<litb> geordi: make func a (function returning void and taking (int(*)()) []) * 
<geordi> {} void (* func)(int(*[])()); 

Hãy vui vẻ!

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