Rất nhiều sự nhầm lẫn về con trỏ C xuất phát từ một lựa chọn rất tệ vốn được đưa ra ban đầu liên quan đến phong cách mã hóa, được chứng thực bởi một lựa chọn nhỏ rất tệ trong cú pháp của ngôn ngữ.
int *x = NULL;
C là đúng, nhưng nó rất dễ gây hiểu lầm, tôi thậm chí sẽ nói vô nghĩa, và nó đã cản trở việc hiểu ngôn ngữ của nhiều người mới làm quen. Nó khiến người ta nghĩ rằng sau này chúng ta có thể làm được *x = NULL;
, điều tất nhiên là không thể. Bạn thấy đấy, kiểu của biến không phải int
, và tên của biến cũng không *x
, cũng như *
khai báo trong khai báo không đóng bất kỳ vai trò chức năng nào khi phối hợp với =
. Nó hoàn toàn là khai báo. Vì vậy, điều có ý nghĩa hơn là:
int* x = NULL;
cũng chính xác C, mặc dù nó không tuân theo kiểu mã hóa K&R ban đầu. Nó làm cho nó hoàn toàn rõ ràng rằng kiểu là int*
và biến con trỏ x
, vì vậy nó trở nên rõ ràng ngay cả với người chưa bắt đầu rằng giá trị NULL
đang được lưu trữ vào x
, đó là một con trỏ tới int
.
Hơn nữa, nó làm cho nó dễ dàng hơn để suy ra một quy tắc: khi ngôi sao ở xa tên biến thì đó là một khai báo, trong khi ngôi sao được gắn với tên là tham chiếu con trỏ.
Vì vậy, bây giờ nó trở nên dễ hiểu hơn rất nhiều rằng chúng ta có thể làm được x = NULL;
hoặc *x = 2;
nói cách khác, nó giúp người mới làm quen dễ dàng hơn trong việc xem cách variable = expression
dẫn đến pointer-type variable = pointer-expression
và dereferenced-pointer-variable = expression
. (Đối với khởi tạo, bởi 'biểu thức', tôi có nghĩa là 'rvalue'.)
Sự lựa chọn đáng tiếc trong cú pháp của ngôn ngữ là khi khai báo các biến cục bộ, bạn có thể nói int i, *p;
cái nào khai báo một số nguyên và một con trỏ tới một số nguyên, vì vậy nó khiến người ta tin rằng cái tên *
là một phần hữu ích. Nhưng nó không phải vậy, và cú pháp này chỉ là một trường hợp đặc biệt kỳ quặc, được thêm vào để thuận tiện, và theo ý kiến của tôi, nó đáng lẽ không bao giờ tồn tại, bởi vì nó làm mất hiệu lực của quy tắc mà tôi đã đề xuất ở trên. Theo như tôi biết, không nơi nào khác trong ngôn ngữ cú pháp này có ý nghĩa, nhưng ngay cả khi đúng như vậy, nó chỉ ra sự khác biệt trong cách các loại con trỏ được định nghĩa trong C. Mọi nơi khác, trong khai báo một biến, trong danh sách tham số, trong cấu trúc thành viên, v.v., bạn có thể khai báo con trỏ của mình type* pointer-variable
thay vì type *pointer-variable
; nó hoàn toàn hợp pháp và có ý nghĩa hơn.
int *x = whatever;
hiện và những gìint *x; *x = whatever;
không.int *x = whatever;
thực sự hành xử giống nhưint *x; x = whatever;
, không phải*x = whatever;
.