C/C++

Extern and Static in C/C++

Xin chào, trong bài viết này chúng ta sẽ tìm hiểu về 2 keyword “extern” và “static” trong ngôn ngữ C/C++.

Đầu tiên chúng ta cần phân biệt hai khái niệm: Declaration (khai báo) và Definition (định nghĩa).

  • Declaration (một biến có thể được declare nhiều lần ở nhiều nơi) – mô tả kiểu dữ liệu của một biến, được sử dụng để tham khảo đến một biến đã được define ở một nơi khác (một file khác); ex: extern int array[];
  • Definition (một biến chỉ có thể được define một lần duy nhất) – chỉ định kiểu dữ liệu và cấp phát bộ nhớ cho biến; ex: int array[100];

EXTERN

Từ khóa “extern” được dùng trong khai báo các “external variable” để chia sẻ chúng giữa các source files. External variable cần được define ở bên ngoài tất cả các function và có thể được sử dụng ở mọi nơi trong source code.

Để dễ dàng trong sử dụng, tất cả khai báo “extern” của các external variable cần được đặt vào một header file (.h file) để chia sẻ giữa các source files. Khi cần sử dụng các external variable này trong các source files, chúng ta chỉ cần include header file.

Example 1:
File: header.h

extern int var;
extern int array[];

File: source.c

#include "header.h"

int var = 99;
int array[5] = {1,2,3,4,5};

File: test.c

#include "stdio.h"
#include "header.h"

void main() {
	printf("var=%d\n", var);
	printf("array[4]=%d\n", array[4]);
}

Compilation & Execution:
$ gcc test.c source.c -o test
$ ./test
Output:
var=99
array[4]=5
Giải thích:
Ở file header.h chúng ta đã khai báo hai biến var và array với từ khóa extern. Vì file header.h được include ở cả test.c và source.c nên chúng ta có thể gọi hai biến này ở bất cứ đâu trong source code, các khai báo extern này sẽ được áp dụng cho tất cả các function có trong file test.c và source.c.


STATIC

Từ khóa “static” được dùng trong khai báo các “external variable” hoặc một function (về bản chất function đã có tính external) để giới hạn phạm vi truy cập tới chúng chỉ ở trong source file nơi chúng được khai báo. Tên của các “static” variable và function này sẽ không bị xung đột với các variable và function cùng tên của các source files khác trong cùng chương trình.

Ngoài ra, nếu “static” được áp dụng trong khai báo một “internal variable” trong một function, thì biến local này vẫn sẽ tồn tại giữa các lần function được gọi. Tất nhiên phạm vi truy cập của nó vẫn chỉ ở trong function nơi nó được khai báo.

Example 2:
File: test.c

#include "stdio.h"

void init();

void main() {
	init();
}

File: source.c

#include "stdio.h"

static int var = 2018;

static void hello() {
	printf("I'm %d, I come from source.c file.\n", var);
}

void init() {
	hello();
}

Compilication & Execution:
$ gcc test.c source.c -o test
$ ./test
Output:
I’m 2018, I come from source.c file.
Giải thích:
Vì chúng ta đã khai báo biến var và function hello() với keyword “static” nên chúng chỉ có thể được truy cập từ bên trong file source.c. Bất cứ truy cập nào đến biến var và function hello() từ bên ngoài đều không hợp lệ. Các bạn hãy tự mình kiểm tra để hiểu rõ hơn nhé.


SUMMARY

Như vậy chúng ta đã tìm hiểu về 2 keyword “extern” và “static” trong C/C++.

  • “extern” được dùng để chia sẻ các External Variables giữa các source files (tốt nhất là đưa tất cả khai báo “extern” vào một header file);
  • “static” được dùng để giới hạn phạm vi của các External Variables và function ở bên trong file nơi nó được khai báo (không cần đưa vào header file). Ngoài ra “static” còn được dùng để khai báo Internal Variables.

Cảm ơn các bạn đã theo dõi bài viết.

Thân ái và quyết thắng.

Reference:
[1] “static” vs “extern”.
[2] How to use extern to share variables between source files.
[3] C Storage Class.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s