2010-04-09 31 views
9

Tôi đã thấy mã nguồn luôn luôn có một typedef cho một cấu trúc và sử dụng cùng ở khắp mọi nơi thay vì sử dụng tên cấu trúc như "struct sname" vv trực tiếp?Tại sao tên cấu trúc lại có typedef?

Lý do đằng sau điều này là gì? Có lợi thế trong việc này không?

+0

Trong cuốn sách * Lập trình C chuyên nghiệp *, Peter van der Linden làm cho trường hợp typedefs cho cấu trúc là vô ích và bạn không nên bận tâm. Tôi thích điều này. Tất cả typedef là nó giúp bạn viết 'struct' ở một vài nơi như declaratations và prototype. Nó không đáng để obfuscation. Tôi muốn ngay lập tức biết khi nào tôi phải sử dụng '->' hoặc '.'. Typedefs làm cho điều này khó hơn. – Jens

Trả lời

10

của nó dễ dàng hơn để đọc Box b; hơn struct boxtype b;

typedef struct _entry{ 
    char *name; 
    int id; 
} Entry, *EntryP; 

Ưu điểm:
Ở phía trên typedef, cả Entry & EntryP được định nghĩa ngoài struct _entry.
Vì vậy, EntryP firstentry có thể được sử dụng thay cho struct _entry *firstentry và đơn giản hơn để phân tích cú pháp.

Lưu ý: Tên cấu trúc không giống như của nó nêntypedef ined, nhưng rõ ràng là dễ đọc hơn. Ngoài ra, việc sử dụng Entry *EntryP hoàn toàn phụ thuộc vào người dùng.

+3

Tôi thường tranh luận chống lại typedefs như 'EntryP'. C đã có một cách hoàn toàn tốt để khai báo con trỏ bạn muốn: 'Entry * firstentry'. –

+1

@Hagglund: Không có gì để tranh luận về :). Nó hoàn toàn chủ quan, người ta có thể thích 'EntryP' trong khi người khác có thể thích' Entry * '. –

+1

Tôi đồng ý nó là chủ quan nhưng tôi đã nghĩ rằng nó không được khuyến khích vì nó tóm tắt thực tế rằng 'firstentry' là loại' Entry * 'không có lý do chính đáng. Mặc dù 'P' trong 'EntryP' có nghĩa là nhấn mạnh 'con trỏ tới', nó vẫn còn mơ hồ trong khi' Entry * 'thì không. Trong mọi trường hợp, tôi tin rằng dòng lệnh 'struct entry * firstentry' của bạn nên là' struct _entry * firstentry', lưu ý dấu gạch dưới – SiegeX

1

Đó là một dạng ẩn thông tin và hữu ích khi tạo các loại mờ. Xem this SO link để có câu trả lời dài hơn một chút.

3

Tôi muốn làm điều này trong C:

// in a "public" header file 
typedef struct Example Example; 

// in a "private" header or a source file 
struct Example { ... }; 

Như thế này, tôi có Example như một loại đục (ví dụ, tôi chỉ có thể vượt qua con trỏ tới về) trong suốt mã của tôi, trừ cho mã thực hiện các hoạt động của nó, có thể thấy những gì nó thực sự được định nghĩa là. (Bạn có thể sử dụng tên riêng cho loại đục nhưng không có lợi thế thực sự cho điều đó.)

1

Tên cấu trúc không được gõ trong C yêu cầu "struct" được đặt trước ở khắp mọi nơi tên loại được sử dụng, vì vậy hầu hết mọi người sử dụng typedef để tạo một tên mới cho kiểu mà không cần phải có từ khóa struct prepended tất cả các thời gian.

Lý do làm việc này là khả năng đọc mã, giảm nhập và có thể là rõ ràng, nhưng typedef có thể che khuất thông tin về các loại con trỏ.

Trong tất cả sự trung thực, việc cần phải gõ để tạo tên mới cho cấu trúc là một di tích, và thật đáng tiếc là C99 không đi theo hướng dẫn của C++ và loại bỏ nó.

+0

C99 không thể loại bỏ 'typedef' để loại bỏ' struct' vì backward khả năng tương thích. Có rất nhiều mã như 'struct Foo {...}; typedef ... Foo; 'sẽ dừng biên dịch. – JeremyP

4

Nó là một quirk lẻ trong ngôn ngữ C, tên thẻ cấu trúc được lưu trữ trong một không gian tên khác nhau (bảng biểu tượng). Ngôn ngữ C++ đã loại bỏ hành vi này. Typedef tạo một bí danh cho kiểu cấu trúc trong không gian tên chung. Vì vậy, bạn không cần phải gõ "struct" trước tên cấu trúc.

Không chắc chắn Ritchie đang hút thuốc khi ông xác định hành vi này. Tôi đoán tại một số loại vấn đề với phân tích cú pháp trong một phiên bản đầu của trình biên dịch.

+0

Tôi đoán rằng việc phân bổ bộ nhớ có thể đơn giản hóa này trong các trình biên dịch đầu tiên, điều quan trọng khi mọi thứ phải phù hợp với không gian dữ liệu 128k hoặc ít hơn. Trong thực tế, trong các trình biên dịch C đầu tiên, cũng có một không gian tên * duy nhất * toàn cục cho các tên thành viên cấu trúc. Điều này có nghĩa là 'struct foo' và' struct bar' không thể có cả một thành viên có tên 'x', dẫn trực tiếp đến kiểu thẻ (' f_x', 'b_x') cho các thành viên cấu trúc phổ biến cho đến ngày nay trong một số Mã C. –

+0

@Dave: Tôi nghĩ bạn nói đúng. Một cái gì đó đang hút thuốc với tên thành viên cấu trúc. Đã quá lâu rồi, tôi đặt tế bào não ở góc bỏ qua một thời gian dài trước đây. Wow, tại sao anh ta phải làm vậy? B? –

2

Chỉ dành cho tính dễ đọc của mã. typedefs chỉ để cung cấp tên mới cho kiểu dữ liệu. Thay vì cho int tất cả các nơi bạn có thể đặt tên nó theo cách bạn muốn và bất cứ nơi nào bạn sử dụng int bạn chỉ có thể thay thế nó bằng tên mới mà bạn đã đưa ra. Điều tương tự cũng áp dụng cho các cấu trúc.

0

Tôi thực sự không sử dụng typedef cho cấu trúc. Tại sao? Vì tôi sẽ sử dụng một số quy ước như tiền tố s_, để dễ dàng xem loại biến tôi đang xem.

Vì tôi sử dụng nhiều loại dữ liệu trừu tượng, tôi đoán bạn nên sử dụng typedef để người dùng thực sự sử dụng nó làm loại mờ. Nhưng trong thực tế tôi luôn luôn sử dụng một cấu trúc trong việc thực hiện anyway.

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