2012-09-03 37 views
10

Trên định nghĩa của cấu trúc bên dưới, có một dòng có định nghĩa macro (#define). Dòng đó làm gì chính xác? Tôi hiểu nó làm cho một bí danh cho mục đầu tiên của mảng h_addr_list, nhưng nó vẫn có vẻ lạ với tôi. Có phải h_addr là thành viên của cấu trúc hostent không? Định nghĩa này chỉ nằm trong phạm vi của cấu trúc?xác định macro bên trong định nghĩa struct

struct hostent 
{ 
    char *h_name;  /* official name of host */ 
    char **h_aliases; /* alias list */ 
    int  h_addrtype;  /* host address type */ 
    int  h_length;  /* length of address */ 
    char **h_addr_list; /* list of addresses from name server */ 
    #define h_addr h_addr_list[0] /* address, for backward compatiblity */ 
}; 

Trả lời

16

Định nghĩa macro không có phạm vi chút nào, nó sẽ hoạt động theo cùng một cách nếu nó được xác định bên ngoài cấu trúc đó.

Cho phép mã cũ tiếp tục sử dụng hr.h_addr thay vì phải được thay đổi thành he.h_addr_list[0] (giả sử hestruct hostent).

Để làm rõ, h_addr không phải là trường struct hostent. Định nghĩa đó được xử lý bởi trước bộ xử lý, trình biên dịch thực tế nhìn thấy một dòng trống trong đó #define là.
Nhưng nếu một đoạn mã được viết là he.h_addr, bộ xử lý trước sẽ sửa đổi và thay thế bằng he.h_addr_list[0]. Đó là những gì trình biên dịch thực tế sẽ thấy.

Macro tiền xử lý không bao giờ bị xáo trộn: trình biên dịch thích hợp thậm chí không nhìn thấy chúng - nó chỉ thấy kết quả của các thay thế và bộ xử lý trước bỏ qua (không nhận thức) phạm vi hoàn toàn.

+0

Tôi hiểu phản hồi của bạn chỉ một phần. Ví dụ, tại sao 'h_addr' sau đó là một thành viên của' struct hostent' khi nó chỉ là một macro? – pap42

+2

'h_addr' không phải là trường' struct hostent'. Định nghĩa đó được xử lý bởi bộ xử lý trước, trình biên dịch thực tế sẽ thấy một dòng trống ở đó '# define' là. Nhưng nếu một đoạn mã được viết là 'he.h_addr', bộ xử lý trước sẽ sửa đổi nó và thay thế nó bằng' he.h_addr_list [0] '. Đó là những gì trình biên dịch thực tế sẽ thấy. – Mat

+0

Câu trả lời của bạn là tuyệt vời, nhưng tôi nghĩ bạn nên chỉnh sửa nó để làm cho nó rõ ràng hơn một chút cho người đọc trong tương lai (có lẽ bao gồm cả bình luận bạn vừa tạo ra). – pap42

5

Khi đã xác định, số nhận dạng macro sẽ vẫn hiển thị độc lập với các quy tắc phạm vi C. Phạm vi của nó bắt đầu theo định nghĩa của nó, cho đến khi kết thúc đơn vị dịch hoặc một chỉ thị tương ứng #undef.

Ở đây, định nghĩa bên trong cấu trúc chỉ dành cho khả năng đọc; bạn cũng có thể xác định macro của mình sau cấu trúc của mình, ví dụ:

struct hostent 
{ 
    char *h_name; 
    char **h_aliases; 
    int h_addrtype; 
    int h_length; 
    char **h_addr_list; 
}; 

#define h_addr h_addr_list[0] 

Nó hoàn toàn không phải là trường; nó cho phép người dùng viết s.h_addr thay vì s.h_addr_list[0].

0

Định nghĩa macro không được sắp xếp để macro này hiển thị trong các đơn vị biên dịch có định nghĩa này và cho đến khi undef h_addr.

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