Hướng dẫn入门 về Union trong C

Xin chào các bạn học lập trình! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới lập trình C, đặc biệt là tập trung vào một khái niệm nhỏ gọn gọi là "union." Đừng lo lắng nếu bạn chưa từng nghe đến nó trước đây - đến cuối bài hướng dẫn này, bạn sẽ thành thạo về union!

C - Unions

Union là gì trong C?

Hãy bắt đầu từ cơ bản. Hãy tưởng tượng bạn có một hộp ma thuật có thể chứa các vật phẩm khác nhau, nhưng chỉ một lúc. Đó chính xác là union trong lập trình C! Đây là một kiểu dữ liệu đặc biệt cho phép bạn lưu trữ các kiểu dữ liệu khác nhau trong cùng một vị trí bộ nhớ.

Bây giờ, bạn có thể nghĩ, "Nhưng tại sao tôi lại muốn làm điều đó?" Well, người bạn tò mò, union vô cùng hữu ích khi bạn muốn tiết kiệm bộ nhớ hoặc khi bạn cần sử dụng cùng một vị trí bộ nhớ cho các mục đích khác nhau vào các thời điểm khác nhau.

Định nghĩa một Union

Định nghĩa một union rất đơn giản. Nó tương tự như định nghĩa một structure, nhưng chúng ta sử dụng từ khóa union thay vì struct. Dưới đây là một ví dụ đơn giản:

union MyUnion {
int integer;
float floating_point;
char character;
};

Trong ví dụ này, chúng ta đã tạo một union叫做 MyUnion có thể chứa một số nguyên, một số dấu phẩy động hoặc một ký tự. Nhớ lại ví dụ về hộp ma thuật của chúng ta? Union này giống như một hộp có thể chứa một con số, một số thập phân hoặc một chữ cái - nhưng chỉ một lúc!

Truy cập các thành viên của Union

Truy cập các thành viên của union rất dễ dàng! Bạn sử dụng ký hiệu chấm (.) giống như bạn sẽ làm với các structure. Dưới đây là cách nó hoạt động:

union MyUnion u;
u.integer = 42;
printf("Giá trị số nguyên là: %d\n", u.integer);

u.floating_point = 3.14;
printf("Giá trị số dấu phẩy động là: %f\n", u.floating_point);

u.character = 'A';
printf("Giá trị ký tự là: %c\n", u.character);

Trong ví dụ này, chúng ta đang lưu trữ các loại dữ liệu khác nhau trong union và sau đó in chúng ra. Nhưng đây là catches - và nó rất quan trọng - khi bạn gán một giá trị mới cho một thành viên union, nó sẽ ghi đè giá trị trước đó. Vì vậy, trong ví dụ của chúng ta, sau khi chúng ta gán 'A' cho u.character, các giá trị số nguyên và số dấu phẩy động trước đó sẽ không còn truy cập được.

Khởi tạo các thành viên của Union

Khởi tạo một union tương tự như khởi tạo một structure, nhưng có một sự khác biệt quan trọng: bạn chỉ có thể khởi tạo một thành viên một lần. Dưới đây là một ví dụ:

union MyUnion u = {42};  // Khởi tạo thành viên số nguyên
// HOẶC
union MyUnion u = {.floating_point = 3.14};  // Khởi tạo thành viên số dấu phẩy động
// HOẶC
union MyUnion u = {.character = 'A'};  // Khởi tạo thành viên ký tự

Nhớ lại, bất kỳ thành viên nào bạn khởi tạo, đó là thành viên duy nhất sẽ có giá trị hợp lệ để bắt đầu.

Ví dụ về Union

Hãy xem một ví dụ thực tế hơn. Hãy tưởng tượng bạn đang tạo một chương trình để quản lý các loại nhân viên khác nhau trong một công ty:

#include <stdio.h>
#include <string.h>

union EmployeeID {
int number;
char string[20];
};

struct Employee {
char name[50];
union EmployeeID id;
int id_type;  // 0 cho số, 1 cho chuỗi
};

int main() {
struct Employee emp1, emp2;

strcpy(emp1.name, "John Doe");
emp1.id.number = 12345;
emp1.id_type = 0;

strcpy(emp2.name, "Jane Smith");
strcpy(emp2.id.string, "ABC-XYZ");
emp2.id_type = 1;

printf("Nhân viên 1: %s, ID: %d\n", emp1.name, emp1.id.number);
printf("Nhân viên 2: %s, ID: %s\n", emp2.name, emp2.id.string);

return 0;
}

Trong ví dụ này, chúng ta sử dụng một union để lưu trữ hoặc một ID số hoặc một ID chuỗi cho mỗi nhân viên. Trường id_type trong structure Employee cho chúng ta biết chúng ta đang dealing với loại ID nào.

Kích thước của Union

Đây là một mẩu thông tin thú vị về unions: kích thước của một union được xác định bởi thành viên lớn nhất của nó. Hãy xem một ví dụ:

#include <stdio.h>

union SizeTest {
int i;
float f;
char c;
};

int main() {
union SizeTest st;
printf("Kích thước của union: %lu byte\n", sizeof(st));
printf("Kích thước của int: %lu byte\n", sizeof(int));
printf("Kích thước của float: %lu byte\n", sizeof(float));
printf("Kích thước của char: %lu byte\n", sizeof(char));
return 0;
}

Khi bạn chạy chương trình này, bạn sẽ thấy rằng kích thước của union bằng kích thước của thành viên lớn nhất (thường là float hoặc int, tùy thuộc vào hệ thống của bạn).

Sự khác biệt giữa Structure và Union

Bây giờ, bạn có thể đang tự hỏi, "Điều này khác gì so với một structure?" Câu hỏi tuyệt vời! Hãy phân tích nó:

Tính năng Structure Union
Phân bổ bộ nhớ Phân bổ bộ nhớ cho tất cả các thành viên Chỉ phân bổ bộ nhớ cho thành viên lớn nhất
Truy cập các thành viên Tất cả các thành viên có thể truy cập cùng lúc Chỉ một thành viên có thể truy cập một lúc
Sử dụng bộ nhớ Sử dụng nhiều bộ nhớ hơn Sử dụng ít bộ nhớ hơn
Lưu trữ dữ liệu Có thể lưu trữ nhiều giá trị cùng một lúc Chỉ có thể lưu trữ một giá trị một lần
Khởi tạo Có thể khởi tạo tất cả các thành viên cùng một lúc Chỉ có thể khởi tạo một thành viên một lần

Nói tóm lại, structure giống như một đống hộp dính lại với nhau, mỗi hộp chứa một vật phẩm riêng, trong khi union giống như một hộp có thể chứa các vật phẩm khác nhau, nhưng chỉ một lúc.

Và đó là tất cả, các bạn! Bạn đã刚刚 bước vào thế giới của union trong C. Nhớ rằng, thực hành là cách tốt nhất để trở nên hoàn hảo, vì vậy đừng ngần ngại thử nghiệm với các khái niệm này. Ai biết được? Bạn có thể sẽ sử dụng union để tạo ra một phần mềm lớn trong tương lai!

Chúc các bạn lập trình vui vẻ, và mong rằng union sẽ luôn bên bạn! ?

Credits: Image by storyset