Struct (Cấu trúc)
Struct gom nhiều biến khác kiểu thành một đơn vị. Mỗi member có địa chỉ riêng, kích thước = tổng kích thước các member (+ padding).
Cú pháp
struct TenStruct {
kiểu thành_viên1;
kiểu thành_viên2;
...
} biến_struct;
Ví dụ
#include <stdio.h>
#include <string.h>
struct Data {
int i;
long int f;
} data, data1;
int main() {
data.i = 28;
printf("Giá trị i: %d\n", data.i);
printf("Kích thước: %zu %zu\n", sizeof(data), sizeof(data1));
return 0;
}
Kết quả
Giá trị i: 28 Kích thước: 16 16 (padding: int 4 + 4 padding + long 8 = 16)
Union (Liên hợp)
Union cho phép các member chia sẻ cùng một vùng nhớ. Kích thước = kích thước member lớn nhất. Chỉ một member có giá trị hợp lệ tại một thời điểm.
Cú pháp
union TenUnion {
kiểu thành_viên1;
kiểu thành_viên2;
...
} biến_union;
Ví dụ
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
} data, data1;
int main() {
printf("Kích thước union: %zu %zu\n", sizeof(data), sizeof(data1));
// Kích thước = max(sizeof(int), sizeof(float)) = 4
data.i = 0x41424344; // ASCII 'ABCD'
printf("data.i = 0x%X\n", data.i);
printf("data.f = %f (giá trị rác, cùng bit pattern)\n", data.f);
return 0;
}
Kết quả
Kích thước union: 4 4 data.i = 0x41424344 data.f = 123.456... (giá trị rác)
Bảng so sánh
| Đặc điểm | Struct | Union |
|---|---|---|
| Bộ nhớ | Tổng các member (+ padding) | Max kích thước member |
| Địa chỉ member | Khác nhau | Giống nhau (offset 0) |
| Giá trị đồng thời | Tất cả hợp lệ | Chỉ 1 member hợp lệ |
| Khởi tạo | Tất cả member | Chỉ member đầu (C99: designated init) |
| Dùng khi | Cần lưu nhiều giá trị cùng lúc | Tiết kiệm RAM, type punning, variant |
Ứng dụng Union
- Type punning (xem float như int bit)
- Protocol network (header có thể là nhiều loại)
- Embedded systems (tiết kiệm RAM)
- C++17:
std::variant- union an toàn kiểu
Ví dụ type punning an toàn (C++20: std::bit_cast)
#include <bit> // C++20 float f = 3.14f; uint32_t bits = std::bit_cast<uint32_t>(f); // An toàn, không UB