2009-10-31 43 views
321

Tôi đã được nhìn thấy mã như thế này thường là ở đầu tập tin tiêu đề:Tại sao #ifndef và #define được sử dụng trong các tệp tiêu đề C++?

#ifndef HEADERFILE_H 
#define HEADERFILE_H 

Và ở phần cuối của tập tin là

#endif 

mục đích của việc này là gì?

+22

+1 - Tôi cũng có cùng một nghi ngờ và có nhiều câu trả lời hay hơn ở đây, có thể hữu ích cho khách truy cập trong tương lai: http://stackoverflow.com/q/3246803/1134940 –

+5

Tôi muốn thêm vào điều này mà bạn có thể cũng sử dụng ** # pragma một lần **, đó là tất cả những gì bạn phải làm và nó phục vụ cùng một mục đích như ifndef. Để so sánh hai, xem: http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards – Dimension

+2

Tốt nhất để đề cập đến một '# pragma' là gì: nó kích hoạt tính năng trình biên dịch cụ thể. Mặc dù '#pragma once' là * rất * được hỗ trợ rộng rãi nhưng nó không chuẩn. – Potatoswatter

Trả lời

369

Chúng được gọi là #include guards.

Khi tiêu đề được bao gồm, nó sẽ kiểm tra nếu một giá trị duy nhất (trong trường hợp này là HEADERFILE_H) được xác định. Sau đó, nếu nó không được xác định, nó định nghĩa nó và tiếp tục phần còn lại của trang.

Khi mã được bao gồm lại, ifndef đầu tiên không thành công, dẫn đến tệp trống.

Điều đó ngăn không cho khai báo hai lần bất kỳ số nhận dạng nào như loại, enums và biến tĩnh.

+3

Mmm interresting. Tôi đã từng trích dẫn VC++ vì nó đã cho tôi lỗi về định nghĩa kép.Nevermind Tôi là một coder Objective-C bây giờ =) –

+0

Koning Baard XIV: VC thậm chí có một '#pragma once' mà làm như vậy :-) – Joey

+63

Ngoài ra nó ngăn cản sự xâm nhập đệ quy ... Hãy tưởng tượng" alice.h "bao gồm" bob.h "và" bob.h "bao gồm" alice.h "và chúng không có bảo vệ ... –

21
#ifndef <token> 
/* code */ 
#else 
/* code to include if the token is defined */ 
#endif 

#ifndef kiểm tra xem các token cung cấp đã được #defined trước đó trong file hoặc trong một tập tin bao gồm; nếu không, nó bao gồm mã giữa nó và đóng #else hoặc, nếu không có #else có mặt, tuyên bố #endif. #ifndef thường được sử dụng để làm cho tập tin tiêu đề idempotent bằng cách xác định một mã thông báo khi tệp đã được bao gồm và kiểm tra xem mã thông báo không được đặt ở đầu tệp đó hay không.

#ifndef _INCL_GUARD 
#define _INCL_GUARD 
#endif 
+3

Số nhận dạng bắt đầu bằng dấu gạch dưới được đặt trước; bạn không nên tự định nghĩa chúng. Sử dụng một cái gì đó như '#ifndef H_HEADER_NAME'. –

+5

Tôi biết đây là nhận xét cũ, nhưng giới hạn gạch dưới chỉ áp dụng cho "số nhận dạng bên ngoài" - số nhận dạng có thể kết thúc trong bảng biểu tượng của đối tượng được biên dịch, tức là các biến toàn cục và tên hàm. Nó không áp dụng cho tên macro. – Stu

+1

Nhận xét của Stu có đúng không? Tôi chỉ đọc https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier và bây giờ tôi không chắc lắm. – Will

2

Điều này ngăn việc bao gồm nhiều tập tin tiêu đề giống nhau nhiều lần.

#ifndef __COMMON_H__ 
#define __COMMON_H__ 
//header file content 
#endif 

Giả sử bạn đã bao gồm tệp tiêu đề này trong nhiều tệp. Vì vậy, lần đầu tiên __COMMON_H__ không được xác định, nó sẽ được xác định và tệp tiêu đề đi kèm.

Lần tới __COMMON_H__ được xác định, vì vậy nó sẽ không bao gồm lại.

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