2011-07-06 39 views
12

Tôi gặp khó khăn khi tìm mẫu trực quan cho cách const được sử dụng trong các khai báo bằng ngôn ngữ C và C++. Dưới đây là một số ví dụ:Xác định vị trí "const" trong tuyên bố

const int a; //Const integer 
int const a; //Const integer 
const int * a; //Pointer to constant integer 
int * const a; //Const pointer to an integer 
int const * a const; //Const pointer to a const integer 

Trong dòng 1 và 2, có vẻ như const có thể đứng trước hoặc sau khi int, đó là những gì nó sẽ thay đổi.

  1. Vậy làm thế nào, ở dòng 4, không trình biên dịch quyết định rằng const được sửa đổi * (con trỏ) chứ không phải là int?
  2. Quy tắc mà trình biên dịch tuân theo để quyết định điều mà const áp dụng cho là gì?
  3. Quy tắc có tuân thủ cùng một quy tắc cho * không?
+9

liên kết bắt buộc với [quy tắc xoắn ốc theo chiều kim đồng hồ] (http://c-faq.com/decl/spiral.anderson.html) –

+1

Nếu không có mảng hoặc chức năng liên quan, chỉ cần ** đọc từ phải sang trái * * cũng có thể trợ giúp: 'int const * const a':" 'a' là một con trỏ const đến một const int". –

+0

Đánh dấu, nếu bạn đã gửi câu trả lời đó, tôi đã kiểm tra nó. Rất hữu ích và thực sự giúp tôi tìm ra! –

Trả lời

4

Trình biên dịch thường đọc các loại từ phải sang trái, như vậy:

T const& const 

Would được đọc là:

const (a constant) 
& (to a reference) 
const (to a constant) 
T (of type T) 

Vì vậy, về cơ bản từ khóa "const" sửa đổi mọi thứ đứng trước nó. Tuy nhiên, có một ngoại lệ trong trường hợp "const" đến trước, trong trường hợp này nó đổi mục trực tiếp ở bên phải của nó:

const T& const 

Trên đây được đọc như sau:

const (a constant) 
& (to a reference) 
const T (to a constant of type T) 

Và ở trên tương đương với T const & const.

Mặc dù đây là cách trình biên dịch thực hiện, tôi thực sự khuyên bạn nên ghi nhớ các trường hợp "T", "const T", "const T &", "const T *", "const T & const", "const T * const "," T & const "và" T * const ". Bạn sẽ hiếm khi gặp phải bất kỳ biến thể nào khác của "const", và khi bạn làm vậy, có thể bạn nên sử dụng typedef.

+0

Cảm ơn bạn đã giải thích cách trình biên dịch thực hiện nó, không chỉ như thế nào "một con người có thể làm điều đó", mà thực sự là những gì tôi đã yêu cầu. –

+5

Tôi tin rằng không có những điều như là một "tham chiếu liên tục" (hoặc, nói cách khác, chúng luôn không đổi). Vì vậy, 'T & const' không đúng ngữ nghĩa. VC++ 2010 đưa ra một cảnh báo và bỏ qua 'const'. Chỉ là một lời nhắc nhở. :) – Nubcase

+1

-1 cho ví dụ xấu. Bạn nên đã sử dụng một con trỏ ở đây, không phải là một tham chiếu. –

7

Giả sử bạn luôn đặt const đến đúng loại, bạn có thể đọc một tuyên bố biến như là một câu từ phải sang trái:

int const x;  // x is a constant int 
int *const x;  // x is a constant pointer to an int 
int const *x;  // x is a pointer to a constant int 
int const *const x; // x is a constant pointer to a constant int 

này vẫn hoạt động nếu bạn đặt const đến bên trái của một loại, nhưng đòi hỏi một chút nỗ lực tinh thần. Lưu ý rằng đây hoạt động giống như tốt với con trỏ-to-con trỏ (và các cấu trúc bậc cao):

int *const *const x; // x is a constant pointer to a constant pointer to an int 
+0

Đánh bại tôi đến 30 giây! –

+1

Vì vậy, quy tắc cơ bản được đọc từ phải sang trái và nếu điều trái nhất là 'const', thì nó áp dụng cho điều trực tiếp bên phải của nó. Vì vậy, 'const' áp dụng cho điều bên trái, trừ khi nó không có gì ở bên trái, vì vậy nó áp dụng cho điều bên phải. –

2

Đối với con trỏ, đây là trang tôi đã chọn từ một trong những cuốn sách của Scott Meyers (tôi nghĩ). Vẽ một đường thẳng đứng qua *, và sau đó bất cứ điều gì trên cùng một bên của dòng như từ khóa const là điều đó const.

Để làm rõ:

int * const a có nghĩa là một là const, không phải là int. Và "a" là một con trỏ tới (không phải const) int.

0

Vâng, để bắt đầu, câu hỏi này là nhiều hơn một sở thích cá nhân. Đối với lập trình viên giải trí, đó là một phong cách cá nhân hơn. Tuy nhiên, đối với những người đối phó với các công ty, có thể có một số loại quy ước mã hóa mà họ bố trí cho các lập trình viên để làm theo như vậy mà tất cả mọi người đi ra với phong cách mã hóa nhất quán.

(1) Đối với const int * const a; điều đó có nghĩa là bạn không thể thay đổi con trỏ trỏ đến nhưng bạn có thể sửa đổi vị trí bộ nhớ đó.

(2) Các 'const' được quyết định bởi bạn, là lập trình viên, cho dù bạn muốn địa chỉ con trỏ trỏ đến, không đổi hoặc nếu bạn muốn con trỏ KHÔNG sửa đổi con trỏ nó trỏ tới.

(3) Có các quy tắc là như nhau cho * như trong trường hợp của const int * const a;

Là một lưu ý bổ sung, dòng cuối cùng của bạn không phải là C89 hợp lệ.

Hy vọng điều đó sẽ hữu ích. Chúc mừng!

+0

Nó có thể là một ưu tiên cho các lập trình viên, nhưng chắc chắn không phải để các anh chàng khác, những người đã đọc mã của mình! –

+0

Vấn đề không chỉ bằng văn bản mà còn đọc một người khác viết. –

+0

Đồng ý. Chúc mừng! :) – Vern

1

Chìa khóa để hiểu những điều này là nhận ra rằng * liên kết với a, không phải với loại. Vì vậy, bạn nên đọc những điều này là:

const int a; // a has type const int 
int const a; // a has type int const 
const int * a; // *a has type const int 
int * const a; // *(const a) has type int, which means *a has type int and a is const 
int const * a const; // *(const a) has type int const, which means *a has type const int and a is const. 

(Lưu ý rằng tham chiếu C++ không tuân thủ quy tắc này).

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