2012-11-06 8 views
15

Tôi khá mới đối với C và tôi đang cố gắng tìm ra một số khai báo C. Ai đó có thể giúp tôi giải thích ý nghĩa của những tờ khai C này?Tìm ra các Tuyên bố C

double (*b)[n]; 
double (*c[n])(); 
double (*d())[n]; 

Tôi đánh giá cao sự trợ giúp!

+8

Đi [Spiral ....] (http://c-faq.com/decl/spiral.anderson.html) –

+1

Liên kết đó thực sự hữu ích, cảm ơn! –

+0

+1 thaks cho yêu cầu này tôi đã có cùng một câu hỏi khi tôi đã kiểm tra mã hạt nhân –

Trả lời

12
double (*b)[n]; 

b là một con trỏ đến một mảng của n tăng gấp đôi

double (*c[n])(); 

c là một mảng của n con trỏ đến chức năng tham số không xác định các tham số và trả về đôi

double (*d())[n]; 

d là một hàm lấy số lượng đối số không xác định và trả về một con trỏ tới một mảng của n đôi

Nói chung, để phân tích các loại khai báo này trong đầu bạn, hãy thực hiện theo cách tiếp cận sau. Hãy xem tuyên bố cuối cùng, ví dụ:

double (*d())[n]; 

điều đầu tiên được thực hiện cho d là gì? Nó được gọi với(), do đó đó là một hàm lấy số lượng đối số không xác định và returnig ... điều gì đã xảy ra với kết quả? Nó được dereferenced (*), do đó nó là một con trỏ đến. Kết quả sau đó được lập chỉ mục, do đó, nó là một mảng n ... còn lại? một đôi, do đó, tăng gấp đôi. Đọc các phần in đậm, bạn sẽ nhận được câu trả lời của bạn.

Chúng ta hãy xem một ví dụ khác

void (*(*f)(int)[n])(char) 

Ở đây, f là đầu tiên dereferenced, do đó nó là một con trỏ đến ... nó sau đó được gọi với (int), do đó một hàm lấy int và trở về, kết quả sau đó được lập chỉ mục với [n], do đó, một mảng n. Kết quả bị hủy đăng ký lại, do đó, con trỏ đến. Sau đó, kết quả được gọi bởi (char), do đó, chức năng lấy char và trả về (tất cả đều bị hủy) void. Vì vậy, f là một con trỏ đến một hàm lấy int và trả về một mảng của n con trỏ đến các hàm lấy char và trả về void.

HTH

+0

@ Joachim: Ah, quên nó đã được C. Cố định –

+0

Cảm ơn, lời giải thích cuối cùng đã giúp tôi thực hiện điều này tốt hơn! –

+0

@JoeCrawley: Thêm một ví dụ khác ... một ví dụ phức tạp hơn. –

8

Nguyên tắc cơ bản để phân tích tờ khai C là "đọc từ phải sang trái và từ trong ra ngoài nhảy về phía bên phải khi rời khỏi một cặp ngoặc", tức là bắt đầu cặp lồng nhau sâu sắc nhất của ngoặc và sau đó làm việc cho mình ra ngoài nhìn về phía bên phải. Về mặt kỹ thuật, bạn phải biết toán tử kết hợp, nhưng nó hoạt động đủ tốt trong hầu hết các tình huống.

Bây giờ cho phép áp dụng điều này quy tắc (giản thể) cho câu hỏi của bạn:


double (*b)[n]; 
     ^

b là một con trỏ

double (*b)[n]; 
     ^

để

double (*b)[n]; 
      ^^^ 

và mảng

double (*b)[n]; 
^^^^^^ 

của đôi.


double (*c[n])(); 
     ^^^^ 

c là một mảng của

double (*c[n])(); 
     ^

con trỏ để

double (*c[n])(); 
       ^^ 

chức năng

double (*c[n])(); 
^^^^^^ 

trở kép.


double (*d())[n]; 
     ^^^ 

d là một hàm

double (*d())[n]; 
     ^

trả về một con trỏ đến

double (*d())[n]; 
      ^^^ 

một mảng của

double (*d())[n]; 
^^^^^^ 

đôi


Có một tiện ích gọn gàng tìm thấy trên hầu hết các * nixes, gọi cdecl, trong đó có một chuỗi khai C và biến nó thành một câu ngôn ngữ tự nhiên.

1

Có hai nguồn tài nguyên tuyệt vời để hiểu "C vô nghia":

Sản lượng cdecl.org:

  • double (*c[n])(): Cú pháp lỗi (n không hợp lệ ở đây)
  • double (*c[])(): khai báo c như mảng của con trỏ đến hoạt động trở lại đôi
3

Hãy thử cách này.

đầu tiên, bạn nên làm quen với ba biểu tượng:

1. * -- a pointer. 
2. [] -- an array. 
3.() -- a function.(notice: not parentheses)

chúng ta hãy "kép (* d()) [n]" làm ví dụ.

bước đầu tiên là tìm số nhận dạng trong khai báo, số nhận dạng là tên biến, tại đây nó là "d".

(i) 
-- what is "d"? 
------------------------------------------------------------------------ 
look to the right side of the identifier, to see if there is a "[]" or a "()" : 
...d[]...: d is an array. 
...d()...: d is a function. 

if neither, look to the left side, to see if there is a "*" : 
...*d...: d is a pointer. 
------------------------------------------------------------------------

bây giờ chúng tôi thấy rằng d là một hàm. sử dụng x để thay thế d(), sau đó tuyên bố trở thành "kép (* x) [n]"

(ii) 
-- what is "x"? 
------------------------------------------------------------------------ 
repeat (i), we find that x is a pointer. 
that means, d is a function returning a pointer. 
------------------------------------------------------------------------

sử dụng y để thay thế * x, sau đó tuyên bố trở thành "đôi y [n]"

(iii) 
-- what is "y"? 
------------------------------------------------------------------------ 
repeat (i), we find that y is an array of n elements. 
that means, d is a function returning a pointer to an array of n elements. 
------------------------------------------------------------------------

sử dụng z để thay thế y [n], sau đó tuyên bố trở thành "z đôi"

(iv) 
-- what is "z"? 
------------------------------------------------------------------------ 
repeat (i), we find that z is a double. 
that means, d is a function returning a pointer to an array of n double elements. 
------------------------------------------------------------------------

chúng ta hãy xem một biểu hiện:

void (*(*f)(int)[n])(char)
1. 
    we find f. 
2. 
    f is a pointer. *f -> a 
    void (*a(int)[n])(char) 
3. 
    a is a function. a() -> b 
    void (*b[n])(char) 
    --f is a pointer to a function (with an int parameter)-- 
4. 
    b is an array. b[] -> c 
    void (*c)(char) 
    --f is a pointer to a function returning an array (of n elements)-- 
5. 
    c is a pointer. *c -> d 
    void d(char) 
    --f is a pointer to a function returning an array of n pointers-- 
6. 
    d is a function returning void. 
    --f is a pointer to a function returning an array of n pointers to functions (with a char parameter) returning void--