2012-04-27 19 views
18

Xin lỗi vì tiêu đề crappy, nhưng tôi không biết cách mô tả tốt hơn vấn đề này.Dấu sao C++ và toán tử khung được sử dụng cùng nhau

int (*x)[]; 

và làm thế nào để khởi tạo nó:

ý nghĩa của là gì?

Tôi biết nó không phải là int *x[] từ:

int a,b; 
int (*x)[] = {&a, &b}; 

sẽ không biên dịch.

Cảm ơn bạn trước.

Trả lời

25

Loại tờ khai có một cú pháp biểu hiện giống như, vì vậy bạn phân tích chúng như bạn sẽ một biểu:

 x  x is 
    *x  a pointer 
    (*x)[] to an array of unknown dimensions 
int (*x)[] of int 

Nguyên tắc ưu tiên là các nhà khai thác với ràng buộc đúng chặt chẽ hơn những sang bên trái, trong mỗi trường hợp, các nhà điều hành gần gũi hơn với các yếu tố liên kết chặt chẽ hơn, và cuối cùng, đó là dấu ngoặc đơn có thể được sử dụng để thay đổi các bindings, vì vậy:

int *x[]; is an array of pointers, 
int *(x[]); as is this. 
int (*x)[]; whereas here, the parentheses change the bindings. 
+1

+1 .... Tuyệt vời! – Nawaz

13

Sử dụng cdecl, bạn có thể dễ dàng xác định các loại:

declare x as pointer to array of int

Vì vậy, bạn có thể khởi tạo x với địa chỉ của một mảng:

int a[]; // conceptual: error if compiled 
x = &a; 

Lưu ý rằng kích thước của mảng là một phần của loại của nó, vì vậy bạn không thể gán địa chỉ của một mảng có kích thước N cho một con trỏ tới mảng có kích thước M, trong đó N!=M (đây là lý do cho lỗi ở trên: bạn cần biết kích thước của mảng đó để khai báo)

int b[5]; 
int c[6]; 
int (*y)[6]; 
y = &b; // error 
y = &c; // OK 
+0

Nhắc nhở khi đề cập đến 'cdecl' - Tôi đã quên nó tồn tại - mặc dù nghiêm chỉnh, nó chỉ hỗ trợ cú pháp C. –

+0

Cảm ơn bạn đã liên kết, nó hữu ích! – Chlind

3

int (*x)[] sử dụng cho con trỏ tới mảng trống. Nhưng khởi tạo một mảng trống không thể trong C++. Chỉ bạn mới có thể xác định nó. Bạn nên sử dụng một mảng không rỗng:

int a[2] = {1, 2}; 
int (*x)[2] = &a; 
+1

GCC phàn nàn nó không thể chuyển đổi 'int (*) [2]' thành 'int (*) []'. Edit: Bây giờ nó deviates từ câu hỏi;) – chris

+0

bạn là đúng, tôi sửa chữa nó. –

2

int (*x)[] nghĩa x là một con trỏ đến int mảng. Bạn có thể làm như thế này:

int a[] = {1, 2}; 
int (* b)[2] = &a; 

Khi giải thích biến mảng, đánh máy, chúng ta nên đi từ phải sang trái. ví dụ.

int *x[] 

chỉ ra rằng x là một mảng, các yếu tố trong mảng được gõ như int * ví dụ: con trỏ đến int. Do đó x đại diện cho một mảng có phần tử là con trỏ int. Tuy nhiên, dấu ngoặc đơn thay đổi ưu tiên của toán tử. Bây giờ * được hiểu đầu tiên cho biết x là một con trỏ, có loại là int []. Vì vậy, x trong int (*x)[] là một con trỏ đến mảng int và bạn nên khởi tạo nó cho phù hợp.

+0

Không biên dịch: lỗi: không thể chuyển 'int (*) [2]' sang 'int (*) []' trong bài tập – Attila

+0

@Attila Trình biên dịch của bạn hoạt động tốt trên 'gcc 4.1.2'. :) –

+0

http : // ideone.com/- Tôi nghĩ rằng nó sử dụng gcc ở phía sau, nhưng tôi không biết phiên bản/tùy chọn – Attila

1

tôi đã từng gặp vấn đề với việc đánh máy C, cho đến khi tôi biết được nó được tạo ra như thế nào.

Trong C, loại được mô tả theo cách bạn sẽ sử dụng một biến loại đó.

Vì vậy, khi bạn nhìn thấy:

int *x; 

nó có nghĩa là sự biểu hiện *x là loại int, vì vậy x là biến kiểu con trỏ-to-int.

Và nếu bạn thấy:

int x[5]; 

nó có nghĩa là sự biểu hiện x[3] là loại int, vì vậy x là một biến kiểu mảng-of-int.

Vì vậy, để có được biểu hiện của bạn:

int (*x)[]; 

nó có nghĩa là sự biểu hiện *x là loại int[] (ví dụ, một mảng của int kích thước không rõ). Do đó x là một biến kiểu con trỏ tới một mảng-của-int.

+1

Về bản chất bạn có thể đúng nhưng bạn thậm chí còn rõ ràng hơn. Khi bạn thấy 'int * x' có nghĩa là' * x' là * một biến * của kiểu int. Cách bạn nói nó, nó không phải là rõ ràng cho dù bạn có nghĩa là '* x' là một * giá trị * của loại int hoặc một * biến * của loại int. –

+0

@EricLippert: '* x' không phải là biến, đó là một biểu thức. Tôi giới thiệu "biểu hiện" và "biến" trên khắp nơi để đánh dấu sự khác biệt và hy vọng làm cho mọi thứ rõ ràng hơn. –

+2

Tất nhiên '* x' là biến * *; nó đại diện cho một * vị trí lưu trữ * mà * bạn có thể gán các giá trị cho *, vì vậy nó là một biến * *; đó là biến số * là *: vị trí lưu trữ mà bạn có thể gán giá trị cho. C lập trình của khóa học có xu hướng gọi những thứ như "lvalues" chứ không phải là "biến" đó là không may; "lvalue" là khó hiểu và không cần thiết cách biệt ngữ để nói "biến". –

0

int (* x) [] Điều này có nghĩa x là một con trỏ đến một mảng int Initialize như: int (* x) []; int [10]; x = & a;

int * x [] Điều này có nghĩa x là một mảng con trỏ tới int int * x [10]; int [10]; x [0] = a;

Theo tôi, luôn sử dụng các biến mảng khởi tạo hoặc sử dụng int ** x thay vì * x [] và sau đó cấp phát bộ nhớ khi chạy.

+0

Ví dụ sử dụng đầu tiên không biên dịch: lỗi: không thể chuyển đổi 'int() [10]' thành 'int() []' trong bài tập – Attila

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