Search…

union Trong C/C++ Và Chia Sẻ Vùng Nhớ

11/09/20203 min read
Giới thiệu union và các trường hợp sử dụng union mang lại hiệu năng tốt và hiệu quả trong tổ chức chương trình.

union trong C/C++

union là kiểu dữ liệu người dùng tự định nghĩa, khác biệt với struct là các thuộc tính của union sử dụng chung vùng nhớ.

Sử dụng union

union có cách định nghĩa như struct:

union UnionName
{
	type attribute1;
	type attribute2;
	type attribute3;
	.... ..........;
};

Ví dụ về cú pháp khai báo và sử dụng

// Khai báo 1 union
union Hardware
{
	float	_cpu;
	short	_ram;
	int	_ssd;
};

// Sử dụng union
int main()
{
	Hardware h;
	
	h._cpu = 3.2f;
	h._ram = 256;
	h._ssd = 1024;
	
	return 0;
}

Khi được định nghĩa như trên, union Hardware có kích thước của thuộc tính có kích thước lớn nhất, trong trường hợp này float hoặc int là 4 bytes nên union này có kích thước là 4 bytes.

Với cách sử dụng (dùng chung vùng nhớ) như trên, 3 thuộc tính _cpu, _ram, _ssd ghi đè lên nhau trong quá trình sử dụng.

Các trường hợp sử dụng union

Cần tiết kiệm vùng nhớ

Trong cùng 1 tầm vực, 1 biến được cấp phát tĩnh được khởi tạo khi bắt đầu vào hàm và hủy khi kết thúc hàm.

void func()
{
	// (1) Đoạn code cần dùng biến ram
	int ram = 2048; // MB
	
	printf("RAM: %d", ram);

	// (2) Đoạn code không cần dùng biến ram, nhưng cần dùng biến hdd
	int ssd = 1024; // GB
	
	printf("SSD: %d", ssd);
}

Với code trên, cần 8 bytes dành cho 2 biến là ramhdd, giả sử cho đến khi sử dụng ssd thì biến ram không cần dùng nữa, vậy có thể sử dụng luôn biến ram để lưu trữ thông tin ssd? Về mặc lý thuyết có thể sử dụng, nhưng thực tế sẽ tự gây khó khăn khi sử dụng biến không rõ ngữ nghĩa và dẫn đến lỗi tiềm ẩn.

Để giải quyết vấn đề ngữ nghĩa và tiết kiệm bộ nhớ trong trường hợp này, có thể sử dụng union.

// Khai báo 1 union
union Hardware
{
	short	_ram;
	int	_ssd;
};

void func()
{
	Hardware hw;

	// (1) Đoạn code cần dùng ram
	hw.ram = 2048; // MB
	
	printf("RAM: %d", hw.ram);

	// (2) Đoạn code không cần dùng ram, nhưng cần dùng hdd
	hw.ssd = 1024; // GB

	printf("SSD: %d", hw.ssd);
}

Tiết kiệm vùng nhớ sẽ hữu ích với các ứng dụng có bộ nhớ nhỏ như trong lập trình nhúng, ví dụ như Arduino Uno R3 dùng ATmega328P, dung lượng bộ nhớ chỉ khoảng 2KB (2048 bytes).

Cần tổ chức chương trình

Xem xét đoạn codes bên dưới

union Vector4
{
	struct {
		float r, g, b, a;
	};
	
	struct {
		float x, y, z, w;
	};
	
	struct {
		float s, t, p, q;
	};
	
	float color[4];
	float position[4];
	float textcoord[4];
};

void rgba_vn()
{
	Vector4 logo_color;
	logo_color.r = 255.0f;
	logo_color.color[0] = 240.0f;
	
	Vector4 monster_position;
	monster_position.x = 100.0f;
	
	// ...
}

Với cách sử dụng union như trên có thể sử dụng 1 cấu trúc dữ liệu thống nhất là Vector4 cho 3 trường hợp: màu sắc (color[4]), tạo độ (position[4]) và bảng ánh xạ màu sắc (textcoord[4]) hoặc có thể sử dụng dưới dạng mảng chỉ số khi cần thiết.

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024