2013-06-10 73 views
7
int (*ptr)(char (*ch)[]); 

Tuyên bố trên có nghĩa là gì? Điều đó có nghĩa làĐối số chấp nhận con trỏ hàm

ptr là con trỏ tới hàm có chấp nhận đối số là mảng con trỏ đến các ký tự trả về số nguyên không?

Cách đánh giá?

+5

Đây là một khu vực của C mà các nhà thiết kế có kinh khủng nặng sai! –

+0

True! Rất khó để đánh giá các biểu thức như vậy .. – RDX

+2

Đây là lỗi cú pháp. –

Trả lời

3

Có quy tắc: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

Tóm lại, bạn nên bắt đầu từ định danh, sau đó phân tích mọi thứ, từ nhận dạng bên phải (nó có thể được ()-chức năng hoặc []mảng), sau đó phân tích mọi thứ, từ nhận dạng để Bên trái. Dấu ngoặc đơn thay đổi thứ tự này - bạn nên phân tích cú pháp mọi thứ trong ngoặc đơn bên trong đầu tiên và cứ như vậy, nó hoạt động giống như với phép tính số học.

Nói cách khác, có một trật tự ưu tiên (có thể được thay đổi bằng dấu ngoặc đơn), từ cao đến thấp:

1) () - chức năng[]-mảng, từ trái bên phải;

2) * - con trỏ, loại, loại modifier, từ phải sang trái.


dụ bạn

int (*ptr)(char (*ch)[]) 

Chúng tôi bắt đầu từ định danh

int (*ptr)(char (*ch)[]); // (1)ptr 
     |_|      
     1 

Định danh ptr là trong ngoặc đơn, vì vậy chúng tôi phân tích tất cả mọi thứ trong parenteses đầu tiên

(*ptr) // (1)ptr 
    |_|  
    1 

Không có gì sang bên phải là, vì vậy chúng tôi phân tích ở phía bên trái

(*ptr) // (1)ptr is (2)a pointer 
||_|  
2 1 

Chúng tôi hoàn thành trong ngoặc đơn, bây giờ chúng tôi phân tích ở bên phải của dấu ngoặc đơn

int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function 
    ||_| |____________| 
    2 1  3 

Cho đến nay chúng ta bỏ qua đối số chức năng và phân tích ở bên trái của dấu ngoặc đơn

int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function which returns (4)int 
|_| ||_| |____________| 
4 2 1  3 

Giống như cách chúng tôi phân tích đối số của hàm (Tôi đã chèn một số khoảng trắng để căn chỉnh tốt hơn)

char (* ch)[ ] // (1)ch is (2)a pointer to (3)array of (4)chars 
|___| | |_| |_| 
    4 2 1 3 

Cuối cùng, ta có:

ptr là con trỏ đến chức năng trả về int và chấp nhận một con trỏ đến mảng các ký tự như là đối số

1

Nó hoạt động tốt trong GCC.

ptr là con trỏ hàm. Nó là một con trỏ trỏ đến một hàm trả về một số nguyên và chấp nhận một con trỏ tới một mảng ký tự làm đối số.

Hãy xem xét các chức năng vui vẻ với nguyên mẫu sau,

int fun(char (*ptr)[]); 

fun() là một chức năng chấp nhận một con trỏ đến một mảng ký tự như là đối số.

và đoạn mã sau biên dịch mà không cần bất kỳ lỗi hoặc cảnh báo,

int (*ptr)(char (*ch)[]); 
ptr=fun; 
+0

Câu hỏi được gắn thẻ C++. G + + không biên dịch được mã này. Xem: http://ideone.com/G7kJpr – jxh

4

ptr là con trỏ đến một chức năng chấp nhận một cuộc tranh cãi mà là một con trỏ đến một loạt các nhân vật, trở về số nguyên.

+1

làm thế nào để u đánh giá giống nhau? – RDX

+0

Không chắc bạn đang hỏi gì. Bạn có thể cụm từ nó một cách khác nhau? – Ziffusion

+0

Ý tôi là, bạn đã đi đến kết luận này như thế nào? – RDX

2

Như bạn đã viết, ptr là một con trỏ đối với hàm trả về int và lấy làm đối số con trỏ tới mảng char.

Tuy nhiên, bạn không được phép có con trỏ tới mảng mà không bị ràng buộc trên mảng. Vì vậy, biến của bạn được chỉ định không chính xác và sẽ không biên dịch. Có vẻ như bạn muốn ptr để có loại có thể chấp nhận con trỏ đến hàm có thể lấy bất kỳ mảng kích thước nào. Điều này đòi hỏi phải xây dựng mẫu. Đối với một luận cứ chức năng, nó sẽ có dạng:

template <unsigned N> 
int foo (int (*ptr)(char (*)[N])) { 
    //... 
} 

Thông thường, cách để đơn giản hóa các loại như vậy là để sử dụng typedef để đại diện cho những phần phức tạp, do đó biến bản thân trở thành một con trỏ đơn giản đối với một số loại. Điều này đặc biệt hữu ích khi cố gắng viết một hàm trả về một con trỏ hàm.

void x (char *s) {} 
typedef void xtype (char *); 

void (* y_hard())(char *) { return x; } 
xtype * y_easy() { return x; } 

Tuy nhiên, tính chất tham số của đối số hàm khiến khó đạt được hơn. Giả sử C++ 11, bạn có thể sử dụng cấu trúc sau (thanks to this answer):

template <unsigned N> 
using ArrayArg = const char [N]; 

template <unsigned N> 
using Function = int (ArrayArg<N> *); 

template <unsigned N> 
int foo (Function<N> *ptr) { 
    //... 
} 
Các vấn đề liên quan