Tệp tiêu đề (Header file) là file có phần mở rộng .h chứa khai báo hàm và định nghĩa macro của C được chia sẻ giữa một số tệp nguồn (source file). Có hai loại file header: một loại do người lập trình viết và một loại thuộc về trình biên dịch (compiler).
Bạn có thể sử dụng file header trong chương trình của mình bằng cách include nó với chỉ thị tiền xử lý C (C preprocessing directive) #include, giống như bạn đã từng thấy cách include file header stdio.h, là một header của trình biên dịch.
Include một file header tương đương với việc copy toàn bộ nội dung của file header đó. Nhưng chúng ta không làm điều đó một cách thủ công vì nó dễ sinh ra lỗi và không phải là một ý tưởng hay nếu copy toàn bộ nội dung của file header trong các file source, đặc biệt là nếu chúng ta có nhiều file source trong một chương trình.
Một kinh nghiệm khi lập trình các chương trình C hoặc C ++ là ta nên giữ tất cả các hằng số, macro, biến toàn cục của toàn hệ thống và các prototype hàm trong các file header và include file header đó ở bất cứ nơi nào cần.
Cú pháp include
Tất cả file header của người dùng và hệ thống đều được include bằng cách sử dụng tiền xử lý #include. Có hai dạng như sau.
#include <file>
Dạng cú pháp này được dùng file header của hệ thống. Nó tìm file có tên ‘file’ trong danh sách chuẩn của thư mục hệ thống (system directories). Bạn có thể thêm các thư mục vào trước danh sách này với lựa chọn -I trong khi biên dịch mã nguồn của bạn.
#include "file"
Dạng cú pháp này được dùng cho file header của chương trình riêng của bạn. Nó tìm file có tên ‘file’ trong thư mục chứa file hiện tại. Bạn có thể thêm các thư mục vào trước danh sách này với lựa chọn -I trong khi biên dịch mã nguồn của bạn.
Hoạt Động Include
Chỉ thị #include hoạt động bằng cách chỉ dẫn bộ tiền xử lý C scan những file được chỉ định như input trước khi xử lý tiếp với phần còn lại của file source hiện tại. Output từ bộ tiền xử lý sẽ bao gồm những output đã được tạo sẵn, tiếp theo là toàn bộ nội dung của những file được include, và sau đó là output của phần văn bản (code) bên dưới chỉ thị #include.
Ví dụ: nếu bạn có một tệp tiêu đề header.h như sau.
char* test(void);
và chương trình chính gọi là program.c sử dụng file header trên để include.
int x; #include “header.h” int main (void) { puts(test()); }
Trình biên dịch sẽ xem file program.c tương đương là
int x; char *test (void); int main (void) { puts (test ()); }
Header Chỉ Dùng Một Lần
Nếu một file header tình cờ được include hai lần, trình biên dịch sẽ xử lý nội dung của nó hai lần và nó sẽ bị lỗi. Để ngăn chặn điều này, bạn cần đặt toàn bộ nội dung thực của file trong một điều kiện, như thế này.
#ifndef HEADER_FILE #define HEADER_FILE the entire header file #endif
Cấu trúc này thường được gọi là đóng gói (wrapper) #ifndef. Khi header được include lại lần nữa, điều kiện #ifndef
sẽ sai, bởi vì HEADER_FILE đã được define. Bộ tiền xử lý sẽ bỏ qua toàn bộ nội dung của file. Do đó compiler sẽ không thể thấy nó hai lần.
Tính Toán Include
Đôi khi cần phải chọn một trong nhiều file header khác nhau để include vào chương trình của bạn. Ví dụ, chúng có thể chỉ định các thông số cấu hình được sử dụng trên các loại hệ điều hành khác nhau. Bạn có thể làm điều này với một chuỗi các điều kiện như sau.
#if SYSTEM_1 # include "system_1.h" #elif SYSTEM_2 # include "system_2.h" #elif SYSTEM_3 ... #endif
Nhưng khi phát triển hơn, nó trở nên cồng kềnh. Tuy nhiên, bộ tiền xử lý có cung cấp khả năng sử dụng một macro cho tên header. Điều này được gọi là tính toán include (computed include). Thay vì viết một tên header làm đối số trực tiếp của #include, bạn chỉ cần đặt một tên macro ở đó.
#define SYSTEM_H "system_1.h" ... #include SYSTEM_H
SYSTEM_H sẽ được mở rộng và bộ tiền xử lý sẽ tìm kiếm system_1.h như thể ban đầu #include đã được viết theo cách đó. SYSTEM_H có thể được define bởi Makefile của bạn với tùy chọn -D.
Xem thêm: Header Files của GNU.