2008-10-28 41 views
30

Ai đó có thể giải thích điều này có nghĩa là gì?Dấu ngoặc đơn trong khai báo biến C có nghĩa là gì?

int (*data[2])[2]; 
+0

Liên kết Microsoft này có thể hữu ích. (Hoặc nó có thể chỉ làm cho bộ não của bạn phát nổ) [Giải thích những người khai báo phức tạp hơn] (http://msdn.microsoft.com/en-us/library/1x82y1z4.aspx) –

Trả lời

37

Các dấu ngoặc đơn là gì?

Trong ngoặc C [] có một ưu tiên cao hơn so với dấu hoa thị *

Tốt lời giải thích từ Wikipedia:

Để khai báo một biến như là một con trỏ đến một mảng, chúng ta phải sử dụng các dấu ngoặc đơn. Điều này là do trong các dấu ngoặc C ([]) có mức ưu tiên cao hơn so với dấu hoa thị (*). Vì vậy, nếu chúng ta muốn khai báo một con trỏ đến một mảng, chúng ta cần phải cung cấp dấu ngoặc đơn để ghi đè này:

double (*elephant)[20]; 

này tuyên bố con voi đó là một con trỏ , và loại nó trỏ tại là một mảng 20 giá trị kép.

Để khai báo một con trỏ tới một mảng của các con trỏ , chỉ cần kết hợp các ký hiệu .

int *(*crocodile)[15]; 

Source.

Và trường hợp thực tế của bạn:

int (*data[2])[5]; 

dữ liệu là một mảng của 2 yếu tố này. Mỗi phần tử chứa một con trỏ tới một mảng gồm 5 int.

Vì vậy, bạn bạn có thể có trong mã sử dụng loại 'dữ liệu' của bạn:

int (*data[2])[5]; 
int x1[5]; 
data[0] = &x1; 
data[1] = &x1; 

data[2] = &x1;//<--- out of bounds, crash data has no 3rd element 
int y1[10]; 
data[0] = &y1;//<--- compiling error, each element of data must point to an int[5] not an int[10] 
+0

câu trả lời hoàn hảo! – J3STER

14

Có một chương trình rất mát mẻ gọi là "cdecl" mà bạn có thể tải về cho Linux/Unix và có lẽ cho Windows là tốt. Bạn dán vào một khai báo biến C (hoặc C++ nếu bạn sử dụng khai báo C++ decl) và nó viết ra bằng các từ đơn giản.

+1

+1 để đề cập đến cdecl – user7116

+1

Với tên như @sixlettervariables, tôi cho rằng bạn thậm chí còn là trường học cũ hơn tôi. Hãy nói cho tôi biết bạn nhớ những điều răn của Henry Spencer? –

+1

Hình tôi muốn đề cập đến rằng cdecl bây giờ là một trang web: [cdecl.org] (http://cdecl.org/) – Urchin

-1

dữ liệu [2] - một mảng của hai số nguyên

* dữ liệu [2] - một con trỏ đến một mảng của hai số nguyên

(* dữ liệu [2]) - "

(* dữ liệu [2]) [2] - một mảng của 2 con trỏ đến mảng của hai số nguyên

+1

Mục thứ hai không phải là những gì bạn nói. Ngoài loại thiếu (mà bạn đã giả định là số nguyên), nó là một mảng gồm 2 con trỏ tới số nguyên. Thứ ba không phải là C. Thứ tư có lẽ là chính xác. –

+0

Hmmm, tôi đoán có thể báo giá là một dấu ditto. Tôi vẫn nghĩ rằng lời giải thích để lại một cái gì đó để được mong muốn. –

4

Nếu bạn biết làm thế nào để đọc biểu trong C, sau đó bạn thực hiện một bước đi từ việc đọc tờ khai phức tạp

..

Những gì hiện

char *p; 

thực sự có nghĩa là gì? Nó có nghĩa là *p là một char.Những gì hiện

int (*data[2])[5]; 

có nghĩa là gì? Nó có nghĩa là (*data[x])[y] là một int (được cung cấp 0 < = x < 2 và 0 < = y < 5). Bây giờ, chỉ cần suy nghĩ về những gì các tác động của đó là. data phải là ... một mảng gồm 2 ... con trỏ ... tới mảng 5 ... số nguyên.

Bạn có nghĩ điều đó khá thanh lịch không? Tất cả những gì bạn đang làm là nói rõ loại biểu thức. Một khi bạn nắm bắt điều đó, các tuyên bố sẽ không bao giờ đe dọa bạn một lần nữa!

"Quy tắc nhanh" là bắt đầu bằng tên biến, quét sang phải cho đến khi bạn nhấn a), quay lại tên biến và quét sang trái cho đến khi bạn nhấn (. Sau đó "bước ra" của cặp ngoặc đơn, và lặp lại quá trình

Hãy áp dụng nó vào một cái gì đó vô lý:.

void **(*(*weird)[6])(char, int); 

weird là một con trỏ đến một mảng của 6 con trỏ đến chức năng từng chấp nhận một char và int như là đối số, và mỗi con trỏ trở về một con trỏ trỏ đến một con trỏ để làm mất hiệu lực.

Bây giờ bạn đã biết nó là gì và nó được thực hiện như thế nào ... đừng làm điều đó. Sử dụng typedefs để phá vỡ các khai báo của bạn thành nhiều phần dễ quản lý hơn. Ví dụ.

typedef void **(*sillyFunction)(char, int); 

sillyFunction (*weird)[6]; 
+0

Và ngày nay, sử dụng 'using' để ánh xạ tên thành một loại. – IllidanS4

+0

Đó sẽ là C++ ... – Artelius

+0

Và ngày nay, hãy sử dụng C++ :-P – IllidanS4

-1

Nếu bạn có một mảng:

int myArray[5]; 
int * myArrayPtr = myArray; 

Sẽ là hoàn toàn hợp lý. myArray không có dấu ngoặc là một con trỏ đến số int. Khi bạn thêm dấu ngoặc của nó giống như bạn hãy chú ý đến con trỏ myArray. Bạn có thể viết ...

myArrayPtr[1] = 3; 

Điều này hoàn toàn hợp lý. Sử dụng dấu ngoặc đơn chỉ làm cho mọi thứ khó đọc và hiểu IMO hơn. Và họ cho thấy rằng mọi người không hiểu con trỏ, mảng, và số học con trỏ, đó là cách trình biên dịch hoặc trình liên kết chuyển từ cái này sang cái kia. Có vẻ như với dấu ngoặc đơn bạn có được kiểm tra giới hạn mặc dù.

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