Header file (File tiêu đề) là gì?
File .h chứa: khai báo hàm, macro, struct, typedef, biến extern... Dùng để chia sẻ interface giữa các file .c.
Tại sao cần custom header?
- Tách khai báo (interface) và triển khai (implementation)
- Dùng lại code ở nhiều file
.ckhác nhau - Quản lý dự án lớn, module hóa
- Tránh trùng lặp khai báo
Cấu trúc dự án ví dụ
project/
├── main.c
├── swap.h # Header tùy chỉnh
└── swap.c # Triển khai
1. File header: swap.h
// swap.h
#ifndef SWAP_H // Include guard - chống include trùng
#define SWAP_H
// Khai báo hàm (prototype)
void hoanDoi(int *a, int *b);
// Macro hữu ích
#define MAX(a,b) ((a) > (b) ? (a) : (b))
// Struct chia sẻ
typedef struct {
int x, y;
} Point;
#endif
2. File triển khai: swap.c
// swap.c
#include "swap.h" // Include header của chính mình (kiểm tra tính nhất quán)
void hoanDoi(int *a, int *b) {
int tam = *a;
*a = *b;
*b = tam;
}
3. File chính: main.c
// main.c
#include
#include "swap.h" // Dùng "" cho header tự viết, <> cho thư viện chuẩn
int main() {
int a = 10, b = 20;
printf("Truoc: a=%d, b=%d\n", a, b);
hoanDoi(&a, &b);
printf("Sau: a=%d, b=%d\n", a, b);
// Dùng macro từ header
printf("Max: %d\n", MAX(a, b));
// Dùng struct từ header
Point p = {3, 4};
printf("Point: (%d, %d)\n", p.x, p.y);
return 0;
}
Compile
# Cách 1: Compile từng file, sau đó link
gcc -c swap.c -o swap.o
gcc -c main.c -o main.o
gcc swap.o main.o -o chuongtrinh
# Cách 2: Một lệnh
gcc main.c swap.c -o chuongtrinh
# Chạy
./chuongtrinh
Kết quả
Truoc: a=10, b=20
Sau: a=20, b=10
Max: 20
Point: (3, 4)
Include Guard (Bảo vệ include trùng)
#ifndef TEN_FILE_H
#define TEN_FILE_H
// Nội dung header
#endif
Hoặc hiện đại hơn (C11, GCC, Clang, MSVC hỗ trợ):
#pragma once
// Nội dung header
Quy tắc đặt tên và tổ chức
| Loại | Quy tắc | Ví dụ |
|---|---|---|
| Header guard | Tên file in hoa + _H | SWAP_H, MYLIB_H |
| Include hệ thống | <stdio.h> | Thư viện chuẩn |
| Include tùy chỉnh | "swap.h" | File cùng dự án |
| Cấu trúc thư mục | #include "utils/math.h" | Subdirectory |
Nguyên tắc thiết kế Header tốt
- Chỉ chứa khai báo (prototype, struct, typedef, macro, extern)
- KHÔNG chứa định nghĩa (function body, biến global, khởi tạo)
- Tự đủ: Header có thể compile độc lập (include các header cần thiết)
- Tối thiểu: Chỉ public những gì cần thiết
- Có include guard
Lỗi thường gặp
- Định nghĩa biến trong header → Multiple definition khi link
- Quên include guard → Recompile error
- Include header trong header không cần thiết → Compile chậm, phụ thuộc vòng
- Dùng
<myheader.h>thay vì"myheader.h"