2011-10-29 15 views
5

Tôi biết trong hai cách có thể để xác định và sử dụng struct s:viết code struct mà làm việc cả trong C và C++

#1 
struct person 
{ 
    char name[32]; 
    int age; 
}; 

struct person dmr = {"Dennis Ritchie", 70}; 

#2 
typedef struct 
{ 
    char name[32]; 
    int age; 
} person; 

person dmr = {"Dennis Ritchie", 70}; 

Thuộc tính thú vị của cách đầu tiên là cả hai loại và biến có thể có cùng tên:

struct person person = {"Sam Persson", 50}; 

Đó có phải là thành ngữ trong C? Nó có được đảm bảo hoạt động trong C++ không? Hoặc có những trường hợp góc tôi nên biết?

Lưu ý rằng tôi không quan tâm đến câu trả lời C++ thuần túy (ví dụ: "sử dụng std::string thay vì char[32]"). Đây là câu hỏi về khả năng tương thích C/C++.

+0

Tôi sẽ không gọi đó là "tài sản thú vị" mà nó là tài sản che khuất. Tốt nhất là giữ tên kiểu bắt đầu từ chữ hoa - để phân biệt tên và tên biến. –

+0

Tôi đã đánh dấu điều này là trùng lặp với [typedef struct vs struct definitions] (http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions). Về mặt kỹ thuật bạn có thể xem xét nó không phải là (câu hỏi khác chỉ giao dịch với C) nhưng ngữ nghĩa giống nhau trong C++ với sự khác biệt duy nhất mà tra cứu cũng sẽ tìm thấy các ký hiệu trong không gian định danh do người dùng xác định nếu nó không tìm thấy chúng trong không gian nhận dạng toàn cầu. Điều đó cũng được xử lý trong câu trả lời được chấp nhận (có chứa các bit của c + +) –

+1

Ngoài ra, chúng không ** hai cách định nghĩa 'struct', có một cách xác định' struct' (có thể có hoặc không phải là một tên), và có 'typedef' (có thể được áp dụng cho một loại có tên hoặc chưa đặt tên), nhưng chúng không phải là hai cách để định nghĩa một 'struct' ở bất kỳ mức nào. Và bạn đang thiếu 3), kết hợp cả hai: 'typedef struct type {} type;' cho giá trị của nó (đó là cách thức thành ngữ C) –

Trả lời

1
struct person person = {"Sam Persson", 50}; 

Nó không phải là thành ngữ để sử dụng cùng số nhận dạng cho loại và biến. Trong Unix, thông thường sử dụng phiên bản viết tắt cho tên biến, ví dụ: struct stat st, struct timeval tv, ... giống như cách fd là tên điển hình cho biến mô tả tệp.

3

struct tương thích giữa C & C++ chỉ khi chúng là POD -s.

tôi có xu hướng để mã hóa một cái gì đó như:

struct person_st { char name[32]; int age; }; 
typedef struct person_st Person_t; 
+2

Vì vậy, cấu trúc không phải là POD 'của C là gì? – xanatos

+0

@xantos, 'class'es! Nhưng thay vì 'class' bạn viết' struct' và các thành viên là 'public' theo mặc định như trái ngược với' private' trong 'class'es – Shahbaz

+0

@Shahbaz: Không có lớp nào trong C. Tôi đoán đó là ý nghĩa của xanatos. – fredoverflow

0

Tôi không chắc chắn nếu nó sẽ là hoàn toàn đúng theo tiêu chuẩn C++, nhưng tôi thử nghiệm với g++ -pedantic -Wall và đã không có lỗi hoặc cảnh báo (lưu ý rằng đây doesn' g ++, ngay cả với -pantic, không đi qua những rắc rối của việc đưa ra cảnh báo cho tất cả các mã không chuẩn.) (Có ai biết C++ spec cũng đủ để bình luận về việc nó thực sự là tiêu chuẩn hay không ?)

Điều có văn bản:

struct person person = {...}; 

là trong C++, person cả hai đều đề cập đến biến và loại. Trong C, đây không phải là vấn đề đơn giản bởi vì person không phải là loại (struct person). Mặc dù từ ngữ cảnh, với một vài bài kiểm tra tôi đã viết với g ++, trình biên dịch không có vấn đề gì khi tôi yêu cầu biến và khi cho kiểu, tôi nghĩ nó có thể bị lẫn lộn ở một số điểm. Một điều khó hiểu mà tôi phát hiện ra là nếu bạn có:

struct person *person = ...; 

sau đó sizeof(person) trả về kích thước của biến, trong khi để có được kích thước của các loại, bạn nên viết sizeof(struct person) mà tôi có thể đảm bảo với bạn, không có C++ coder sẽ nhớ viết stuct.

Tốt nhất là tránh mọi loại nhầm lẫn. Tôi thường làm điều này cho mã mà có thể được sử dụng cả trong C và C++:

typedef struct person 
{ 
    ... 
} person; 

Đưa ra một tên cho struct đó đang được typedef ed cho phép các lập trình viên sử dụng hoặc person hoặc struct person. Vì vậy, một chút linh hoạt (chưa kể bạn không phải thay đổi mã đã viết sau khi typedef nhập struct.

+1

Ví dụ 'sizeof'. xem tiêu chuẩn C++ §9.1 ¶2 _Nếu tên lớp được khai báo trong phạm vi mà một biến, hàm, hoặc điều tra viên cùng tên cũng được khai báo, thì khi cả hai khai báo nằm trong phạm vi, lớp đó có thể được gọi chỉ bằng cách sử dụng một elaborated-type-specifier_ – ninjalj

+0

Không, trong C++ cho ví dụ đầu tiên của bạn 'person' sẽ tham chiếu đến biến. –

2

Tôi tuyên bố họ có cùng tên trong cả thẻ struct và không gian tên nhận dạng toàn cầu:

#ifdef __cplusplus 
extern "C" { 
#endif 

typedef struct person 
{ 
    char name[32]; 
    int age; 
} person; 

#ifdef __cplusplus 
} 
#endif 

Khi sử dụng, mà không cần sử dụng các thẻ struct trong cả hai bản dịch C và C++:

person dmr = {"Dennis Ritchie", 70}; 

Nếu bạn thích thẻ cấu trúc ở một số nơi, bạn cũng có thể sử dụng theo cách đó.

Lợi ích rõ ràng là loại có thể được tham chiếu bằng một trong hai từ định danh trong cả hai không gian tên, bất kể ngôn ngữ.