1. extern
là gì?
Trong ngôn ngữ C, extern
là tín hiệu cho phép bạn “mượn” các biến hoặc hàm đã được định nghĩa ở tệp khác. Ví dụ, khi bạn muốn sử dụng biến toàn cục đã được khai báo trong một tệp ở một tệp khác, bạn sẽ dùng extern
. Khi chương trình được chia thành nhiều tệp, extern
giúp chia sẻ dữ liệu giữa các tệp đó.
Hãy tưởng tượng bên trong chương trình có nhiều “phòng” khác nhau, và extern
giống như một “hợp đồng mượn đồ” để lấy dụng cụ từ phòng bên cạnh. Nó có nghĩa là “ở đây không có, nhưng phòng bên cạnh thì có”.
Ví dụ
// file1.c
int g_data = 100;
// file2.c
extern int g_data;
void printData() {
printf("%dn", g_data); // Truy cập g_data trong file1.c
}
Trong ví dụ này, g_data
được định nghĩa ở file1.c
, nhưng nhờ extern
, biến này có thể được truy cập từ file2.c
.

2. Mối quan hệ giữa extern
và biến toàn cục
extern
có liên hệ mật thiết với biến toàn cục. Biến toàn cục chỉ cần được định nghĩa một lần trong toàn bộ chương trình, và có thể truy cập từ bất kỳ tệp nào. Tuy nhiên, nếu không khai báo bằng extern
, các tệp khác sẽ không biết biến đó ở đâu, nên bạn cần thông báo “ở đây có biến này!” bằng cách dùng extern
.
Lưu ý, extern
chỉ là khai báo, không cấp phát bộ nhớ. Việc cấp phát bộ nhớ cho biến được thực hiện tại tệp gốc đã định nghĩa biến đó.
Ví dụ về biến toàn cục
// file1.c
int counter = 0;
// file2.c
extern int counter; // Sử dụng counter đã được định nghĩa ở tệp khác
void incrementCounter() {
counter++; // Cập nhật giá trị của counter
}
3. Sử dụng extern
trong tệp header
Khi dự án lớn, việc khai báo lại biến hoặc hàm nhiều lần rất phiền phức. Lúc này, “tệp header” sẽ rất tiện lợi. Tệp header là nơi tập trung các thông tin dùng chung cho nhiều tệp khác. Khi khai báo extern
trong tệp header, các tệp khác có thể tham chiếu cùng một biến toàn cục hoặc hàm một cách dễ dàng.
Tệp header giống như “hộp công cụ” chung của toàn bộ dự án. Bạn tập hợp các công cụ dùng chung ở một nơi và chỉ cần sử dụng trong các tệp cần thiết.
Ví dụ về tệp header
// globals.h
extern int global_variable;
void printGlobalVariable();
// file1.c
#include "globals.h"
int global_variable = 10;
// file2.c
#include "globals.h"
void printGlobalVariable() {
printf("%dn", global_variable);
}

4. Những sai lầm thường gặp với extern
Có một số điểm cần lưu ý khi sử dụng extern
. Ví dụ, bạn không thể gán giá trị khởi tạo cho biến khi khai báo với extern
. extern
chỉ là “khai báo”, không phải “định nghĩa”. Nếu bạn khai báo extern
ở tệp không định nghĩa biến đó, chương trình sẽ báo lỗi liên kết.
Sai lầm thường gặp
extern int data = 100; // Không được khởi tạo giá trị khi dùng extern
Như ví dụ trên, nếu bạn cố gán giá trị cho biến khi khai báo bằng extern
sẽ gây ra lỗi. extern
chỉ để tham chiếu biến đã được định nghĩa ở nơi khác, không phải để định nghĩa hoặc khởi tạo biến.
5. Ví dụ thực tế sử dụng extern
extern
đặc biệt hữu ích trong các dự án lớn. Ví dụ, với chương trình có nhiều module, bạn có thể khai báo chung dữ liệu hoặc hàm bằng extern
và tái sử dụng ở nhiều tệp khác nhau.
Bằng cách này, chương trình được chia thành nhiều module rõ ràng, giúp dễ bảo trì và đọc hiểu hơn. Mỗi tệp có thể hoạt động độc lập, nhưng vẫn chia sẻ dữ liệu cần thiết khi cần thiết nhờ extern
.
Ví dụ thực tế
// main.c
#include "globals.h"
int main() {
printGlobalVariable(); // Gọi hàm được định nghĩa ở tệp khác
return 0;
}
// globals.c
#include "globals.h"
int global_variable = 100;
void printGlobalVariable() {
printf("%dn", global_variable); // Xuất giá trị biến toàn cục
}
Bài viết này đã bao quát từ cơ bản đến thực tiễn cách dùng extern
. Hiểu rõ vai trò của extern
là rất quan trọng khi bạn muốn chia nhỏ và tái sử dụng các phần của chương trình trong ngôn ngữ C.