Tại sao sử dụng typedefs cho structs?


12

trong C (ANSI, C99, v.v.), các cấu trúc sống trong không gian tên riêng của chúng. Một cấu trúc cho một danh sách được liên kết có thể trông giống như thế này:

struct my_buffer_type {
   struct my_buffer_type * next;
   struct my_buffer_type * prev;
   void * data;
};

Tuy nhiên, có vẻ khá tự nhiên đối với hầu hết các lập trình viên C để tự động đánh máy các cấu trúc đó như sau

typedef struct tag_buffer_type {
   struct tag_buffer_type * next;
   struct tag_buffer_type * prev;
   void * data;
} my_buffer_type;

Và sau đó tham chiếu cấu trúc như một loại bình thường, tức là get_next_element(my_buffer_type * ptr).

Bây giờ câu hỏi của tôi là: Có một lý do cụ thể cho việc này?

Wikipedia nói http://en.wikipedia.org/wiki/Typedef#Usage_concerns

Một số người phản đối việc sử dụng rộng rãi typedefs. Hầu hết các đối số tập trung vào ý tưởng rằng typedefs chỉ đơn giản là ẩn kiểu dữ liệu thực tế của một biến. Ví dụ, Greg Kroah-Hartman, một hacker và nhà tài liệu nhân Linux, không khuyến khích họ sử dụng cho bất cứ điều gì ngoại trừ các khai báo nguyên mẫu hàm. Ông lập luận rằng thực tế này không chỉ làm xáo trộn mã một cách không cần thiết, nó còn có thể khiến các lập trình viên vô tình lạm dụng các cấu trúc lớn nghĩ rằng chúng là các loại đơn giản. [4]

Những người khác cho rằng việc sử dụng typedefs có thể giúp mã dễ bảo trì hơn. K & R tuyên bố rằng có hai lý do để sử dụng typedef. Đầu tiên, nó cung cấp một phương tiện để làm cho một chương trình di động hơn. Thay vì phải thay đổi một loại ở mọi nơi nó xuất hiện trong các tệp nguồn của chương trình, chỉ cần thay đổi một câu lệnh typedef duy nhất. Thứ hai, một typedef có thể làm cho một tuyên bố phức tạp dễ hiểu hơn.

Cá nhân tôi tự hỏi liệu structđôi khi không có không gian tên riêng biệt đôi khi không sử dụng các cấu trúc typedef'd và vì có một số nền văn hóa lập trình C xung quanh (lập trình Windows C có truyền thống khác với lập trình Linux C trong kinh nghiệm của tôi) nếu có khác truyền thống mà tôi không nhận thức được.

Sau đó, tôi quan tâm đến những cân nhắc lịch sử (tiền thân, phiên bản đầu tiên của C).


4
Mục đích của a typedef để ẩn loại thực tế của một biến. Lấy time_tmột ví dụ: nếu mọi người đi xung quanh bằng cách sử dụng loại số nguyên cơ bản, một thay đổi trong triển khai như vậy sẽ là một thay đổi sẽ được yêu cầu vào năm 2038 sẽ phá vỡ rất nhiều mã. Nếu mọi người đang sử dụng các cấu trúc mà không hiểu tại sao, đó là một lỗi trong lập trình viên, không phải là cấu trúc.
Blrfl

Câu trả lời:


14

Tôi đã làm việc trong một dự án lớn sử dụng rộng rãi các cấu trúc typedef'd. Chúng tôi đã làm như vậy vì một vài lý do. Xin lưu ý rằng đây là tiền C99 và cách ly không gian tên.

  1. Việc nhập my_buffer_type *bufferthay thế dễ dàng hơn struct tag_buffer_type *buffervà với kích thước của cơ sở mã (1M + loc) đã tạo ra sự khác biệt lớn.

  2. Nó trừu tượng hóa cấu trúc thành một đối tượng. Thay vì tập trung vào mọi biến riêng lẻ trong cấu trúc, chúng tôi sẽ tập trung vào đối tượng dữ liệu mà nó đại diện. Sự trừu tượng này dẫn đến việc viết mã thường hữu ích hơn và dễ dàng hơn.

    • Tôi nghĩ rằng điều này mâu thuẫn trực tiếp với trích dẫn được gán cho Greg Kroah-Hartman mà bạn cung cấp. FWIW, dự án đó là một ứng dụng khách / máy chủ và không phải là kernel nên chắc chắn có một số cân nhắc khác nhau cần tính đến.
  3. Việc coi cấu trúc như một đối tượng cũng cho phép chúng tôi đóng gói thông tin tốt hơn. Đánh giá mã đã bắt gặp khá nhiều tình huống trong đó một nhà phát triển mới hơn sẽ vi phạm các nguyên tắc đóng gói mà chúng tôi đã đưa ra. Sử dụng các cấu trúc typedef'd thực sự làm cho những vi phạm rõ ràng.

  4. Tính di động là một mối quan tâm khi chúng tôi đã viết cho một nửa tá nền tảng với máy chủ và một vài thứ nữa với máy khách.


5

Mỗi lần thay vì gõ

struct my_buffer_type *buffer;

nếu bạn typedefnó bạn có thể trực tiếp sử dụng

my_buffer_type *buffer;

typedefMục đích chính của chúng tôi là giảm số lượng tổ hợp phím cần thiết để viết mã và tăng cường khả năng đọc.


bạn đúng nhưng tôi đã mô tả thực tế này trong câu hỏi của tôi rồi.
wirrbel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.